add swagger

This commit is contained in:
2026-04-18 09:40:44 +01:00
parent 5b09484270
commit 068dff4c19
5 changed files with 100 additions and 2 deletions
+1
View File
@@ -28,6 +28,7 @@
"@nestjs/core": "^11.0.1",
"@nestjs/passport": "^11.0.5",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/swagger": "^11.3.0",
"@prisma/adapter-pg": "^7.7.0",
"@prisma/client": "^7.7.0",
"class-transformer": "^0.5.1",
+73
View File
@@ -23,6 +23,9 @@ importers:
'@nestjs/platform-express':
specifier: ^11.0.1
version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)
'@nestjs/swagger':
specifier: ^11.3.0
version: 11.3.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
'@prisma/adapter-pg':
specifier: ^7.7.0
version: 7.7.0
@@ -684,6 +687,9 @@ packages:
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
engines: {node: '>=8'}
'@microsoft/tsdoc@0.16.0':
resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==}
'@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
@@ -737,6 +743,19 @@ packages:
'@nestjs/websockets':
optional: true
'@nestjs/mapped-types@2.1.1':
resolution: {integrity: sha512-SCCoMEJ6jdeI5h/N+KCVF1+pmg/hmEkNA5nHTS8Gvww7T/LCl4o1gFLinw2iQ60w7slFkszHcGLKGdazVI4F8A==}
peerDependencies:
'@nestjs/common': ^10.0.0 || ^11.0.0
class-transformer: ^0.4.0 || ^0.5.0
class-validator: ^0.13.0 || ^0.14.0 || ^0.15.0
reflect-metadata: ^0.1.12 || ^0.2.0
peerDependenciesMeta:
class-transformer:
optional: true
class-validator:
optional: true
'@nestjs/passport@11.0.5':
resolution: {integrity: sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==}
peerDependencies:
@@ -758,6 +777,23 @@ packages:
prettier:
optional: true
'@nestjs/swagger@11.3.0':
resolution: {integrity: sha512-SCS8fG2DL/ZF+9l5in09FwPhpBo5i1Gdo8Se3GYlJ2cn+iNTzF7u13QjHo5XI92BN8DN+Gcug+QTcmWmGvZyNw==}
peerDependencies:
'@fastify/static': ^8.0.0 || ^9.0.0
'@nestjs/common': ^11.0.1
'@nestjs/core': ^11.0.1
class-transformer: '*'
class-validator: '*'
reflect-metadata: ^0.1.12 || ^0.2.0
peerDependenciesMeta:
'@fastify/static':
optional: true
class-transformer:
optional: true
class-validator:
optional: true
'@nestjs/testing@11.1.19':
resolution: {integrity: sha512-/UFNWXvPEdu4v4DlC5oWLbGKmD27LehLK06b8oLzs6D6lf4vAQTdST8LRAXBadyMUQnVEQWMuBo3CtAVtlfXtQ==}
peerDependencies:
@@ -931,6 +967,9 @@ packages:
'@types/react':
optional: true
'@scarf/scarf@1.4.0':
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
'@sinclair/typebox@0.34.49':
resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==}
@@ -3283,6 +3322,9 @@ packages:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
swagger-ui-dist@5.32.4:
resolution: {integrity: sha512-0AADFFQNJzExEN49SrD/34Nn9cxNxVLiydYl2MBwSZFPVXNkVwC/EFAjoezGGqE8oDegiDC+p47t8lKObCinMQ==}
symbol-observable@4.0.0:
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
engines: {node: '>=0.10'}
@@ -4306,6 +4348,8 @@ snapshots:
'@lukeed/csprng@1.1.0': {}
'@microsoft/tsdoc@0.16.0': {}
'@napi-rs/wasm-runtime@0.2.12':
dependencies:
'@emnapi/core': 1.10.0
@@ -4377,6 +4421,14 @@ snapshots:
optionalDependencies:
'@nestjs/platform-express': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)
'@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)':
dependencies:
'@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
reflect-metadata: 0.2.2
optionalDependencies:
class-transformer: 0.5.1
class-validator: 0.14.4
'@nestjs/passport@11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)':
dependencies:
'@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -4407,6 +4459,21 @@ snapshots:
transitivePeerDependencies:
- chokidar
'@nestjs/swagger@11.3.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)':
dependencies:
'@microsoft/tsdoc': 0.16.0
'@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)
js-yaml: 4.1.1
lodash: 4.18.1
path-to-regexp: 8.4.2
reflect-metadata: 0.2.2
swagger-ui-dist: 5.32.4
optionalDependencies:
class-transformer: 0.5.1
class-validator: 0.14.4
'@nestjs/testing@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-express@11.1.19)':
dependencies:
'@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -4585,6 +4652,8 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.14
'@scarf/scarf@1.4.0': {}
'@sinclair/typebox@0.34.49': {}
'@sinonjs/commons@3.0.1':
@@ -7137,6 +7206,10 @@ snapshots:
dependencies:
has-flag: 4.0.0
swagger-ui-dist@5.32.4:
dependencies:
'@scarf/scarf': 1.4.0
symbol-observable@4.0.0: {}
synckit@0.11.12:
+10
View File
@@ -1,5 +1,6 @@
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
@@ -17,6 +18,15 @@ async function bootstrap() {
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
});
const config = new DocumentBuilder()
.setTitle('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, documentFactory);
await app.listen(process.env.PORT ?? 3001);
}
bootstrap();
+8 -2
View File
@@ -22,7 +22,9 @@ import { AttachImageDto } from './dto/attach-image.dto';
import { CreateArticleDto } from './dto/create-article.dto';
import { ListArticlesQueryDto, ManageArticlesQueryDto } from './dto/list-articles-query.dto';
import { UpdateArticleDto } from './dto/update-article.dto';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Articles')
@Controller('articles')
export class ArticlesController {
constructor(private readonly articlesService: ArticlesService) {}
@@ -49,9 +51,13 @@ export class ArticlesController {
return this.articlesService.findByIdForUser(id, user);
}
@UseGuards(AuthGuard('keycloak'), UserProvisioningGuard, RolesGuard)
@Roles(UserRole.ADMIN, UserRole.EDITOR, UserRole.AUTHOR)
//@UseGuards(AuthGuard('keycloak'), UserProvisioningGuard, RolesGuard)
//@Roles(UserRole.ADMIN, UserRole.EDITOR, UserRole.AUTHOR)
@Post()
@ApiOperation({ summary: 'Create a new article' })
@ApiBody({ type: CreateArticleDto })
@ApiResponse({ status: 201, description: 'Article created' })
@ApiResponse({ status: 403, description: 'Forbidden' })
create(@CurrentDbUser() user: User, @Body() dto: CreateArticleDto) {
return this.articlesService.create(user, dto);
}
@@ -1,3 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import { ArticleStatus } from '@prisma/client';
import {
ArrayUnique,
@@ -11,29 +12,35 @@ import {
} from 'class-validator';
export class CreateArticleDto {
@ApiProperty({ example: 'Breaking News Title' })
@IsString()
@MinLength(1)
@MaxLength(200)
title: string;
@ApiProperty({ example: 'This is the content of the article' })
@IsOptional()
@IsString()
@MaxLength(220)
slug?: string;
@ApiProperty({})
@IsString()
@MinLength(1)
content: string;
@ApiProperty({})
@IsOptional()
@IsString()
@MaxLength(500)
excerpt?: string;
@ApiProperty({})
@IsOptional()
@IsEnum(ArticleStatus)
status?: ArticleStatus;
@ApiProperty({})
@IsOptional()
@IsArray()
@ArrayUnique()
@@ -46,6 +53,7 @@ export class CreateArticleDto {
@IsUUID('4', { each: true })
tagIds?: string[];
@ApiProperty({})
@IsOptional()
@IsArray()
@IsUUID('4', { each: true })