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.

refactor: remove redundant infrastructure from NestJS example

Strip DTOs, ValidationPipe, HttpExceptionFilter, and app.factory — none
demonstrate the plugin. Controller now uses generated types directly
(CreatePetData['body'], UpdatePetData['body']) instead of hand-written DTOs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+7 -91
-1
docs/openapi-ts/plugins/nest.md
··· 116 116 117 117 - `class-validator` DTOs for request validation 118 118 - `ValidationPipe` with `forbidNonWhitelisted: true` 119 - - Exception filters 120 119 - `@darraghor/eslint-plugin-nestjs-typed` for NestJS-specific linting 121 120 122 121 ## Constraints
-3
examples/openapi-ts-nestjs/package.json
··· 14 14 "@nestjs/common": "^11.0.1", 15 15 "@nestjs/core": "^11.0.1", 16 16 "@nestjs/platform-express": "^11.0.1", 17 - "class-transformer": "^0.5.1", 18 - "class-validator": "^0.14.1", 19 17 "reflect-metadata": "^0.2.2", 20 18 "rxjs": "^7.8.1" 21 19 }, ··· 25 23 "@nestjs/testing": "^11.0.1", 26 24 "@swc-node/register": "^1.10.10", 27 25 "@swc/core": "^1.11.29", 28 - "@types/express": "^5.0.0", 29 26 "eslint": "^9.18.0", 30 27 "oxfmt": "^0.27.0", 31 28 "typescript": "^5.9.3",
-17
examples/openapi-ts-nestjs/src/app.factory.ts
··· 1 - import type { INestApplication } from '@nestjs/common'; 2 - import { ValidationPipe } from '@nestjs/common'; 3 - 4 - import { HttpExceptionFilter } from './common/filters/http-exception.filter'; 5 - 6 - export function configureApp(app: INestApplication): INestApplication { 7 - app.useGlobalPipes( 8 - new ValidationPipe({ 9 - forbidNonWhitelisted: true, 10 - forbidUnknownValues: true, 11 - transform: true, 12 - whitelist: true, 13 - }), 14 - ); 15 - app.useGlobalFilters(new HttpExceptionFilter()); 16 - return app; 17 - }
-21
examples/openapi-ts-nestjs/src/common/filters/http-exception.filter.ts
··· 1 - import type { ArgumentsHost, ExceptionFilter } from '@nestjs/common'; 2 - import { Catch, HttpException } from '@nestjs/common'; 3 - import type { Response } from 'express'; 4 - 5 - @Catch(HttpException) 6 - export class HttpExceptionFilter implements ExceptionFilter { 7 - catch(exception: HttpException, host: ArgumentsHost) { 8 - const ctx = host.switchToHttp(); 9 - const response = ctx.getResponse<Response>(); 10 - const status = exception.getStatus(); 11 - const exceptionResponse = exception.getResponse(); 12 - 13 - response 14 - .status(status) 15 - .json( 16 - typeof exceptionResponse === 'string' 17 - ? { code: status, message: exceptionResponse } 18 - : exceptionResponse, 19 - ); 20 - } 21 - }
+1 -2
examples/openapi-ts-nestjs/src/main.ts
··· 2 2 3 3 import { NestFactory } from '@nestjs/core'; 4 4 5 - import { configureApp } from './app.factory'; 6 5 import { AppModule } from './app.module'; 7 6 8 7 async function bootstrap() { 9 - const app = configureApp(await NestFactory.create(AppModule)); 8 + const app = await NestFactory.create(AppModule); 10 9 await app.listen(3000); 11 10 } 12 11
-12
examples/openapi-ts-nestjs/src/pets/dto/create-pet.dto.ts
··· 1 - import { IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; 2 - 3 - export class CreatePetDto { 4 - @IsString() 5 - @MinLength(1) 6 - @MaxLength(100) 7 - name!: string; 8 - 9 - @IsOptional() 10 - @IsString() 11 - tag?: string; 12 - }
-19
examples/openapi-ts-nestjs/src/pets/dto/update-pet.dto.ts
··· 1 - import { IsEnum, IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; 2 - 3 - const PetStatus = ['available', 'pending', 'sold'] as const; 4 - 5 - export class UpdatePetDto { 6 - @IsOptional() 7 - @IsString() 8 - @MinLength(1) 9 - @MaxLength(100) 10 - name?: string; 11 - 12 - @IsOptional() 13 - @IsString() 14 - tag?: string; 15 - 16 - @IsOptional() 17 - @IsEnum(PetStatus) 18 - status?: (typeof PetStatus)[number]; 19 - }
+3 -4
examples/openapi-ts-nestjs/src/pets/pets.controller.ts
··· 13 13 14 14 import type { PetsControllerMethods } from '../client/nestjs.gen'; 15 15 import type { 16 + CreatePetData, 16 17 DeletePetData, 17 18 ListPetsData, 18 19 Pet, 19 20 ShowPetByIdData, 20 21 UpdatePetData, 21 22 } from '../client/types.gen'; 22 - import type { CreatePetDto } from './dto/create-pet.dto'; 23 - import type { UpdatePetDto } from './dto/update-pet.dto'; 24 23 25 24 @Controller('pets') 26 25 export class PetsController implements Pick< ··· 50 49 } 51 50 52 51 @Post() 53 - async createPet(@Body() body: CreatePetDto) { 52 + async createPet(@Body() body: CreatePetData['body']) { 54 53 const pet: Pet = { 55 54 id: crypto.randomUUID(), 56 55 name: body.name, ··· 71 70 } 72 71 73 72 @Put(':petId') 74 - async updatePet(@Param() path: UpdatePetData['path'], @Body() body: UpdatePetDto) { 73 + async updatePet(@Param() path: UpdatePetData['path'], @Body() body: UpdatePetData['body']) { 75 74 const pet = this.pets.find((p) => p.id === path.petId); 76 75 if (!pet) { 77 76 throw new NotFoundException(`Pet ${path.petId} not found`);
+1 -2
examples/openapi-ts-nestjs/test/pets.test.ts
··· 1 1 import type { INestApplication } from '@nestjs/common'; 2 2 import { Test } from '@nestjs/testing'; 3 3 import type { AddressInfo } from 'net'; 4 - import { configureApp } from 'src/app.factory'; 5 4 import { AppModule } from 'src/app.module'; 6 5 import { createPet, deletePet, getInventory, listPets, showPetById, updatePet } from 'src/client'; 7 6 import { client } from 'src/client/client.gen'; ··· 13 12 imports: [AppModule], 14 13 }).compile(); 15 14 16 - app = configureApp(moduleRef.createNestApplication()); 15 + app = moduleRef.createNestApplication(); 17 16 await app.init(); 18 17 await app.listen(0); 19 18
+2 -10
pnpm-lock.yaml
··· 608 608 '@nestjs/platform-express': 609 609 specifier: ^11.0.1 610 610 version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) 611 - class-transformer: 612 - specifier: ^0.5.1 613 - version: 0.5.1 614 - class-validator: 615 - specifier: ^0.14.1 616 - version: 0.14.1 617 611 reflect-metadata: 618 612 specifier: ^0.2.2 619 613 version: 0.2.2 ··· 636 630 '@swc/core': 637 631 specifier: ^1.11.29 638 632 version: 1.11.29 639 - '@types/express': 640 - specifier: ^5.0.0 641 - version: 5.0.6 642 633 eslint: 643 634 specifier: ^9.18.0 644 635 version: 9.39.2(jiti@2.6.1) ··· 25020 25011 cjs-module-lexer@2.2.0: 25021 25012 optional: true 25022 25013 25023 - class-transformer@0.5.1: {} 25014 + class-transformer@0.5.1: 25015 + optional: true 25024 25016 25025 25017 class-validator@0.14.1: 25026 25018 dependencies: