diff --git a/backend/nest-cli.json b/backend/nest-cli.json index 2566481..fb0d691 100644 --- a/backend/nest-cli.json +++ b/backend/nest-cli.json @@ -1,5 +1,8 @@ { "$schema": "https://json.schemastore.org/nest-cli", "collection": "@nestjs/schematics", - "sourceRoot": "src" + "sourceRoot": "src", + "compilerOptions": { + "plugins": ["@nestjs/swagger"] + } } diff --git a/backend/package-lock.json b/backend/package-lock.json index 77677e7..05b3772 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -12,10 +12,10 @@ "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.2.1", "@nestjs/jwt": "^10.0.1", - "@nestjs/mapped-types": "^1.2.0", "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.2.1", "@nestjs/schedule": "^2.1.0", + "@nestjs/swagger": "^6.2.1", "@nestjs/throttler": "^3.1.0", "@prisma/client": "^4.8.1", "archiver": "^5.3.1", @@ -704,13 +704,13 @@ } }, "node_modules/@nestjs/mapped-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", - "integrity": "sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.2.tgz", + "integrity": "sha512-3dHxLXs3M0GPiriAcCFFJQHoDFUuzTD5w6JDhE7TyfT89YKpe6tcCCIqOZWdXmt9AZjjK30RkHRSFF+QEnWFQg==", "peerDependencies": { "@nestjs/common": "^7.0.8 || ^8.0.0 || ^9.0.0", "class-transformer": "^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0", - "class-validator": "^0.11.1 || ^0.12.0 || ^0.13.0", + "class-validator": "^0.11.1 || ^0.12.0 || ^0.13.0 || ^0.14.0", "reflect-metadata": "^0.1.12" }, "peerDependenciesMeta": { @@ -806,6 +806,37 @@ "typescript": "^4.3.5" } }, + "node_modules/@nestjs/swagger": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-6.2.1.tgz", + "integrity": "sha512-9M2vkfJHIzLqDZwvM5TEZO0MxRCvIb0xVy0LsmWwxH1lrb0z/4MhU+r2CWDhBtTccVJrKxVPiU2s3T3b9uUJbg==", + "dependencies": { + "@nestjs/mapped-types": "1.2.2", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "4.15.5" + }, + "peerDependencies": { + "@fastify/static": "^6.0.0", + "@nestjs/common": "^9.0.0", + "@nestjs/core": "^9.0.0", + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", @@ -1955,8 +1986,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", @@ -4431,7 +4461,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -6641,6 +6670,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz", + "integrity": "sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA==" + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", @@ -8047,9 +8081,9 @@ } }, "@nestjs/mapped-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", - "integrity": "sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.2.tgz", + "integrity": "sha512-3dHxLXs3M0GPiriAcCFFJQHoDFUuzTD5w6JDhE7TyfT89YKpe6tcCCIqOZWdXmt9AZjjK30RkHRSFF+QEnWFQg==", "requires": {} }, "@nestjs/passport": { @@ -8115,6 +8149,18 @@ "pluralize": "8.0.0" } }, + "@nestjs/swagger": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-6.2.1.tgz", + "integrity": "sha512-9M2vkfJHIzLqDZwvM5TEZO0MxRCvIb0xVy0LsmWwxH1lrb0z/4MhU+r2CWDhBtTccVJrKxVPiU2s3T3b9uUJbg==", + "requires": { + "@nestjs/mapped-types": "1.2.2", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "4.15.5" + } + }, "@nestjs/testing": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", @@ -9041,8 +9087,7 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "array-flatten": { "version": "1.1.1", @@ -10908,7 +10953,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "requires": { "argparse": "^2.0.1" } @@ -12563,6 +12607,11 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "swagger-ui-dist": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz", + "integrity": "sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA==" + }, "symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index 3196bf0..7ef7dfc 100644 --- a/backend/package.json +++ b/backend/package.json @@ -3,7 +3,7 @@ "version": "0.9.0", "scripts": { "build": "nest build", - "dev": "nest start --watch", + "dev": "cross-env NODE_ENV=development nest start --watch", "prod": "prisma migrate deploy && prisma db seed && node dist/src/main", "lint": "eslint 'src/**/*.ts'", "format": "prettier --write 'src/**/*.ts'", @@ -17,10 +17,10 @@ "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.2.1", "@nestjs/jwt": "^10.0.1", - "@nestjs/mapped-types": "^1.2.0", "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.2.1", "@nestjs/schedule": "^2.1.0", + "@nestjs/swagger": "^6.2.1", "@nestjs/throttler": "^3.1.0", "@prisma/client": "^4.8.1", "archiver": "^5.3.1", diff --git a/backend/src/auth/dto/authRegister.dto.ts b/backend/src/auth/dto/authRegister.dto.ts index b574a16..daaa451 100644 --- a/backend/src/auth/dto/authRegister.dto.ts +++ b/backend/src/auth/dto/authRegister.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { UserDTO } from "src/user/dto/user.dto"; export class AuthRegisterDTO extends PickType(UserDTO, [ diff --git a/backend/src/auth/dto/authSignIn.dto.ts b/backend/src/auth/dto/authSignIn.dto.ts index 0dfa2e2..42e7cb9 100644 --- a/backend/src/auth/dto/authSignIn.dto.ts +++ b/backend/src/auth/dto/authSignIn.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { IsEmail, IsOptional, IsString } from "class-validator"; import { UserDTO } from "src/user/dto/user.dto"; diff --git a/backend/src/auth/dto/authSignInTotp.dto.ts b/backend/src/auth/dto/authSignInTotp.dto.ts index a90559d..835b591 100644 --- a/backend/src/auth/dto/authSignInTotp.dto.ts +++ b/backend/src/auth/dto/authSignInTotp.dto.ts @@ -1,18 +1,7 @@ -import { PickType } from "@nestjs/mapped-types"; -import { IsEmail, IsOptional, IsString } from "class-validator"; -import { UserDTO } from "src/user/dto/user.dto"; - -export class AuthSignInTotpDTO extends PickType(UserDTO, [ - "password", -] as const) { - @IsEmail() - @IsOptional() - email: string; - - @IsString() - @IsOptional() - username: string; +import { IsString } from "class-validator"; +import { AuthSignInDTO } from "./authSignIn.dto"; +export class AuthSignInTotpDTO extends AuthSignInDTO { @IsString() totp: string; diff --git a/backend/src/auth/dto/enableTotp.dto.ts b/backend/src/auth/dto/enableTotp.dto.ts index d3db7db..dc55d3d 100644 --- a/backend/src/auth/dto/enableTotp.dto.ts +++ b/backend/src/auth/dto/enableTotp.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { UserDTO } from "src/user/dto/user.dto"; export class EnableTotpDTO extends PickType(UserDTO, ["password"] as const) {} diff --git a/backend/src/auth/dto/updatePassword.dto.ts b/backend/src/auth/dto/updatePassword.dto.ts index 8bfa991..ee6b0e0 100644 --- a/backend/src/auth/dto/updatePassword.dto.ts +++ b/backend/src/auth/dto/updatePassword.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { IsString } from "class-validator"; import { UserDTO } from "src/user/dto/user.dto"; diff --git a/backend/src/auth/dto/verifyTotp.dto.ts b/backend/src/auth/dto/verifyTotp.dto.ts index d1c7729..dc96c1e 100644 --- a/backend/src/auth/dto/verifyTotp.dto.ts +++ b/backend/src/auth/dto/verifyTotp.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { IsString } from "class-validator"; import { UserDTO } from "src/user/dto/user.dto"; diff --git a/backend/src/main.ts b/backend/src/main.ts index 96d8714..a9004e6 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -1,6 +1,7 @@ import { ClassSerializerInterceptor, ValidationPipe } from "@nestjs/common"; import { NestFactory, Reflector } from "@nestjs/core"; import { NestExpressApplication } from "@nestjs/platform-express"; +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import * as bodyParser from "body-parser"; import * as cookieParser from "cookie-parser"; import * as fs from "fs"; @@ -18,6 +19,17 @@ async function bootstrap() { await fs.promises.mkdir("./data/uploads/_temp", { recursive: true }); app.setGlobalPrefix("api"); + + // Setup Swagger in development mode + if (process.env.NODE_ENV == "development") { + const config = new DocumentBuilder() + .setTitle("Pingvin Share API") + .setVersion("1.0") + .build(); + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup("api/swagger", app, document); + } + await app.listen(8080); } bootstrap(); diff --git a/backend/src/reverseShare/dto/reverseShareTokenWithShare.ts b/backend/src/reverseShare/dto/reverseShareTokenWithShare.ts index 537707b..55dac0b 100644 --- a/backend/src/reverseShare/dto/reverseShareTokenWithShare.ts +++ b/backend/src/reverseShare/dto/reverseShareTokenWithShare.ts @@ -1,4 +1,4 @@ -import { OmitType } from "@nestjs/mapped-types"; +import { OmitType } from "@nestjs/swagger"; import { Expose, plainToClass, Type } from "class-transformer"; import { MyShareDTO } from "src/share/dto/myShare.dto"; import { ReverseShareDTO } from "./reverseShare.dto"; diff --git a/backend/src/user/dto/publicUser.dto.ts b/backend/src/user/dto/publicUser.dto.ts index 01c5e22..024a697 100644 --- a/backend/src/user/dto/publicUser.dto.ts +++ b/backend/src/user/dto/publicUser.dto.ts @@ -1,4 +1,4 @@ -import { PickType } from "@nestjs/mapped-types"; +import { PickType } from "@nestjs/swagger"; import { UserDTO } from "./user.dto"; export class PublicUserDTO extends PickType(UserDTO, ["username"] as const) {} diff --git a/backend/src/user/dto/updateOwnUser.dto.ts b/backend/src/user/dto/updateOwnUser.dto.ts index 604d380..6b7abec 100644 --- a/backend/src/user/dto/updateOwnUser.dto.ts +++ b/backend/src/user/dto/updateOwnUser.dto.ts @@ -1,4 +1,4 @@ -import { OmitType, PartialType } from "@nestjs/mapped-types"; +import { OmitType, PartialType } from "@nestjs/swagger"; import { UserDTO } from "./user.dto"; export class UpdateOwnUserDTO extends PartialType( diff --git a/backend/src/user/dto/updateUser.dto.ts b/backend/src/user/dto/updateUser.dto.ts index eef29a2..dd0b1a3 100644 --- a/backend/src/user/dto/updateUser.dto.ts +++ b/backend/src/user/dto/updateUser.dto.ts @@ -1,4 +1,4 @@ -import { PartialType } from "@nestjs/mapped-types"; +import { PartialType } from "@nestjs/swagger"; import { CreateUserDTO } from "./createUser.dto"; export class UpdateUserDto extends PartialType(CreateUserDTO) {}