From 83115658e97b73f1be6ec07d7794b3b99dc4c0f1 Mon Sep 17 00:00:00 2001 From: Golovko Matvey Date: Thu, 5 Sep 2024 14:55:31 +0300 Subject: [PATCH 1/7] review: add todos --- .env.example | 5 ++++- docker-compose.yaml | 5 ++++- src/module/auth/auth.controller.ts | 1 + src/module/auth/guards/organizer.guard.ts | 1 + src/module/auth/guards/owner.guard.ts | 1 + src/module/booking/booking.service.ts | 7 +++++++ src/module/event/event.controller.ts | 1 + src/module/event/event.repository.ts | 1 + src/module/event/event.service.ts | 1 + src/module/mail/mail.module.ts | 1 + src/module/user/user.repository.ts | 1 + src/module/user/user.service.ts | 2 ++ 12 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index f340ddd..46c62d8 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ +# todo: нейминг SERVER_PORT -> HTTP_PORT, так как приложение может иметь несколько портов SERVER_PORT= POSTGRES_PORT= @@ -11,4 +12,6 @@ JWT_ACCESS_EXPIRATION_TIME= SMTP_HOST= SMTP_POTY= SMTP_USER= -SMTP_PASS= \ No newline at end of file +SMTP_PASS= + +# todo: заполнить примерами данных и\или локальными кредами \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 538770c..c0510df 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,4 +6,7 @@ services: env_file: - path: ./.env ports: - - "$POSTGRES_PORT:5432" \ No newline at end of file + - "$POSTGRES_PORT:5432" + + +# todo: сделать полный запуск проекта с помощью docker-compose, а не только БД \ No newline at end of file diff --git a/src/module/auth/auth.controller.ts b/src/module/auth/auth.controller.ts index 340b89a..373d871 100644 --- a/src/module/auth/auth.controller.ts +++ b/src/module/auth/auth.controller.ts @@ -22,6 +22,7 @@ export class AuthController { return this.authService.login(user); } + // todo: мёртвый код @UseGuards(AccessTokenGuard) @Get('logout') logout() { diff --git a/src/module/auth/guards/organizer.guard.ts b/src/module/auth/guards/organizer.guard.ts index 93ef055..14bbb3f 100644 --- a/src/module/auth/guards/organizer.guard.ts +++ b/src/module/auth/guards/organizer.guard.ts @@ -1,6 +1,7 @@ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { UserRole } from 'src/config/types/entity.enums'; +// todo: как будто по логике этот guard должен быть в другом модуле @Injectable() export class OrganizerGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { diff --git a/src/module/auth/guards/owner.guard.ts b/src/module/auth/guards/owner.guard.ts index 41ce94e..f745308 100644 --- a/src/module/auth/guards/owner.guard.ts +++ b/src/module/auth/guards/owner.guard.ts @@ -1,6 +1,7 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; import { EventRepository } from 'src/module/event/event.repository'; +// todo: как будто по логике этот guard должен быть в другом модуле @Injectable() export class EventOwnerGuard implements CanActivate { constructor(private eventRepository: EventRepository) {} diff --git a/src/module/booking/booking.service.ts b/src/module/booking/booking.service.ts index 012920a..666e6f4 100644 --- a/src/module/booking/booking.service.ts +++ b/src/module/booking/booking.service.ts @@ -26,6 +26,11 @@ export class BookingService { } async deleteBooking(user: User, eventId: number) { + // todo: убрать формирование запроса в сервисе + // { + // user: Equal(user.id), + // event: Equal(eventId), + // } const result = await this.bookingRepository.delete({ user: Equal(user.id), event: Equal(eventId), @@ -36,12 +41,14 @@ export class BookingService { } private findOneBooking(user: User, eventId: number) { + // todo: убрать формирование запроса в сервисе return this.bookingRepository.findOneBy({ user: Equal(user.id), event: Equal(eventId), }); } findAll() { + // todo: убрать формирование запроса в сервисе return this.bookingRepository.find({ relations: ['user', 'event'] }); } } diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index 2ca4c62..8915d11 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -46,6 +46,7 @@ export class EventController { @Patch('update/:id') @UseGuards(AccessTokenGuard, EventOwnerGuard) + // todo: сделать отдельное dto для updateEventDto. Использовать PartialType update(@Param('id') id: number, @Body() updateEventDto: CreateEventDto) { return this.eventService.updateEvent(id, updateEventDto); } diff --git a/src/module/event/event.repository.ts b/src/module/event/event.repository.ts index 38981de..ff783b6 100644 --- a/src/module/event/event.repository.ts +++ b/src/module/event/event.repository.ts @@ -15,6 +15,7 @@ export class EventRepository extends Repository { ); } + // todo: переопределил метод из репозитория typeOrm. Это решится, если избавиться от наследования (смотри todo в user.reposutory) async findOneById(id: number) { return this.eventRepository.findOne({ where: { id }, diff --git a/src/module/event/event.service.ts b/src/module/event/event.service.ts index c057046..d0d3ed2 100644 --- a/src/module/event/event.service.ts +++ b/src/module/event/event.service.ts @@ -64,6 +64,7 @@ export class EventService { }); } + // todo: мертвый код sendEmail() { this.mailerService .sendMail({ diff --git a/src/module/mail/mail.module.ts b/src/module/mail/mail.module.ts index 2de0bc0..7532049 100644 --- a/src/module/mail/mail.module.ts +++ b/src/module/mail/mail.module.ts @@ -8,6 +8,7 @@ import { MailerModule } from '@nestjs-modules/mailer'; inject: [ConfigService], useFactory: async (configService: ConfigService) => ({ transport: { + // todo: use configService.getOrThrow host: configService.get('SMTP_HOST'), port: configService.get('SMTP_PORT'), auth: { diff --git a/src/module/user/user.repository.ts b/src/module/user/user.repository.ts index dee5742..933088e 100644 --- a/src/module/user/user.repository.ts +++ b/src/module/user/user.repository.ts @@ -2,6 +2,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { User } from 'src/module/user/entity/user.entity'; import { Between, Repository } from 'typeorm'; +// todo: не использовать наследование, а делать обёртку export class UserRepository extends Repository { constructor( @InjectRepository(User) diff --git a/src/module/user/user.service.ts b/src/module/user/user.service.ts index b052fcd..0868379 100644 --- a/src/module/user/user.service.ts +++ b/src/module/user/user.service.ts @@ -1,5 +1,6 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { hash } from 'argon2'; +// todo: делать относительные пути везде либо использовать настройку шорткатов через ts-config import { UserRepository } from 'src/module/user/user.repository'; import { CreateUserDto } from './dto/create-user.dto'; @@ -18,6 +19,7 @@ export class UserService { const hashedPassword = await hash(user.password); user.password = hashedPassword; user.email = email; + return this.userRepository.save(user); } From 92cc8571fa0c5bbe4615c549c426d73433f7145d Mon Sep 17 00:00:00 2001 From: mikhail Date: Fri, 6 Sep 2024 15:49:25 +0500 Subject: [PATCH 2/7] fix --- src/module/booking/booking.module.ts | 3 +- src/module/booking/booking.repository.ts | 24 +++++++++++----- src/module/event/event.controller.ts | 4 +-- src/module/event/event.repository.ts | 28 +++++++++++++------ .../{auth => user}/guards/organizer.guard.ts | 0 .../{auth => user}/guards/owner.guard.ts | 0 src/module/user/user.repository.ts | 16 ++++++----- 7 files changed, 49 insertions(+), 26 deletions(-) rename src/module/{auth => user}/guards/organizer.guard.ts (100%) rename src/module/{auth => user}/guards/owner.guard.ts (100%) diff --git a/src/module/booking/booking.module.ts b/src/module/booking/booking.module.ts index 5fbbc51..148ec4b 100644 --- a/src/module/booking/booking.module.ts +++ b/src/module/booking/booking.module.ts @@ -5,11 +5,12 @@ import { BookingController } from './booking.controller'; import { BookingService } from './booking.service'; import { Booking } from './entity/booking.entity'; import { EventModule } from '../event/event.module'; +import { BookingRepository } from './booking.repository'; @Module({ imports: [TypeOrmModule.forFeature([Booking]), EventModule], controllers: [BookingController], - providers: [BookingService], + providers: [BookingService, BookingRepository], exports: [], }) export class BookingModule {} diff --git a/src/module/booking/booking.repository.ts b/src/module/booking/booking.repository.ts index 77d5d8d..0b45c0b 100644 --- a/src/module/booking/booking.repository.ts +++ b/src/module/booking/booking.repository.ts @@ -3,15 +3,25 @@ import { Repository } from 'typeorm'; import { Booking } from './entity/booking.entity'; -export class BookingRepository extends Repository { +export class BookingRepository{ constructor( @InjectRepository(Booking) private readonly bookingRepository: Repository, - ) { - super( - bookingRepository.target, - bookingRepository.manager, - bookingRepository.queryRunner, - ); + ) {} + + save(data) { + return this.bookingRepository.save(data) + } + + delete(data) { + return this.bookingRepository.delete(data) + } + + findOneBy(data) { + return this.bookingRepository.findOneBy(data) + } + + find(data) { + return this.bookingRepository.find(data) } } diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index 8915d11..f655c60 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -17,9 +17,9 @@ import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; import { EventService } from './event.service'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; -import { OrganizerGuard } from '../auth/guards/organizer.guard'; -import { EventOwnerGuard } from '../auth/guards/owner.guard'; import { User } from '../user/entity/user.entity'; +import { OrganizerGuard } from '../user/guards/organizer.guard'; +import { EventOwnerGuard } from '../user/guards/owner.guard'; @Controller('event') export class EventController { diff --git a/src/module/event/event.repository.ts b/src/module/event/event.repository.ts index ff783b6..6128511 100644 --- a/src/module/event/event.repository.ts +++ b/src/module/event/event.repository.ts @@ -1,19 +1,13 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; +import { DeepPartial, Repository } from 'typeorm'; import { Event } from './entity/event.entity'; -export class EventRepository extends Repository { +export class EventRepository { constructor( @InjectRepository(Event) private readonly eventRepository: Repository, - ) { - super( - eventRepository.target, - eventRepository.manager, - eventRepository.queryRunner, - ); - } + ) {} // todo: переопределил метод из репозитория typeOrm. Это решится, если избавиться от наследования (смотри todo в user.reposutory) async findOneById(id: number) { @@ -22,4 +16,20 @@ export class EventRepository extends Repository { relations: ['organizer'], }); } + + create(data: DeepPartial) { + return this.eventRepository.create(data) + } + + save(data) { + return this.eventRepository.save(data) + } + + delete(data) { + return this.eventRepository.delete(data) + } + + find(data) { + return this.eventRepository.find(data) + } } diff --git a/src/module/auth/guards/organizer.guard.ts b/src/module/user/guards/organizer.guard.ts similarity index 100% rename from src/module/auth/guards/organizer.guard.ts rename to src/module/user/guards/organizer.guard.ts diff --git a/src/module/auth/guards/owner.guard.ts b/src/module/user/guards/owner.guard.ts similarity index 100% rename from src/module/auth/guards/owner.guard.ts rename to src/module/user/guards/owner.guard.ts diff --git a/src/module/user/user.repository.ts b/src/module/user/user.repository.ts index 933088e..8869b74 100644 --- a/src/module/user/user.repository.ts +++ b/src/module/user/user.repository.ts @@ -3,16 +3,18 @@ import { User } from 'src/module/user/entity/user.entity'; import { Between, Repository } from 'typeorm'; // todo: не использовать наследование, а делать обёртку -export class UserRepository extends Repository { +export class UserRepository { constructor( @InjectRepository(User) private readonly userRepository: Repository, - ) { - super( - userRepository.target, - userRepository.manager, - userRepository.queryRunner, - ); + ) {} +//naming + find(data){ + return this.userRepository.find(data) + } + + save(data){ + return this.userRepository.save(data) } findOneByEmail(email: string) { From 0cda78ab2e4261e80b3ae6de8040b9055a1aa158 Mon Sep 17 00:00:00 2001 From: mikhail Date: Sun, 8 Sep 2024 23:53:23 +0500 Subject: [PATCH 3/7] fix --- .env.example | 31 +- Dockerfile | 7 + docker-compose.yaml | 18 +- nest-cli.json | 8 + package-lock.json | 846 ++++++++++-------- package.json | 3 +- src/config/typeorm.config.ts | 9 +- src/main.ts | 15 +- src/migrations/1725817595096-Fix.ts | 18 + src/module/app.module.ts | 2 +- src/module/auth/auth.controller.ts | 12 +- src/module/auth/auth.service.ts | 6 +- src/module/auth/dto/register.auth.dto.ts | 2 +- .../auth/strategies/access-token.strategy.ts | 2 +- src/module/booking/booking.controller.ts | 4 +- src/module/booking/booking.module.ts | 2 +- src/module/booking/booking.repository.ts | 29 +- src/module/booking/booking.service.ts | 24 +- src/module/booking/entity/booking.entity.ts | 5 +- src/module/event/dto/create-event.dto.ts | 6 +- src/module/event/dto/search-event.dto.ts | 24 +- src/module/event/dto/update-event.dto.ts | 5 + src/module/event/entity/event.entity.ts | 16 +- src/module/event/event.controller.ts | 27 +- src/module/event/event.repository.ts | 57 +- src/module/event/event.service.ts | 51 +- src/module/mail/mail.module.ts | 11 +- src/module/scheduler/scheduler.service.ts | 6 +- src/module/user/dto/create-user.dto.ts | 9 +- src/module/user/dto/update-user.dto.ts | 16 +- src/module/user/entity/user.entity.ts | 16 +- src/module/user/guards/organizer.guard.ts | 4 +- src/module/user/guards/owner.guard.ts | 6 +- src/module/user/user.controller.ts | 4 +- src/module/user/user.module.ts | 2 +- src/module/user/user.repository.ts | 14 +- src/module/user/user.service.ts | 6 +- tsconfig.json | 2 +- 38 files changed, 721 insertions(+), 604 deletions(-) create mode 100644 Dockerfile create mode 100644 src/migrations/1725817595096-Fix.ts create mode 100644 src/module/event/dto/update-event.dto.ts diff --git a/.env.example b/.env.example index 46c62d8..fc923ea 100644 --- a/.env.example +++ b/.env.example @@ -1,17 +1,22 @@ -# todo: нейминг SERVER_PORT -> HTTP_PORT, так как приложение может иметь несколько портов -SERVER_PORT= +HTTP_PORT=3000 +HTTP_HOST=localhost +HTTP_PREFIX=api -POSTGRES_PORT= -POSTGRES_DB= -POSTGRES_USER= -POSTGRES_PASSWORD= +DB_HOST=events_node_db -JWT_ACCESS_SECRET= -JWT_ACCESS_EXPIRATION_TIME= +POSTGRES_PORT=5432 +POSTGRES_DB=example +POSTGRES_USER=example +POSTGRES_PASSWORD=example -SMTP_HOST= -SMTP_POTY= -SMTP_USER= -SMTP_PASS= +JWT_ACCESS_SECRET=example +JWT_ACCESS_EXPIRATION_TIME=1d -# todo: заполнить примерами данных и\или локальными кредами \ No newline at end of file +SMTP_HOST=sandbox.smtp.mailtrap.io +SMTP_POTY=2525 +SMTP_USER=example +SMTP_PASS=example +SMTP_FROM='"nest-modules" ' + +EMAIL_SUBJECT='Напоминание' +EMAIL_TEXT='У вас назначена встреча сегодня' \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..201fed5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm i +COPY . . +RUN npm run build +CMD ["sh", "-c", "npm run migration:run && npm start"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index c0510df..55b567c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,11 +2,19 @@ services: events_node_db: restart: always image: postgres:16-alpine - container_name: events_node_db + container_name: $DB_HOST env_file: - - path: ./.env + - path: ./.env ports: - - "$POSTGRES_PORT:5432" + - '$POSTGRES_PORT:5432' - -# todo: сделать полный запуск проекта с помощью docker-compose, а не только БД \ No newline at end of file + events_node: + restart: always + build: . + container_name: events_node + env_file: + - path: ./.env + ports: + - '$HTTP_PORT:3000' + depends_on: + - events_node_db \ No newline at end of file diff --git a/nest-cli.json b/nest-cli.json index f9aa683..dfe879c 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -3,6 +3,14 @@ "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { + "plugins": [ + { + "name": "@nestjs/swagger", + "options": { + "classValidatorShim": true + } + } +], "deleteOutDir": true } } diff --git a/package-lock.json b/package-lock.json index 068e36a..5334d5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,11 @@ "@nestjs/config": "^3.2.3", "@nestjs/core": "^10.0.0", "@nestjs/jwt": "^10.2.0", + "@nestjs/mapped-types": "^2.0.5", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.0.0", "@nestjs/schedule": "^4.1.0", + "@nestjs/swagger": "^7.4.0", "@nestjs/typeorm": "^10.0.2", "@types/passport-local": "^1.0.38", "argon2": "^0.40.3", @@ -26,7 +28,6 @@ "passport-jwt": "^4.0.1", "passport-local": "^1.0.0", "pg": "^8.12.0", - "pug": "^3.0.3", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "typeorm": "^0.3.20" @@ -215,9 +216,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -263,12 +264,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "dependencies": { - "@babel/types": "^7.25.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -359,6 +360,7 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -367,6 +369,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -381,13 +384,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -480,11 +483,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "devOptional": true, "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -529,6 +533,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", @@ -640,6 +674,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -656,12 +705,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -671,9 +720,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "optional": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -697,16 +746,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -724,9 +773,10 @@ } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "devOptional": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -1708,6 +1758,11 @@ "node": ">=8" } }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==" + }, "node_modules/@nestjs-modules/mailer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.0.2.tgz", @@ -1742,48 +1797,10 @@ "pug": ">=3.0.1" } }, - "node_modules/@nestjs-modules/mailer/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs-modules/mailer/node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/@nestjs/cli": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.2.tgz", - "integrity": "sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.5.tgz", + "integrity": "sha512-FP7Rh13u8aJbHe+zZ7hM0CC4785g9Pw4lz4r2TTgRtf0zTxSWMkJaPEwyjX8SK9oWK2GsYxl+fKpwVZNbmnj9A==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", @@ -1803,7 +1820,7 @@ "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.92.1", + "webpack": "5.94.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -1825,26 +1842,57 @@ } } }, - "node_modules/@nestjs/cli/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@nestjs/cli/node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=8.0.0" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@nestjs/cli/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@nestjs/cli/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@nestjs/cli/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=4.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@nestjs/cli/node_modules/typescript": { @@ -1860,57 +1908,10 @@ "node": ">=14.17" } }, - "node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@nestjs/common": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.10.tgz", - "integrity": "sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.1.tgz", + "integrity": "sha512-4CkrDx0s4XuWqFjX8WvOFV7Y6RGJd0P2OBblkhZS7nwoctoSuW5pyEa8SWak6YHNGrHRpFb6ymm5Ai4LncwRVA==", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.3", @@ -1950,9 +1951,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.10.tgz", - "integrity": "sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.1.tgz", + "integrity": "sha512-9I1WdfOBCCHdUm+ClBJupOuZQS6UxzIWHIq6Vp1brAA5ZKl/Wq6BVwSsbnUJGBy3J3PM2XHmR0EQ4fwX3nR7lA==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", @@ -1998,6 +1999,25 @@ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0" } }, + "node_modules/@nestjs/mapped-types": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/passport": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-10.0.3.tgz", @@ -2008,9 +2028,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.10.tgz", - "integrity": "sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.1.tgz", + "integrity": "sha512-ccfqIDAq/bg1ShLI5KGtaLaYGykuAdvCi57ohewH7eKJSIpWY1DQjbgKlFfXokALYUq1YOMGqjeZ244OWHfDQg==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", @@ -2040,22 +2060,10 @@ "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/@nestjs/schedule/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@nestjs/schematics": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.3.tgz", - "integrity": "sha512-aLJ4Nl/K/u6ZlgLa0NjKw5CuBOIgc6vudF42QvmGueu5FaMGM6IJrAuEvB5T2kr0PAfVwYmDFBBHCWdYhTw4Tg==", + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.4.tgz", + "integrity": "sha512-QpY8ez9cTvXXPr3/KBrtSgXQHMSV6BkOUYy2c2TTe6cBqriEdGnCYqGl8cnfrQl3632q3lveQPaZ/c127dHsEw==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", @@ -2074,10 +2082,42 @@ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, + "node_modules/@nestjs/swagger": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", + "integrity": "sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==", + "dependencies": { + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "5.17.14" + }, + "peerDependencies": { + "@fastify/static": "^6.0.0 || ^7.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "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 + } + } + }, "node_modules/@nestjs/testing": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.10.tgz", - "integrity": "sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.1.tgz", + "integrity": "sha512-pR+su5+YGqCLH0RhhVkPowQK7FCORU0/PWAywPK7LScAOtD67ZoviZ7hAU4vnGdwkg4HCB0D7W8Bkg19CGU8Xw==", "dev": true, "dependencies": { "tslib": "2.6.3" @@ -2116,6 +2156,18 @@ "typeorm": "^0.3.0" } }, + "node_modules/@nestjs/typeorm/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2203,6 +2255,12 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", @@ -2339,26 +2397,6 @@ "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", "optional": true }, - "node_modules/@types/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -2487,11 +2525,11 @@ "optional": true }, "node_modules/@types/node": { - "version": "20.14.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", - "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/passport": { @@ -2579,9 +2617,9 @@ "dev": true }, "node_modules/@types/superagent": { - "version": "8.1.8", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.8.tgz", - "integrity": "sha512-nTqHJ2OTa7PFEpLahzSEEeFeqbMpmcN7OeayiOc7v+xk+/vyTKljRe+o4MPqSnPeRCMvtxuLG+5QqluUVQJOnA==", + "version": "8.1.9", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", + "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", "dev": true, "dependencies": { "@types/cookiejar": "^2.1.5", @@ -2601,14 +2639,14 @@ } }, "node_modules/@types/validator": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.0.tgz", - "integrity": "sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==" + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.1.tgz", + "integrity": "sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA==" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -3231,8 +3269,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-buffer-byte-length": { "version": "1.0.1", @@ -3371,17 +3408,19 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "devOptional": true }, "node_modules/assert-never": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.3.0.tgz", - "integrity": "sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==" + "integrity": "sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==", + "optional": true }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "devOptional": true }, "node_modules/asynckit": { @@ -3483,23 +3522,26 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -3525,6 +3567,7 @@ "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "optional": true, "dependencies": { "@babel/types": "^7.9.6" }, @@ -3808,9 +3851,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001647", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001647.tgz", - "integrity": "sha512-n83xdNiyeNcHpzWY+1aFbqCK7LuLfBricc4+alSQL2Xb6OR3XpnQAmlDG+pQcdTfiHRuLcQ96VOfrPSGiNJYSg==", + "version": "1.0.30001658", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz", + "integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==", "dev": true, "funding": [ { @@ -3855,6 +3898,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "optional": true, "dependencies": { "is-regex": "^1.0.3" } @@ -3903,31 +3947,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cheerio/node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "optional": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/cheerio/node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "optional": true, - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3977,9 +3996,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz", + "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", "dev": true }, "node_modules/class-transformer": { @@ -4060,6 +4079,24 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/cli-highlight/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, + "node_modules/cli-highlight/node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/cli-highlight/node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, "node_modules/cli-highlight/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4292,6 +4329,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "optional": true, "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" @@ -4513,16 +4551,16 @@ } }, "node_modules/dayjs": { - "version": "1.11.12", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", - "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4736,7 +4774,8 @@ "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "optional": true }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -4888,9 +4927,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", - "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", + "version": "1.5.18", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.18.tgz", + "integrity": "sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==", "dev": true }, "node_modules/emittery": { @@ -5099,9 +5138,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -5234,9 +5273,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz", - "integrity": "sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz", + "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -5260,26 +5299,27 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, @@ -5962,9 +6002,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -6232,22 +6272,21 @@ } }, "node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6271,20 +6310,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -6453,6 +6478,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "devOptional": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -6623,9 +6649,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -6820,9 +6846,10 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "devOptional": true, "dependencies": { "hasown": "^2.0.2" }, @@ -6882,6 +6909,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "optional": true, "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" @@ -6891,6 +6919,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "optional": true, "bin": { "acorn": "bin/acorn" }, @@ -6994,12 +7023,14 @@ "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "optional": true }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "devOptional": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7213,12 +7244,15 @@ } }, "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dependencies": { "@isaacs/cliui": "^8.0.2" }, + "engines": { + "node": ">=14" + }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -7971,7 +8005,8 @@ "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "optional": true }, "node_modules/js-tokens": { "version": "4.0.0", @@ -7983,7 +8018,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" }, @@ -8084,6 +8118,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "optional": true, "dependencies": { "is-promise": "^2.0.0", "promise": "^7.0.1" @@ -8218,9 +8253,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.5.tgz", - "integrity": "sha512-TwHR5BZxGRODtAfz03szucAkjT5OArXr+94SMtAM2pYXIlQNVMrxvb6uSCbnaJJV6QXEyICk7+l6QPgn72WHhg==" + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.7.tgz", + "integrity": "sha512-x2xON4/Qg2bRIS11KIN9yCNYUjhtiEjNyptjX0mX+pyKHecxuJVLIpfX1lq9ZD6CrC/rB+y4GBi18c6CEcUR+A==" }, "node_modules/libqp": { "version": "2.1.0", @@ -8244,9 +8279,9 @@ } }, "node_modules/liquidjs": { - "version": "10.16.4", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.16.4.tgz", - "integrity": "sha512-5kK5HRZng6crSedS11D1h9Od8pYB5wjWjvJIlbhLVS7n+ITWzQervv27jx+7MkOS2KYfAEhwlEinTsTn4Ae5WQ==", + "version": "10.16.7", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.16.7.tgz", + "integrity": "sha512-vjlBDyPxFgUc6vJB+TbAMcxKKKcm4Ee0rj9Je9lcG1I0lr9xvtHgB/ZdNMNAgsPUvJLkLfdrKRd+KzQ5opPfNg==", "optional": true, "dependencies": { "commander": "^10.0.0" @@ -8581,9 +8616,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -9111,9 +9146,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multer": { "version": "1.4.4-lts.1", @@ -9226,9 +9261,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -9248,9 +9283,9 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", - "integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==", + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", + "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", "engines": { "node": ">=6.0.0" } @@ -9593,7 +9628,8 @@ "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true }, "node_modules/param-case": { "version": "2.1.1", @@ -9635,23 +9671,30 @@ } }, "node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "optional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "optional": true, "dependencies": { - "parse5": "^6.0.1" + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, "node_modules/parseley": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", @@ -9748,7 +9791,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "devOptional": true }, "node_modules/path-scurry": { "version": "1.11.1", @@ -9881,9 +9925,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -10109,6 +10153,19 @@ "node": ">=14" } }, + "node_modules/preview-email/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -10118,6 +10175,7 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "optional": true, "dependencies": { "asap": "~2.0.3" } @@ -10157,6 +10215,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "optional": true, "dependencies": { "pug-code-gen": "^3.0.3", "pug-filters": "^4.0.0", @@ -10172,6 +10231,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", @@ -10182,6 +10242,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", @@ -10196,12 +10257,14 @@ "node_modules/pug-error": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", - "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==" + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "optional": true }, "node_modules/pug-filters": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", @@ -10214,6 +10277,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "optional": true, "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", @@ -10224,6 +10288,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "optional": true, "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" @@ -10233,6 +10298,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "optional": true, "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" @@ -10242,6 +10308,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "optional": true, "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" @@ -10250,12 +10317,14 @@ "node_modules/pug-runtime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "optional": true }, "node_modules/pug-strip-comments": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "optional": true, "dependencies": { "pug-error": "^2.0.0" } @@ -10263,7 +10332,8 @@ "node_modules/pug-walk": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", - "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "optional": true }, "node_modules/punycode": { "version": "2.3.1", @@ -10505,6 +10575,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "devOptional": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -10994,11 +11065,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -11446,6 +11512,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -11453,6 +11520,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", @@ -11488,9 +11560,9 @@ } }, "node_modules/terser": { - "version": "5.31.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", - "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -11694,6 +11766,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "devOptional": true, "engines": { "node": ">=4" } @@ -11721,7 +11794,8 @@ "node_modules/token-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", - "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "optional": true }, "node_modules/tr46": { "version": "0.0.3", @@ -11750,20 +11824,20 @@ } }, "node_modules/ts-jest": { - "version": "29.2.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.4.tgz", - "integrity": "sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==", + "version": "29.2.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", + "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", "dev": true, "dependencies": { - "bs-logger": "0.x", + "bs-logger": "^0.2.6", "ejs": "^3.1.10", - "fast-json-stable-stringify": "2.x", + "fast-json-stable-stringify": "^2.1.0", "jest-util": "^29.0.0", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.6.3", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" @@ -12169,6 +12243,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/typeorm/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/typescript": { "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", @@ -12189,9 +12275,9 @@ "optional": true }, "node_modules/uglify-js": { - "version": "3.19.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.2.tgz", - "integrity": "sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -12227,9 +12313,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/universalify": { "version": "2.0.1", @@ -12307,9 +12393,9 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -12367,6 +12453,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -12381,9 +12468,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -12534,13 +12621,11 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, - "peer": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -12549,7 +12634,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -12604,7 +12689,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -12618,7 +12702,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -12685,6 +12768,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "optional": true, "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", diff --git a/package.json b/package.json index 83e4ea1..1752222 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "@nestjs/config": "^3.2.3", "@nestjs/core": "^10.0.0", "@nestjs/jwt": "^10.2.0", + "@nestjs/mapped-types": "^2.0.5", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.0.0", "@nestjs/schedule": "^4.1.0", + "@nestjs/swagger": "^7.4.0", "@nestjs/typeorm": "^10.0.2", "@types/passport-local": "^1.0.38", "argon2": "^0.40.3", @@ -42,7 +44,6 @@ "passport-jwt": "^4.0.1", "passport-local": "^1.0.0", "pg": "^8.12.0", - "pug": "^3.0.3", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "typeorm": "^0.3.20" diff --git a/src/config/typeorm.config.ts b/src/config/typeorm.config.ts index 2ed22a4..a8f1b1e 100644 --- a/src/config/typeorm.config.ts +++ b/src/config/typeorm.config.ts @@ -11,10 +11,11 @@ config(); const configService = new ConfigService(); const databaseConfig = { type: 'postgres' as const, - port: configService.get('POSTGRES_PORT'), - database: configService.get('POSTGRES_DB'), - username: configService.get('POSTGRES_USER'), - password: configService.get('POSTGRES_PASSWORD'), + host: configService.getOrThrow('DB_HOST'), + port: configService.getOrThrow('POSTGRES_PORT'), + database: configService.getOrThrow('POSTGRES_DB'), + username: configService.getOrThrow('POSTGRES_USER'), + password: configService.getOrThrow('POSTGRES_PASSWORD'), autoLoadEntities: true, synchronize: false, entities: ['dist/**/*.entity.js'], diff --git a/src/main.ts b/src/main.ts index 50c6e67..a19ed7c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,29 @@ import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { NestFactory, Reflector } from '@nestjs/core'; +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from './module/app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); - const PORT = configService.get('SERVER_PORT'); + const PORT = configService.getOrThrow('HTTP_PORT'); app.useGlobalPipes(new ValidationPipe()); app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector))); + + const configSwagger = new DocumentBuilder() + .setTitle('Events service') + .setDescription('API Documentation') + .setVersion('1.0') + .build(); + const document = SwaggerModule.createDocument(app, configSwagger); + SwaggerModule.setup( + `${configService.getOrThrow('HTTP_PREFIX')}/docs`, + app, + document, + ); await app.listen(PORT); } bootstrap(); diff --git a/src/migrations/1725817595096-Fix.ts b/src/migrations/1725817595096-Fix.ts new file mode 100644 index 0000000..efe38bb --- /dev/null +++ b/src/migrations/1725817595096-Fix.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Fix1725817595096 implements MigrationInterface { + name = 'Fix1725817595096' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "location" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "fullname" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "event" ALTER COLUMN "description" DROP NOT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "event" ALTER COLUMN "description" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "fullname" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "location" DROP NOT NULL`); + } + +} diff --git a/src/module/app.module.ts b/src/module/app.module.ts index 4b1073f..c9a9367 100644 --- a/src/module/app.module.ts +++ b/src/module/app.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { typeOrmAsyncConfig } from 'src/config/typeorm.config'; +import { typeOrmAsyncConfig } from '../config/typeorm.config'; import { AuthModule } from './auth/auth.module'; import { BookingModule } from './booking/booking.module'; import { EventModule } from './event/event.module'; diff --git a/src/module/auth/auth.controller.ts b/src/module/auth/auth.controller.ts index 373d871..cddc256 100644 --- a/src/module/auth/auth.controller.ts +++ b/src/module/auth/auth.controller.ts @@ -1,12 +1,13 @@ -import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common'; +import { Body, Controller, Post, UseGuards } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; import { UserFromRequest } from 'src/config/decorators/user.decorator'; import { AuthService } from './auth.service'; import { RegisterAuthDto } from './dto/register.auth.dto'; -import { AccessTokenGuard } from './guards/access-token.guard'; import { LocalGuard } from './guards/local.guard'; import { User } from '../user/entity/user.entity'; +@ApiTags('Auth') @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @@ -21,11 +22,4 @@ export class AuthController { login(@UserFromRequest() user: User) { return this.authService.login(user); } - - // todo: мёртвый код - @UseGuards(AccessTokenGuard) - @Get('logout') - logout() { - return 1; - } } diff --git a/src/module/auth/auth.service.ts b/src/module/auth/auth.service.ts index ee23eaa..a8bef98 100644 --- a/src/module/auth/auth.service.ts +++ b/src/module/auth/auth.service.ts @@ -2,11 +2,11 @@ import { Injectable, UnauthorizedException } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { JwtService } from '@nestjs/jwt'; import { verify } from 'argon2'; -import { UserRepository } from 'src/module/user/user.repository'; import { RegisterAuthDto } from './dto/register.auth.dto'; import { Payload } from './strategies/types/auth.types'; import { User } from '../user/entity/user.entity'; +import { UserRepository } from '../user/user.repository'; import { UserService } from '../user/user.service'; @Injectable() @@ -42,8 +42,8 @@ export class AuthService { private async getToken(user: User) { const payload: Payload = { id: user.id, role: user.role }; const accessToken = await this.jwtService.signAsync(payload, { - secret: this.configService.get('JWT_ACCESS_SECRET'), - expiresIn: this.configService.get('JWT_ACCESS_EXPIRATION_TIME'), + secret: this.configService.getOrThrow('JWT_ACCESS_SECRET'), + expiresIn: this.configService.getOrThrow('JWT_ACCESS_EXPIRATION_TIME'), }); return accessToken; } diff --git a/src/module/auth/dto/register.auth.dto.ts b/src/module/auth/dto/register.auth.dto.ts index ce0075f..29293e9 100644 --- a/src/module/auth/dto/register.auth.dto.ts +++ b/src/module/auth/dto/register.auth.dto.ts @@ -1,3 +1,3 @@ -import { CreateUserDto } from 'src/module/user/dto/create-user.dto'; +import { CreateUserDto } from '../../user/dto/create-user.dto'; export class RegisterAuthDto extends CreateUserDto {} diff --git a/src/module/auth/strategies/access-token.strategy.ts b/src/module/auth/strategies/access-token.strategy.ts index c7bea61..4240f8d 100644 --- a/src/module/auth/strategies/access-token.strategy.ts +++ b/src/module/auth/strategies/access-token.strategy.ts @@ -11,7 +11,7 @@ export class AccessTokenStrategy extends PassportStrategy(Strategy) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, - secretOrKey: configService.get('JWT_ACCESS_SECRET'), + secretOrKey: configService.getOrThrow('JWT_ACCESS_SECRET'), }); } diff --git a/src/module/booking/booking.controller.ts b/src/module/booking/booking.controller.ts index 5f25d4e..cc3bca6 100644 --- a/src/module/booking/booking.controller.ts +++ b/src/module/booking/booking.controller.ts @@ -8,12 +8,14 @@ import { Post, UseGuards, } from '@nestjs/common'; -import { UserFromRequest } from 'src/config/decorators/user.decorator'; +import { ApiTags } from '@nestjs/swagger'; import { BookingService } from './booking.service'; +import { UserFromRequest } from '../../config/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; +@ApiTags('Booking') @Controller() export class BookingController { constructor(private readonly bookingService: BookingService) {} diff --git a/src/module/booking/booking.module.ts b/src/module/booking/booking.module.ts index 148ec4b..21ae76d 100644 --- a/src/module/booking/booking.module.ts +++ b/src/module/booking/booking.module.ts @@ -2,10 +2,10 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { BookingController } from './booking.controller'; +import { BookingRepository } from './booking.repository'; import { BookingService } from './booking.service'; import { Booking } from './entity/booking.entity'; import { EventModule } from '../event/event.module'; -import { BookingRepository } from './booking.repository'; @Module({ imports: [TypeOrmModule.forFeature([Booking]), EventModule], diff --git a/src/module/booking/booking.repository.ts b/src/module/booking/booking.repository.ts index 0b45c0b..5db765c 100644 --- a/src/module/booking/booking.repository.ts +++ b/src/module/booking/booking.repository.ts @@ -1,27 +1,36 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; +import { Repository, Equal, DeepPartial } from 'typeorm'; import { Booking } from './entity/booking.entity'; -export class BookingRepository{ +export class BookingRepository { constructor( @InjectRepository(Booking) private readonly bookingRepository: Repository, ) {} - save(data) { - return this.bookingRepository.save(data) + save(entity: DeepPartial) { + return this.bookingRepository.save(entity); } - delete(data) { - return this.bookingRepository.delete(data) + delete(entity: Booking) { + return this.bookingRepository.delete(entity); } - findOneBy(data) { - return this.bookingRepository.findOneBy(data) + deleteBooking(userId: number, eventId: number) { + return this.bookingRepository.delete({ + user: Equal(userId), + event: Equal(eventId), + }); } - find(data) { - return this.bookingRepository.find(data) + findOneById(userId: number, eventId: number) { + return this.bookingRepository.findOneBy({ + user: Equal(userId), + event: Equal(eventId), + }); + } + findAll() { + return this.bookingRepository.find({ relations: ['user', 'event'] }); } } diff --git a/src/module/booking/booking.service.ts b/src/module/booking/booking.service.ts index 666e6f4..4d55544 100644 --- a/src/module/booking/booking.service.ts +++ b/src/module/booking/booking.service.ts @@ -3,7 +3,6 @@ import { Injectable, NotFoundException, } from '@nestjs/common'; -import { Equal } from 'typeorm'; import { BookingRepository } from './booking.repository'; import { EventRepository } from '../event/event.repository'; @@ -18,7 +17,7 @@ export class BookingService { async createBooking(user: User, eventId: number) { const event = await this.eventRepository.findOneById(eventId); - const isBookingExists = await this.findOneBooking(user, eventId); + const isBookingExists = await this.findOneBooking(user.id, eventId); if (isBookingExists) { throw new ConflictException(); } @@ -26,29 +25,16 @@ export class BookingService { } async deleteBooking(user: User, eventId: number) { - // todo: убрать формирование запроса в сервисе - // { - // user: Equal(user.id), - // event: Equal(eventId), - // } - const result = await this.bookingRepository.delete({ - user: Equal(user.id), - event: Equal(eventId), - }); + const result = await this.bookingRepository.deleteBooking(user.id, eventId); if (result.affected === 0) { throw new NotFoundException(); } } - private findOneBooking(user: User, eventId: number) { - // todo: убрать формирование запроса в сервисе - return this.bookingRepository.findOneBy({ - user: Equal(user.id), - event: Equal(eventId), - }); + private findOneBooking(userId: number, eventId: number) { + return this.bookingRepository.findOneById(userId, eventId); } findAll() { - // todo: убрать формирование запроса в сервисе - return this.bookingRepository.find({ relations: ['user', 'event'] }); + return this.bookingRepository.findAll(); } } diff --git a/src/module/booking/entity/booking.entity.ts b/src/module/booking/entity/booking.entity.ts index 0184dd0..f665e7c 100644 --- a/src/module/booking/entity/booking.entity.ts +++ b/src/module/booking/entity/booking.entity.ts @@ -1,7 +1,8 @@ -import { Event } from 'src/module/event/entity/event.entity'; -import { User } from 'src/module/user/entity/user.entity'; import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; +import { Event } from '../../event/entity/event.entity'; +import { User } from '../../user/entity/user.entity'; + @Entity() export class Booking { @PrimaryGeneratedColumn() diff --git a/src/module/event/dto/create-event.dto.ts b/src/module/event/dto/create-event.dto.ts index 2ae89a7..62bb1c1 100644 --- a/src/module/event/dto/create-event.dto.ts +++ b/src/module/event/dto/create-event.dto.ts @@ -5,7 +5,8 @@ import { IsPositive, IsString, } from 'class-validator'; -import { Location } from 'src/config/types/entity.enums'; + +import { Location } from '../../../config/types/entity.enums'; export class CreateEventDto { @IsString() @@ -16,7 +17,8 @@ export class CreateEventDto { @IsDateString() startDate: Date; - description: string; + @IsString() + description?: string; @IsEnum(Location) location: Location; diff --git a/src/module/event/dto/search-event.dto.ts b/src/module/event/dto/search-event.dto.ts index 4d4e97c..8ba1630 100644 --- a/src/module/event/dto/search-event.dto.ts +++ b/src/module/event/dto/search-event.dto.ts @@ -1,19 +1,11 @@ -import { IsEnum, IsNumberString, IsOptional, IsString } from 'class-validator'; -import { Location } from 'src/config/types/entity.enums'; +import { PartialType, PickType } from '@nestjs/swagger'; +import { IsNumberString, IsOptional } from 'class-validator'; -export class SearchEventDto { - @IsOptional() - @IsString() - title?: string; - - @IsOptional() - @IsString() - description?: string; - - @IsOptional() - @IsEnum(Location) - location?: Location; +import { CreateEventDto } from './create-event.dto'; +export class SearchEventDto extends PartialType( + PickType(CreateEventDto, ['title', 'description', 'location', 'tag']), +) { @IsOptional() @IsNumberString() priceFrom?: number; @@ -21,8 +13,4 @@ export class SearchEventDto { @IsOptional() @IsNumberString() priceTo?: number; - - @IsOptional() - @IsString() - tag?: string; } diff --git a/src/module/event/dto/update-event.dto.ts b/src/module/event/dto/update-event.dto.ts new file mode 100644 index 0000000..c26d0b1 --- /dev/null +++ b/src/module/event/dto/update-event.dto.ts @@ -0,0 +1,5 @@ +import { PartialType } from '@nestjs/swagger'; + +import { CreateEventDto } from './create-event.dto'; + +export class UpdateEventDto extends PartialType(CreateEventDto) {} diff --git a/src/module/event/entity/event.entity.ts b/src/module/event/entity/event.entity.ts index aea74fb..8da0fe7 100644 --- a/src/module/event/entity/event.entity.ts +++ b/src/module/event/entity/event.entity.ts @@ -1,6 +1,3 @@ -import { Location } from 'src/config/types/entity.enums'; -import { Booking } from 'src/module/booking/entity/booking.entity'; -import { User } from 'src/module/user/entity/user.entity'; import { Column, Entity, @@ -9,6 +6,10 @@ import { PrimaryGeneratedColumn, } from 'typeorm'; +import { Location } from '../../../config/types/entity.enums'; +import { Booking } from '../../booking/entity/booking.entity'; +import { User } from '../../user/entity/user.entity'; + @Entity() export class Event { @PrimaryGeneratedColumn() @@ -23,8 +24,11 @@ export class Event { @Column('timestamptz') startDate: Date; - @Column('text') - description: string; + @Column({ + type: 'text', + nullable: true, + }) + description?: string; @Column({ type: 'enum', @@ -39,5 +43,5 @@ export class Event { tag: string; @OneToMany(() => Booking, (booking) => booking.event) - bookings: Booking[]; + bookings?: Booking[]; } diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index f655c60..0a598b7 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -6,21 +6,25 @@ import { HttpCode, HttpStatus, Param, + ParseIntPipe, Patch, Post, Query, UseGuards, } from '@nestjs/common'; -import { UserFromRequest } from 'src/config/decorators/user.decorator'; +import { ApiTags } from '@nestjs/swagger'; import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; +import { UpdateEventDto } from './dto/update-event.dto'; import { EventService } from './event.service'; +import { UserFromRequest } from '../../config/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; import { OrganizerGuard } from '../user/guards/organizer.guard'; import { EventOwnerGuard } from '../user/guards/owner.guard'; +@ApiTags('Event') @Controller('event') export class EventController { constructor(private readonly eventService: EventService) {} @@ -34,32 +38,27 @@ export class EventController { return this.eventService.createEvent(user, createEventDto); } - @Get('search') - search(@Query() params: SearchEventDto) { - return this.eventService.getEvents(params); - } - @Get(':id') - read(@Param('id') id: number) { + read(@Param('id', ParseIntPipe) id: number) { return this.eventService.getOneById(id); } + @Get() + search(@Query() params: SearchEventDto) { + return this.eventService.getEvents(params); + } + // FIXME: не работает при id = string @Patch('update/:id') @UseGuards(AccessTokenGuard, EventOwnerGuard) - // todo: сделать отдельное dto для updateEventDto. Использовать PartialType - update(@Param('id') id: number, @Body() updateEventDto: CreateEventDto) { + update(@Param('id') id: number, @Body() updateEventDto: UpdateEventDto) { return this.eventService.updateEvent(id, updateEventDto); } + // FIXME: не работает при id = string @Delete(':id') @HttpCode(HttpStatus.NO_CONTENT) @UseGuards(AccessTokenGuard, EventOwnerGuard) delete(@Param('id') id: number) { return this.eventService.deleteEvent(id); } - - @Get() - getAll() { - return this.eventService.getAll(); - } } diff --git a/src/module/event/event.repository.ts b/src/module/event/event.repository.ts index 6128511..00b1ab5 100644 --- a/src/module/event/event.repository.ts +++ b/src/module/event/event.repository.ts @@ -1,6 +1,16 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { DeepPartial, Repository } from 'typeorm'; +import { + And, + DeepPartial, + Equal, + FindManyOptions, + ILike, + LessThanOrEqual, + MoreThanOrEqual, + Repository, +} from 'typeorm'; +import { SearchEventDto } from './dto/search-event.dto'; import { Event } from './entity/event.entity'; export class EventRepository { @@ -9,27 +19,44 @@ export class EventRepository { private readonly eventRepository: Repository, ) {} - // todo: переопределил метод из репозитория typeOrm. Это решится, если избавиться от наследования (смотри todo в user.reposutory) - async findOneById(id: number) { - return this.eventRepository.findOne({ - where: { id }, - relations: ['organizer'], - }); + create(entity: Partial) { + return this.eventRepository.create(entity); } - create(data: DeepPartial) { - return this.eventRepository.create(data) + save(entity: DeepPartial) { + return this.eventRepository.save(entity); } - save(data) { - return this.eventRepository.save(data) + deleteById(id: number) { + return this.eventRepository.delete(id); } - delete(data) { - return this.eventRepository.delete(data) + find(options: FindManyOptions) { + return this.eventRepository.find(options); } - find(data) { - return this.eventRepository.find(data) + findOneById(id: number) { + return this.eventRepository.findOne({ + where: { id }, + relations: ['organizer'], + }); + } + + findEvents(params: SearchEventDto) { + const { title, description, location, tag, priceTo } = params; + const priceFrom = params.priceFrom ?? 0; + + return this.eventRepository.find({ + where: { + title: title ? ILike(`%${title}%`) : null, + description: description ? ILike(`%${description}%`) : null, + location: location ? Equal(location) : null, + tag: tag ? ILike(`%${tag}%`) : null, + price: priceTo + ? And(MoreThanOrEqual(priceFrom), LessThanOrEqual(priceTo)) + : MoreThanOrEqual(priceFrom), + }, + relations: ['organizer'], + }); } } diff --git a/src/module/event/event.service.ts b/src/module/event/event.service.ts index d0d3ed2..9a7571f 100644 --- a/src/module/event/event.service.ts +++ b/src/module/event/event.service.ts @@ -1,18 +1,14 @@ import { Injectable, NotFoundException } from '@nestjs/common'; -import { MailerService } from '@nestjs-modules/mailer'; -import { And, Equal, ILike, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'; import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; +import { UpdateEventDto } from './dto/update-event.dto'; import { EventRepository } from './event.repository'; import { User } from '../user/entity/user.entity'; @Injectable() export class EventService { - constructor( - private readonly eventRepository: EventRepository, - private readonly mailerService: MailerService, - ) {} + constructor(private readonly eventRepository: EventRepository) {} async createEvent(user: User, createEventDto: CreateEventDto) { const event = this.eventRepository.create(createEventDto); @@ -20,11 +16,8 @@ export class EventService { return await this.eventRepository.save(event); } - async updateEvent(id: number, updateEventDto: CreateEventDto) { + async updateEvent(id: number, updateEventDto: UpdateEventDto) { const event = await this.eventRepository.findOneById(id); - if (!event) { - throw new NotFoundException(); - } const newEvent = { ...updateEventDto, id: event.id, @@ -34,7 +27,7 @@ export class EventService { } async deleteEvent(id: number) { - const result = await this.eventRepository.delete(id); + const result = await this.eventRepository.deleteById(id); if (result.affected === 0) { throw new NotFoundException(); } @@ -43,41 +36,7 @@ export class EventService { return this.eventRepository.findOneById(id); } - getAll() { - return this.eventRepository.find({ relations: ['organizer'] }); - } - getEvents(params: SearchEventDto) { - const { title, description, location, tag, priceTo } = params; - const priceFrom = params.priceFrom ?? 0; - return this.eventRepository.find({ - where: { - title: title ? ILike(`%${title}%`) : null, - description: description ? ILike(`%${description}%`) : null, - location: location ? Equal(location) : null, - tag: tag ? ILike(`%${tag}%`) : null, - price: priceTo - ? And(MoreThanOrEqual(priceFrom), LessThanOrEqual(priceTo)) - : MoreThanOrEqual(priceFrom), - }, - relations: ['organizer'], - }); - } - - // todo: мертвый код - sendEmail() { - this.mailerService - .sendMail({ - to: 'test@nestjs.com', - subject: 'Testing Nest MailerModule ✔', - text: 'welcome', - html: 'welcome', - }) - .then(() => { - console.log('success'); - }) - .catch((err) => { - console.log(err); - }); + return this.eventRepository.findEvents(params); } } diff --git a/src/module/mail/mail.module.ts b/src/module/mail/mail.module.ts index 7532049..8d1e122 100644 --- a/src/module/mail/mail.module.ts +++ b/src/module/mail/mail.module.ts @@ -8,16 +8,15 @@ import { MailerModule } from '@nestjs-modules/mailer'; inject: [ConfigService], useFactory: async (configService: ConfigService) => ({ transport: { - // todo: use configService.getOrThrow - host: configService.get('SMTP_HOST'), - port: configService.get('SMTP_PORT'), + host: configService.getOrThrow('SMTP_HOST'), + port: configService.getOrThrow('SMTP_PORT'), auth: { - user: configService.get('SMTP_USER'), - pass: configService.get('SMTP_PASS'), + user: configService.getOrThrow('SMTP_USER'), + pass: configService.getOrThrow('SMTP_PASS'), }, }, defaults: { - from: '"nest-modules" ', + from: configService.getOrThrow('SMTP_FROM'), }, }), }), diff --git a/src/module/scheduler/scheduler.service.ts b/src/module/scheduler/scheduler.service.ts index e2f6eb7..92b2224 100644 --- a/src/module/scheduler/scheduler.service.ts +++ b/src/module/scheduler/scheduler.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; import { Cron, CronExpression } from '@nestjs/schedule'; import { MailerService } from '@nestjs-modules/mailer'; @@ -9,6 +10,7 @@ export class SchedulerService { constructor( private readonly mailerService: MailerService, private readonly userService: UserService, + private readonly congigService: ConfigService, ) {} @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT) @@ -25,8 +27,8 @@ export class SchedulerService { const sendMailPromises = users.map(({ email }) => { return this.mailerService.sendMail({ to: email, - subject: 'Напоминание', - text: 'У вас назначена встреча сегодня', + subject: this.congigService.getOrThrow('EMAIL_SUBJECT'), + text: this.congigService.getOrThrow('EMAIL_TEXT'), }); }); await Promise.all(sendMailPromises); diff --git a/src/module/user/dto/create-user.dto.ts b/src/module/user/dto/create-user.dto.ts index a7059f3..7e564c2 100644 --- a/src/module/user/dto/create-user.dto.ts +++ b/src/module/user/dto/create-user.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsEnum, @@ -5,11 +6,10 @@ import { IsString, IsStrongPassword, } from 'class-validator'; -import { Location, UserRole } from 'src/config/types/entity.enums'; -export class CreateUserDto { - id: number; +import { Location, UserRole } from '../../../config/types/entity.enums'; +export class CreateUserDto { @IsEmail() email: string; @@ -22,7 +22,8 @@ export class CreateUserDto { @IsString() fullname: string; + @ApiProperty({ default: UserRole.USER }) @IsOptional() @IsEnum(UserRole) - role: UserRole; + role?: UserRole; } diff --git a/src/module/user/dto/update-user.dto.ts b/src/module/user/dto/update-user.dto.ts index 22da112..92d12c0 100644 --- a/src/module/user/dto/update-user.dto.ts +++ b/src/module/user/dto/update-user.dto.ts @@ -1,12 +1,8 @@ -import { IsEnum, IsOptional, IsString } from 'class-validator'; -import { Location } from 'src/config/types/entity.enums'; +import { PartialType, PickType } from '@nestjs/swagger'; -export class UpdateUserDto { - @IsEnum(Location) - @IsOptional() - location: Location; +import { CreateUserDto } from './create-user.dto'; - @IsString() - @IsOptional() - fullname: string; -} +export class UpdateUserDto extends PickType(PartialType(CreateUserDto), [ + 'location', + 'fullname', +]) {} diff --git a/src/module/user/entity/user.entity.ts b/src/module/user/entity/user.entity.ts index 0009405..d091cb7 100644 --- a/src/module/user/entity/user.entity.ts +++ b/src/module/user/entity/user.entity.ts @@ -1,9 +1,10 @@ import { Exclude } from 'class-transformer'; -import { UserRole, Location } from 'src/config/types/entity.enums'; -import { Booking } from 'src/module/booking/entity/booking.entity'; -import { Event } from 'src/module/event/entity/event.entity'; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; +import { UserRole, Location } from '../../../config/types/entity.enums'; +import { Booking } from '../../booking/entity/booking.entity'; +import { Event } from '../../event/entity/event.entity'; + @Entity() export class User { @PrimaryGeneratedColumn() @@ -21,13 +22,10 @@ export class User { @Column({ type: 'enum', enum: Location, - nullable: true, }) location: Location; - @Column({ - nullable: true, - }) + @Column() fullname: string; @Column({ @@ -38,8 +36,8 @@ export class User { role: UserRole; @OneToMany(() => Event, (event) => event.organizer) - events: Event[]; + events?: Event[]; @OneToMany(() => Booking, (booking) => booking.user) - bookings: Booking[]; + bookings?: Booking[]; } diff --git a/src/module/user/guards/organizer.guard.ts b/src/module/user/guards/organizer.guard.ts index 14bbb3f..e2ebf0f 100644 --- a/src/module/user/guards/organizer.guard.ts +++ b/src/module/user/guards/organizer.guard.ts @@ -1,7 +1,7 @@ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; -import { UserRole } from 'src/config/types/entity.enums'; -// todo: как будто по логике этот guard должен быть в другом модуле +import { UserRole } from '../../../config/types/entity.enums'; + @Injectable() export class OrganizerGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { diff --git a/src/module/user/guards/owner.guard.ts b/src/module/user/guards/owner.guard.ts index f745308..9f77ab4 100644 --- a/src/module/user/guards/owner.guard.ts +++ b/src/module/user/guards/owner.guard.ts @@ -1,7 +1,7 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; -import { EventRepository } from 'src/module/event/event.repository'; -// todo: как будто по логике этот guard должен быть в другом модуле +import { EventRepository } from '../../event/event.repository'; + @Injectable() export class EventOwnerGuard implements CanActivate { constructor(private eventRepository: EventRepository) {} @@ -11,6 +11,6 @@ export class EventOwnerGuard implements CanActivate { const id = request.params.id; const event = await this.eventRepository.findOneById(id); - return event.organizer.id === user.id; + return event?.organizer.id === user.id; } } diff --git a/src/module/user/user.controller.ts b/src/module/user/user.controller.ts index a5c6223..e4155f5 100644 --- a/src/module/user/user.controller.ts +++ b/src/module/user/user.controller.ts @@ -1,11 +1,13 @@ import { Body, Get, Patch, UseGuards, Controller } from '@nestjs/common'; -import { UserFromRequest } from 'src/config/decorators/user.decorator'; +import { ApiTags } from '@nestjs/swagger'; import { UpdateUserDto } from './dto/update-user.dto'; import { User } from './entity/user.entity'; import { UserService } from './user.service'; +import { UserFromRequest } from '../../config/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; +@ApiTags('User') @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} diff --git a/src/module/user/user.module.ts b/src/module/user/user.module.ts index 559a7f6..643aa61 100644 --- a/src/module/user/user.module.ts +++ b/src/module/user/user.module.ts @@ -1,9 +1,9 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { UserRepository } from 'src/module/user/user.repository'; import { User } from './entity/user.entity'; import { UserController } from './user.controller'; +import { UserRepository } from './user.repository'; import { UserService } from './user.service'; @Module({ diff --git a/src/module/user/user.repository.ts b/src/module/user/user.repository.ts index 8869b74..ca84e5f 100644 --- a/src/module/user/user.repository.ts +++ b/src/module/user/user.repository.ts @@ -1,20 +1,20 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { User } from 'src/module/user/entity/user.entity'; import { Between, Repository } from 'typeorm'; -// todo: не использовать наследование, а делать обёртку +import { User } from './entity/user.entity'; + export class UserRepository { constructor( @InjectRepository(User) private readonly userRepository: Repository, ) {} -//naming - find(data){ - return this.userRepository.find(data) + + find() { + return this.userRepository.find({ relations: ['events'] }); } - save(data){ - return this.userRepository.save(data) + save(entity: Partial) { + return this.userRepository.save(entity); } findOneByEmail(email: string) { diff --git a/src/module/user/user.service.ts b/src/module/user/user.service.ts index 0868379..198c3e4 100644 --- a/src/module/user/user.service.ts +++ b/src/module/user/user.service.ts @@ -1,10 +1,9 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { hash } from 'argon2'; -// todo: делать относительные пути везде либо использовать настройку шорткатов через ts-config -import { UserRepository } from 'src/module/user/user.repository'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; +import { UserRepository } from './user.repository'; @Injectable() export class UserService { @@ -30,12 +29,11 @@ export class UserService { fullname: updateUserDto.fullname, location: updateUserDto.location, }; - return this.userRepository.save(updatedUser); } getAll() { - return this.userRepository.find({ relations: ['events'] }); + return this.userRepository.find(); } getUsersWithAppointments(today: Date, tomorrow: Date) { diff --git a/tsconfig.json b/tsconfig.json index 95f5641..3b92ed7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,6 @@ "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false + "noFallthroughCasesInSwitch": false, } } From fbea220a9840a280b475d52b7888efecd76dac40 Mon Sep 17 00:00:00 2001 From: mikhail Date: Mon, 9 Sep 2024 22:06:17 +0500 Subject: [PATCH 4/7] fix --- .env.example | 2 +- src/{ => common}/config/typeorm.config.ts | 2 +- src/{config => common}/decorators/user.decorator.ts | 0 .../auth/strategies => common}/types/auth.types.ts | 2 +- src/{config => common}/types/entity.enums.ts | 0 src/common/utils/parse-id.ts | 9 +++++++++ src/module/app.module.ts | 2 +- src/module/auth/auth.controller.ts | 2 +- src/module/auth/auth.service.ts | 2 +- src/module/auth/strategies/access-token.strategy.ts | 2 +- src/module/booking/booking.controller.ts | 2 +- src/module/event/dto/create-event.dto.ts | 2 +- src/module/event/entity/event.entity.ts | 2 +- src/module/event/event.controller.ts | 4 +--- src/module/user/dto/create-user.dto.ts | 2 +- src/module/user/entity/user.entity.ts | 2 +- src/module/user/guards/organizer.guard.ts | 2 +- src/module/user/guards/owner.guard.ts | 4 +++- src/module/user/user.controller.ts | 2 +- 19 files changed, 27 insertions(+), 18 deletions(-) rename src/{ => common}/config/typeorm.config.ts (94%) rename src/{config => common}/decorators/user.decorator.ts (100%) rename src/{module/auth/strategies => common}/types/auth.types.ts (50%) rename src/{config => common}/types/entity.enums.ts (100%) create mode 100644 src/common/utils/parse-id.ts diff --git a/.env.example b/.env.example index fc923ea..48ca2e6 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ JWT_ACCESS_SECRET=example JWT_ACCESS_EXPIRATION_TIME=1d SMTP_HOST=sandbox.smtp.mailtrap.io -SMTP_POTY=2525 +SMTP_PORT=2525 SMTP_USER=example SMTP_PASS=example SMTP_FROM='"nest-modules" ' diff --git a/src/config/typeorm.config.ts b/src/common/config/typeorm.config.ts similarity index 94% rename from src/config/typeorm.config.ts rename to src/common/config/typeorm.config.ts index a8f1b1e..c1ddafb 100644 --- a/src/config/typeorm.config.ts +++ b/src/common/config/typeorm.config.ts @@ -11,7 +11,7 @@ config(); const configService = new ConfigService(); const databaseConfig = { type: 'postgres' as const, - host: configService.getOrThrow('DB_HOST'), + // host: configService.getOrThrow('DB_HOST'), port: configService.getOrThrow('POSTGRES_PORT'), database: configService.getOrThrow('POSTGRES_DB'), username: configService.getOrThrow('POSTGRES_USER'), diff --git a/src/config/decorators/user.decorator.ts b/src/common/decorators/user.decorator.ts similarity index 100% rename from src/config/decorators/user.decorator.ts rename to src/common/decorators/user.decorator.ts diff --git a/src/module/auth/strategies/types/auth.types.ts b/src/common/types/auth.types.ts similarity index 50% rename from src/module/auth/strategies/types/auth.types.ts rename to src/common/types/auth.types.ts index 68a8171..d86ffd4 100644 --- a/src/module/auth/strategies/types/auth.types.ts +++ b/src/common/types/auth.types.ts @@ -1,4 +1,4 @@ -import { UserRole } from 'src/config/types/entity.enums'; +import { UserRole } from 'src/common/types/entity.enums'; export type Payload = { id: number; diff --git a/src/config/types/entity.enums.ts b/src/common/types/entity.enums.ts similarity index 100% rename from src/config/types/entity.enums.ts rename to src/common/types/entity.enums.ts diff --git a/src/common/utils/parse-id.ts b/src/common/utils/parse-id.ts new file mode 100644 index 0000000..2485553 --- /dev/null +++ b/src/common/utils/parse-id.ts @@ -0,0 +1,9 @@ +import { BadRequestException } from '@nestjs/common'; + +export function parseId(id: string) { + const parsedId = parseInt(id, 10); + if (isNaN(parsedId)) { + throw new BadRequestException(); + } + return parsedId; +} diff --git a/src/module/app.module.ts b/src/module/app.module.ts index c9a9367..0d96580 100644 --- a/src/module/app.module.ts +++ b/src/module/app.module.ts @@ -2,13 +2,13 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { typeOrmAsyncConfig } from '../config/typeorm.config'; import { AuthModule } from './auth/auth.module'; import { BookingModule } from './booking/booking.module'; import { EventModule } from './event/event.module'; import { MailModule } from './mail/mail.module'; import { SchedulerModule } from './scheduler/scheduler.module'; import { UserModule } from './user/user.module'; +import { typeOrmAsyncConfig } from '../common/config/typeorm.config'; @Module({ imports: [ diff --git a/src/module/auth/auth.controller.ts b/src/module/auth/auth.controller.ts index cddc256..efd6459 100644 --- a/src/module/auth/auth.controller.ts +++ b/src/module/auth/auth.controller.ts @@ -1,10 +1,10 @@ import { Body, Controller, Post, UseGuards } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; -import { UserFromRequest } from 'src/config/decorators/user.decorator'; import { AuthService } from './auth.service'; import { RegisterAuthDto } from './dto/register.auth.dto'; import { LocalGuard } from './guards/local.guard'; +import { UserFromRequest } from '../../common/decorators/user.decorator'; import { User } from '../user/entity/user.entity'; @ApiTags('Auth') diff --git a/src/module/auth/auth.service.ts b/src/module/auth/auth.service.ts index a8bef98..be847eb 100644 --- a/src/module/auth/auth.service.ts +++ b/src/module/auth/auth.service.ts @@ -4,7 +4,7 @@ import { JwtService } from '@nestjs/jwt'; import { verify } from 'argon2'; import { RegisterAuthDto } from './dto/register.auth.dto'; -import { Payload } from './strategies/types/auth.types'; +import { Payload } from '../../common/types/auth.types'; import { User } from '../user/entity/user.entity'; import { UserRepository } from '../user/user.repository'; import { UserService } from '../user/user.service'; diff --git a/src/module/auth/strategies/access-token.strategy.ts b/src/module/auth/strategies/access-token.strategy.ts index 4240f8d..d8ce9f7 100644 --- a/src/module/auth/strategies/access-token.strategy.ts +++ b/src/module/auth/strategies/access-token.strategy.ts @@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; -import { Payload } from './types/auth.types'; +import { Payload } from '../../../common/types/auth.types'; @Injectable() export class AccessTokenStrategy extends PassportStrategy(Strategy) { diff --git a/src/module/booking/booking.controller.ts b/src/module/booking/booking.controller.ts index cc3bca6..e795318 100644 --- a/src/module/booking/booking.controller.ts +++ b/src/module/booking/booking.controller.ts @@ -11,7 +11,7 @@ import { import { ApiTags } from '@nestjs/swagger'; import { BookingService } from './booking.service'; -import { UserFromRequest } from '../../config/decorators/user.decorator'; +import { UserFromRequest } from '../../common/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; diff --git a/src/module/event/dto/create-event.dto.ts b/src/module/event/dto/create-event.dto.ts index 62bb1c1..2aa458d 100644 --- a/src/module/event/dto/create-event.dto.ts +++ b/src/module/event/dto/create-event.dto.ts @@ -6,7 +6,7 @@ import { IsString, } from 'class-validator'; -import { Location } from '../../../config/types/entity.enums'; +import { Location } from '../../../common/types/entity.enums'; export class CreateEventDto { @IsString() diff --git a/src/module/event/entity/event.entity.ts b/src/module/event/entity/event.entity.ts index 8da0fe7..742d14c 100644 --- a/src/module/event/entity/event.entity.ts +++ b/src/module/event/entity/event.entity.ts @@ -6,7 +6,7 @@ import { PrimaryGeneratedColumn, } from 'typeorm'; -import { Location } from '../../../config/types/entity.enums'; +import { Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { User } from '../../user/entity/user.entity'; diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index 0a598b7..6b7d512 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -18,7 +18,7 @@ import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; import { UpdateEventDto } from './dto/update-event.dto'; import { EventService } from './event.service'; -import { UserFromRequest } from '../../config/decorators/user.decorator'; +import { UserFromRequest } from '../../common/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; import { OrganizerGuard } from '../user/guards/organizer.guard'; @@ -47,14 +47,12 @@ export class EventController { search(@Query() params: SearchEventDto) { return this.eventService.getEvents(params); } - // FIXME: не работает при id = string @Patch('update/:id') @UseGuards(AccessTokenGuard, EventOwnerGuard) update(@Param('id') id: number, @Body() updateEventDto: UpdateEventDto) { return this.eventService.updateEvent(id, updateEventDto); } - // FIXME: не работает при id = string @Delete(':id') @HttpCode(HttpStatus.NO_CONTENT) @UseGuards(AccessTokenGuard, EventOwnerGuard) diff --git a/src/module/user/dto/create-user.dto.ts b/src/module/user/dto/create-user.dto.ts index 7e564c2..ed31eda 100644 --- a/src/module/user/dto/create-user.dto.ts +++ b/src/module/user/dto/create-user.dto.ts @@ -7,7 +7,7 @@ import { IsStrongPassword, } from 'class-validator'; -import { Location, UserRole } from '../../../config/types/entity.enums'; +import { Location, UserRole } from '../../../common/types/entity.enums'; export class CreateUserDto { @IsEmail() diff --git a/src/module/user/entity/user.entity.ts b/src/module/user/entity/user.entity.ts index d091cb7..cdbf802 100644 --- a/src/module/user/entity/user.entity.ts +++ b/src/module/user/entity/user.entity.ts @@ -1,7 +1,7 @@ import { Exclude } from 'class-transformer'; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; -import { UserRole, Location } from '../../../config/types/entity.enums'; +import { UserRole, Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { Event } from '../../event/entity/event.entity'; diff --git a/src/module/user/guards/organizer.guard.ts b/src/module/user/guards/organizer.guard.ts index e2ebf0f..fe6a71b 100644 --- a/src/module/user/guards/organizer.guard.ts +++ b/src/module/user/guards/organizer.guard.ts @@ -1,6 +1,6 @@ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; -import { UserRole } from '../../../config/types/entity.enums'; +import { UserRole } from '../../../common/types/entity.enums'; @Injectable() export class OrganizerGuard implements CanActivate { diff --git a/src/module/user/guards/owner.guard.ts b/src/module/user/guards/owner.guard.ts index 9f77ab4..c9dc77e 100644 --- a/src/module/user/guards/owner.guard.ts +++ b/src/module/user/guards/owner.guard.ts @@ -1,5 +1,6 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { parseId } from '../../../common/utils/parse-id'; import { EventRepository } from '../../event/event.repository'; @Injectable() @@ -9,7 +10,8 @@ export class EventOwnerGuard implements CanActivate { const request = context.switchToHttp().getRequest(); const user = request.user; const id = request.params.id; - const event = await this.eventRepository.findOneById(id); + const parsedId = parseId(id); + const event = await this.eventRepository.findOneById(parsedId); return event?.organizer.id === user.id; } diff --git a/src/module/user/user.controller.ts b/src/module/user/user.controller.ts index e4155f5..b9726a7 100644 --- a/src/module/user/user.controller.ts +++ b/src/module/user/user.controller.ts @@ -4,7 +4,7 @@ import { ApiTags } from '@nestjs/swagger'; import { UpdateUserDto } from './dto/update-user.dto'; import { User } from './entity/user.entity'; import { UserService } from './user.service'; -import { UserFromRequest } from '../../config/decorators/user.decorator'; +import { UserFromRequest } from '../../common/decorators/user.decorator'; import { AccessTokenGuard } from '../auth/guards/access-token.guard'; @ApiTags('User') From f02f4cae5b146b268263903042bc4159145291cd Mon Sep 17 00:00:00 2001 From: mikhail Date: Mon, 9 Sep 2024 22:15:01 +0500 Subject: [PATCH 5/7] fix --- .env.example | 13 ++++++++++++- src/module/auth/auth.controller.ts | 10 ++++++++++ src/module/booking/booking.controller.ts | 7 +++++++ src/module/event/dto/create-event.dto.ts | 9 +++++++++ src/module/event/entity/event.entity.ts | 9 +++++++++ src/module/event/event.controller.ts | 21 +++++++++++++++++++++ src/module/user/dto/create-user.dto.ts | 9 +++++++++ src/module/user/entity/user.entity.ts | 9 +++++++++ src/module/user/guards/organizer.guard.ts | 9 +++++++++ src/module/user/guards/owner.guard.ts | 10 ++++++++++ src/module/user/user.controller.ts | 7 +++++++ 11 files changed, 112 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 48ca2e6..cb29f73 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,12 @@ POSTGRES_PASSWORD=example JWT_ACCESS_SECRET=example JWT_ACCESS_EXPIRATION_TIME=1d +<<<<<<< Updated upstream +======= +<<<<<<< Updated upstream +# todo: заполнить примерами данных и\или локальными кредами +======= +>>>>>>> Stashed changes SMTP_HOST=sandbox.smtp.mailtrap.io SMTP_PORT=2525 SMTP_USER=example @@ -19,4 +25,9 @@ SMTP_PASS=example SMTP_FROM='"nest-modules" ' EMAIL_SUBJECT='Напоминание' -EMAIL_TEXT='У вас назначена встреча сегодня' \ No newline at end of file +<<<<<<< Updated upstream +EMAIL_TEXT='У вас назначена встреча сегодня' +======= +EMAIL_TEXT='У вас назначена встреча сегодня' +>>>>>>> Stashed changes +>>>>>>> Stashed changes diff --git a/src/module/auth/auth.controller.ts b/src/module/auth/auth.controller.ts index efd6459..c09a066 100644 --- a/src/module/auth/auth.controller.ts +++ b/src/module/auth/auth.controller.ts @@ -1,5 +1,15 @@ +<<<<<<< Updated upstream import { Body, Controller, Post, UseGuards } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; +======= +<<<<<<< Updated upstream +import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common'; +import { UserFromRequest } from 'src/config/decorators/user.decorator'; +======= +import { Body, Controller, Post, UseGuards } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes import { AuthService } from './auth.service'; import { RegisterAuthDto } from './dto/register.auth.dto'; diff --git a/src/module/booking/booking.controller.ts b/src/module/booking/booking.controller.ts index e795318..4405986 100644 --- a/src/module/booking/booking.controller.ts +++ b/src/module/booking/booking.controller.ts @@ -11,7 +11,14 @@ import { import { ApiTags } from '@nestjs/swagger'; import { BookingService } from './booking.service'; +<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; +======= +<<<<<<< Updated upstream +======= +import { UserFromRequest } from '../../common/decorators/user.decorator'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; diff --git a/src/module/event/dto/create-event.dto.ts b/src/module/event/dto/create-event.dto.ts index 2aa458d..9dbce9b 100644 --- a/src/module/event/dto/create-event.dto.ts +++ b/src/module/event/dto/create-event.dto.ts @@ -5,8 +5,17 @@ import { IsPositive, IsString, } from 'class-validator'; +<<<<<<< Updated upstream import { Location } from '../../../common/types/entity.enums'; +======= +<<<<<<< Updated upstream +import { Location } from 'src/config/types/entity.enums'; +======= + +import { Location } from '../../../common/types/entity.enums'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes export class CreateEventDto { @IsString() diff --git a/src/module/event/entity/event.entity.ts b/src/module/event/entity/event.entity.ts index 742d14c..602330a 100644 --- a/src/module/event/entity/event.entity.ts +++ b/src/module/event/entity/event.entity.ts @@ -6,10 +6,19 @@ import { PrimaryGeneratedColumn, } from 'typeorm'; +<<<<<<< Updated upstream +======= +<<<<<<< Updated upstream +======= +>>>>>>> Stashed changes import { Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { User } from '../../user/entity/user.entity'; +<<<<<<< Updated upstream +======= +>>>>>>> Stashed changes +>>>>>>> Stashed changes @Entity() export class Event { @PrimaryGeneratedColumn() diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index 6b7d512..a61b557 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -18,7 +18,14 @@ import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; import { UpdateEventDto } from './dto/update-event.dto'; import { EventService } from './event.service'; +<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; +======= +<<<<<<< Updated upstream +======= +import { UserFromRequest } from '../../common/decorators/user.decorator'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; import { OrganizerGuard } from '../user/guards/organizer.guard'; @@ -38,15 +45,29 @@ export class EventController { return this.eventService.createEvent(user, createEventDto); } +<<<<<<< Updated upstream +======= + @Get('search') + search(@Query() params: SearchEventDto) { + return this.eventService.getEvents(params); + } +<<<<<<< Updated upstream + +>>>>>>> Stashed changes @Get(':id') read(@Param('id', ParseIntPipe) id: number) { return this.eventService.getOneById(id); } +<<<<<<< Updated upstream @Get() search(@Query() params: SearchEventDto) { return this.eventService.getEvents(params); } +======= +======= +>>>>>>> Stashed changes +>>>>>>> Stashed changes @Patch('update/:id') @UseGuards(AccessTokenGuard, EventOwnerGuard) update(@Param('id') id: number, @Body() updateEventDto: UpdateEventDto) { diff --git a/src/module/user/dto/create-user.dto.ts b/src/module/user/dto/create-user.dto.ts index ed31eda..9bedf92 100644 --- a/src/module/user/dto/create-user.dto.ts +++ b/src/module/user/dto/create-user.dto.ts @@ -6,8 +6,17 @@ import { IsString, IsStrongPassword, } from 'class-validator'; +<<<<<<< Updated upstream import { Location, UserRole } from '../../../common/types/entity.enums'; +======= +<<<<<<< Updated upstream +import { Location, UserRole } from 'src/config/types/entity.enums'; +======= + +import { Location, UserRole } from '../../../common/types/entity.enums'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes export class CreateUserDto { @IsEmail() diff --git a/src/module/user/entity/user.entity.ts b/src/module/user/entity/user.entity.ts index cdbf802..a388688 100644 --- a/src/module/user/entity/user.entity.ts +++ b/src/module/user/entity/user.entity.ts @@ -1,10 +1,19 @@ import { Exclude } from 'class-transformer'; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; +<<<<<<< Updated upstream +======= +<<<<<<< Updated upstream +======= +>>>>>>> Stashed changes import { UserRole, Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { Event } from '../../event/entity/event.entity'; +<<<<<<< Updated upstream +======= +>>>>>>> Stashed changes +>>>>>>> Stashed changes @Entity() export class User { @PrimaryGeneratedColumn() diff --git a/src/module/user/guards/organizer.guard.ts b/src/module/user/guards/organizer.guard.ts index fe6a71b..61c9211 100644 --- a/src/module/user/guards/organizer.guard.ts +++ b/src/module/user/guards/organizer.guard.ts @@ -1,7 +1,16 @@ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; +<<<<<<< Updated upstream import { UserRole } from '../../../common/types/entity.enums'; +======= +<<<<<<< Updated upstream +// todo: как будто по логике этот guard должен быть в другом модуле +======= +import { UserRole } from '../../../common/types/entity.enums'; + +>>>>>>> Stashed changes +>>>>>>> Stashed changes @Injectable() export class OrganizerGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { diff --git a/src/module/user/guards/owner.guard.ts b/src/module/user/guards/owner.guard.ts index c9dc77e..ee2c1c9 100644 --- a/src/module/user/guards/owner.guard.ts +++ b/src/module/user/guards/owner.guard.ts @@ -1,8 +1,18 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +<<<<<<< Updated upstream import { parseId } from '../../../common/utils/parse-id'; import { EventRepository } from '../../event/event.repository'; +======= +<<<<<<< Updated upstream +// todo: как будто по логике этот guard должен быть в другом модуле +======= +import { parseId } from '../../../common/utils/parse-id'; +import { EventRepository } from '../../event/event.repository'; + +>>>>>>> Stashed changes +>>>>>>> Stashed changes @Injectable() export class EventOwnerGuard implements CanActivate { constructor(private eventRepository: EventRepository) {} diff --git a/src/module/user/user.controller.ts b/src/module/user/user.controller.ts index b9726a7..b6e561b 100644 --- a/src/module/user/user.controller.ts +++ b/src/module/user/user.controller.ts @@ -4,7 +4,14 @@ import { ApiTags } from '@nestjs/swagger'; import { UpdateUserDto } from './dto/update-user.dto'; import { User } from './entity/user.entity'; import { UserService } from './user.service'; +<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; +======= +<<<<<<< Updated upstream +======= +import { UserFromRequest } from '../../common/decorators/user.decorator'; +>>>>>>> Stashed changes +>>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; @ApiTags('User') From 896a9042487f13bebca7ce5725125c8c5438ef0f Mon Sep 17 00:00:00 2001 From: mikhail Date: Mon, 9 Sep 2024 22:15:08 +0500 Subject: [PATCH 6/7] fix --- src/common/config/typeorm.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/config/typeorm.config.ts b/src/common/config/typeorm.config.ts index c1ddafb..b41662f 100644 --- a/src/common/config/typeorm.config.ts +++ b/src/common/config/typeorm.config.ts @@ -11,7 +11,6 @@ config(); const configService = new ConfigService(); const databaseConfig = { type: 'postgres' as const, - // host: configService.getOrThrow('DB_HOST'), port: configService.getOrThrow('POSTGRES_PORT'), database: configService.getOrThrow('POSTGRES_DB'), username: configService.getOrThrow('POSTGRES_USER'), From e973d08efc5c2d45b6b2dba712819326fe06a905 Mon Sep 17 00:00:00 2001 From: mikhail Date: Mon, 9 Sep 2024 22:40:54 +0500 Subject: [PATCH 7/7] fix --- .env.example | 13 +------- package.json | 6 ++-- src/common/config/typeorm.config.ts | 1 + src/migrations/1725817595096-Fix.ts | 37 +++++++++++++++-------- src/module/auth/auth.controller.ts | 10 ------ src/module/booking/booking.controller.ts | 7 ----- src/module/event/dto/create-event.dto.ts | 9 ------ src/module/event/entity/event.entity.ts | 9 ------ src/module/event/event.controller.ts | 20 ------------ src/module/user/dto/create-user.dto.ts | 9 ------ src/module/user/entity/user.entity.ts | 9 ------ src/module/user/guards/organizer.guard.ts | 10 ------ src/module/user/guards/owner.guard.ts | 10 ------ src/module/user/user.controller.ts | 7 ----- 14 files changed, 29 insertions(+), 128 deletions(-) diff --git a/.env.example b/.env.example index cb29f73..48ca2e6 100644 --- a/.env.example +++ b/.env.example @@ -12,12 +12,6 @@ POSTGRES_PASSWORD=example JWT_ACCESS_SECRET=example JWT_ACCESS_EXPIRATION_TIME=1d -<<<<<<< Updated upstream -======= -<<<<<<< Updated upstream -# todo: заполнить примерами данных и\или локальными кредами -======= ->>>>>>> Stashed changes SMTP_HOST=sandbox.smtp.mailtrap.io SMTP_PORT=2525 SMTP_USER=example @@ -25,9 +19,4 @@ SMTP_PASS=example SMTP_FROM='"nest-modules" ' EMAIL_SUBJECT='Напоминание' -<<<<<<< Updated upstream -EMAIL_TEXT='У вас назначена встреча сегодня' -======= -EMAIL_TEXT='У вас назначена встреча сегодня' ->>>>>>> Stashed changes ->>>>>>> Stashed changes +EMAIL_TEXT='У вас назначена встреча сегодня' \ No newline at end of file diff --git a/package.json b/package.json index 1752222..dabcc95 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "typeorm": "ts-node ./node_modules/typeorm/cli", "migration:create": "npm run typeorm -- migration:create ./src/migrations/$npm_config_name", - "migration:generate": "npm run typeorm -- -d src/config/typeorm.config.ts migration:generate ./src/migrations/$npm_config_name", - "migration:run": "npm run typeorm migration:run -- -d src/config/typeorm.config.ts", - "migration:revert": "npm run typeorm -- -d src/config/typeorm.config.ts migration:revert", + "migration:generate": "npm run typeorm -- -d src/common/config/typeorm.config.ts migration:generate ./src/migrations/$npm_config_name", + "migration:run": "npm run typeorm migration:run -- -d src/common/config/typeorm.config.ts", + "migration:revert": "npm run typeorm -- -d src/common/config/typeorm.config.ts migration:revert", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", diff --git a/src/common/config/typeorm.config.ts b/src/common/config/typeorm.config.ts index b41662f..a8f1b1e 100644 --- a/src/common/config/typeorm.config.ts +++ b/src/common/config/typeorm.config.ts @@ -11,6 +11,7 @@ config(); const configService = new ConfigService(); const databaseConfig = { type: 'postgres' as const, + host: configService.getOrThrow('DB_HOST'), port: configService.getOrThrow('POSTGRES_PORT'), database: configService.getOrThrow('POSTGRES_DB'), username: configService.getOrThrow('POSTGRES_USER'), diff --git a/src/migrations/1725817595096-Fix.ts b/src/migrations/1725817595096-Fix.ts index efe38bb..a6a59e7 100644 --- a/src/migrations/1725817595096-Fix.ts +++ b/src/migrations/1725817595096-Fix.ts @@ -1,18 +1,29 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class Fix1725817595096 implements MigrationInterface { - name = 'Fix1725817595096' + name = 'Fix1725817595096'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "location" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "fullname" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "event" ALTER COLUMN "description" DROP NOT NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "event" ALTER COLUMN "description" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "fullname" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "location" DROP NOT NULL`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "location" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "fullname" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "event" ALTER COLUMN "description" DROP NOT NULL`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "event" ALTER COLUMN "description" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "fullname" DROP NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "location" DROP NOT NULL`, + ); + } } diff --git a/src/module/auth/auth.controller.ts b/src/module/auth/auth.controller.ts index c09a066..efd6459 100644 --- a/src/module/auth/auth.controller.ts +++ b/src/module/auth/auth.controller.ts @@ -1,15 +1,5 @@ -<<<<<<< Updated upstream import { Body, Controller, Post, UseGuards } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; -======= -<<<<<<< Updated upstream -import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common'; -import { UserFromRequest } from 'src/config/decorators/user.decorator'; -======= -import { Body, Controller, Post, UseGuards } from '@nestjs/common'; -import { ApiTags } from '@nestjs/swagger'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes import { AuthService } from './auth.service'; import { RegisterAuthDto } from './dto/register.auth.dto'; diff --git a/src/module/booking/booking.controller.ts b/src/module/booking/booking.controller.ts index 4405986..e795318 100644 --- a/src/module/booking/booking.controller.ts +++ b/src/module/booking/booking.controller.ts @@ -11,14 +11,7 @@ import { import { ApiTags } from '@nestjs/swagger'; import { BookingService } from './booking.service'; -<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; -======= -<<<<<<< Updated upstream -======= -import { UserFromRequest } from '../../common/decorators/user.decorator'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; diff --git a/src/module/event/dto/create-event.dto.ts b/src/module/event/dto/create-event.dto.ts index 9dbce9b..2aa458d 100644 --- a/src/module/event/dto/create-event.dto.ts +++ b/src/module/event/dto/create-event.dto.ts @@ -5,17 +5,8 @@ import { IsPositive, IsString, } from 'class-validator'; -<<<<<<< Updated upstream import { Location } from '../../../common/types/entity.enums'; -======= -<<<<<<< Updated upstream -import { Location } from 'src/config/types/entity.enums'; -======= - -import { Location } from '../../../common/types/entity.enums'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes export class CreateEventDto { @IsString() diff --git a/src/module/event/entity/event.entity.ts b/src/module/event/entity/event.entity.ts index 602330a..742d14c 100644 --- a/src/module/event/entity/event.entity.ts +++ b/src/module/event/entity/event.entity.ts @@ -6,19 +6,10 @@ import { PrimaryGeneratedColumn, } from 'typeorm'; -<<<<<<< Updated upstream -======= -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes import { Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { User } from '../../user/entity/user.entity'; -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes ->>>>>>> Stashed changes @Entity() export class Event { @PrimaryGeneratedColumn() diff --git a/src/module/event/event.controller.ts b/src/module/event/event.controller.ts index a61b557..2f2d3b6 100644 --- a/src/module/event/event.controller.ts +++ b/src/module/event/event.controller.ts @@ -18,14 +18,7 @@ import { CreateEventDto } from './dto/create-event.dto'; import { SearchEventDto } from './dto/search-event.dto'; import { UpdateEventDto } from './dto/update-event.dto'; import { EventService } from './event.service'; -<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; -======= -<<<<<<< Updated upstream -======= -import { UserFromRequest } from '../../common/decorators/user.decorator'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; import { User } from '../user/entity/user.entity'; import { OrganizerGuard } from '../user/guards/organizer.guard'; @@ -45,29 +38,16 @@ export class EventController { return this.eventService.createEvent(user, createEventDto); } -<<<<<<< Updated upstream -======= @Get('search') search(@Query() params: SearchEventDto) { return this.eventService.getEvents(params); } -<<<<<<< Updated upstream ->>>>>>> Stashed changes @Get(':id') read(@Param('id', ParseIntPipe) id: number) { return this.eventService.getOneById(id); } -<<<<<<< Updated upstream - @Get() - search(@Query() params: SearchEventDto) { - return this.eventService.getEvents(params); - } -======= -======= ->>>>>>> Stashed changes ->>>>>>> Stashed changes @Patch('update/:id') @UseGuards(AccessTokenGuard, EventOwnerGuard) update(@Param('id') id: number, @Body() updateEventDto: UpdateEventDto) { diff --git a/src/module/user/dto/create-user.dto.ts b/src/module/user/dto/create-user.dto.ts index 9bedf92..ed31eda 100644 --- a/src/module/user/dto/create-user.dto.ts +++ b/src/module/user/dto/create-user.dto.ts @@ -6,17 +6,8 @@ import { IsString, IsStrongPassword, } from 'class-validator'; -<<<<<<< Updated upstream import { Location, UserRole } from '../../../common/types/entity.enums'; -======= -<<<<<<< Updated upstream -import { Location, UserRole } from 'src/config/types/entity.enums'; -======= - -import { Location, UserRole } from '../../../common/types/entity.enums'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes export class CreateUserDto { @IsEmail() diff --git a/src/module/user/entity/user.entity.ts b/src/module/user/entity/user.entity.ts index a388688..cdbf802 100644 --- a/src/module/user/entity/user.entity.ts +++ b/src/module/user/entity/user.entity.ts @@ -1,19 +1,10 @@ import { Exclude } from 'class-transformer'; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; -<<<<<<< Updated upstream -======= -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes import { UserRole, Location } from '../../../common/types/entity.enums'; import { Booking } from '../../booking/entity/booking.entity'; import { Event } from '../../event/entity/event.entity'; -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes ->>>>>>> Stashed changes @Entity() export class User { @PrimaryGeneratedColumn() diff --git a/src/module/user/guards/organizer.guard.ts b/src/module/user/guards/organizer.guard.ts index 61c9211..5900ae4 100644 --- a/src/module/user/guards/organizer.guard.ts +++ b/src/module/user/guards/organizer.guard.ts @@ -1,16 +1,6 @@ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; -<<<<<<< Updated upstream import { UserRole } from '../../../common/types/entity.enums'; - -======= -<<<<<<< Updated upstream -// todo: как будто по логике этот guard должен быть в другом модуле -======= -import { UserRole } from '../../../common/types/entity.enums'; - ->>>>>>> Stashed changes ->>>>>>> Stashed changes @Injectable() export class OrganizerGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { diff --git a/src/module/user/guards/owner.guard.ts b/src/module/user/guards/owner.guard.ts index ee2c1c9..c9dc77e 100644 --- a/src/module/user/guards/owner.guard.ts +++ b/src/module/user/guards/owner.guard.ts @@ -1,18 +1,8 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; -<<<<<<< Updated upstream import { parseId } from '../../../common/utils/parse-id'; import { EventRepository } from '../../event/event.repository'; -======= -<<<<<<< Updated upstream -// todo: как будто по логике этот guard должен быть в другом модуле -======= -import { parseId } from '../../../common/utils/parse-id'; -import { EventRepository } from '../../event/event.repository'; - ->>>>>>> Stashed changes ->>>>>>> Stashed changes @Injectable() export class EventOwnerGuard implements CanActivate { constructor(private eventRepository: EventRepository) {} diff --git a/src/module/user/user.controller.ts b/src/module/user/user.controller.ts index b6e561b..b9726a7 100644 --- a/src/module/user/user.controller.ts +++ b/src/module/user/user.controller.ts @@ -4,14 +4,7 @@ import { ApiTags } from '@nestjs/swagger'; import { UpdateUserDto } from './dto/update-user.dto'; import { User } from './entity/user.entity'; import { UserService } from './user.service'; -<<<<<<< Updated upstream import { UserFromRequest } from '../../common/decorators/user.decorator'; -======= -<<<<<<< Updated upstream -======= -import { UserFromRequest } from '../../common/decorators/user.decorator'; ->>>>>>> Stashed changes ->>>>>>> Stashed changes import { AccessTokenGuard } from '../auth/guards/access-token.guard'; @ApiTags('User')