diff --git a/README.md b/README.md index c997880..370765c 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,3 @@ -

- Nest Logo -

+# Schedule Parser Next -[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 -[circleci-url]: https://circleci.com/gh/nestjs/nest - -

A progressive Node.js framework for building efficient and scalable server-side applications.

-

-NPM Version -Package License -NPM Downloads -CircleCI -Coverage -Discord -Backers on Open Collective -Sponsors on Open Collective - Donate us - Support us - Follow us on Twitter -

- - -## Description - -[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. - -## Project setup - -```bash -$ npm install -``` - -## Compile and run the project - -```bash -# development -$ npm run start - -# watch mode -$ npm run start:dev - -# production mode -$ npm run start:prod -``` - -## Run tests - -```bash -# unit tests -$ npm run test - -# e2e tests -$ npm run test:e2e - -# test coverage -$ npm run test:cov -``` - -## Resources - -Check out a few resources that may come in handy when working with NestJS: - -- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework. -- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy). -- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/). -- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com). -- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com). -- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs). -- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com). - -## Support - -Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). - -## Stay in touch - -- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec) -- Website - [https://nestjs.com](https://nestjs.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) - -## License - -Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). +Based on [Nest](https://github.com/nestjs/nest) framework. \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e821b2c..82f793a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -14,12 +14,12 @@ datasource db { } model user { - id String @id @map("_id") @db.ObjectId + id String @id @map("_id") @db.ObjectId // - username String @unique + username String @unique // - salt String - password String + salt String + password String // - access_token String @unique + accessToken String @unique } diff --git a/src/auth/auth.decorator.ts b/src/auth/auth.decorator.ts index 2faf362..a265ad2 100644 --- a/src/auth/auth.decorator.ts +++ b/src/auth/auth.decorator.ts @@ -1,6 +1,8 @@ import { createParamDecorator, ExecutionContext } from "@nestjs/common"; import { AuthGuard } from "./auth.guard"; +// TODO: Найти применение этой функции +// noinspection JSUnusedGlobalSymbols export const UserId = createParamDecorator((_, context: ExecutionContext) => { return AuthGuard.extractTokenFromRequest( context.switchToHttp().getRequest(), diff --git a/src/auth/auth.guard.ts b/src/auth/auth.guard.ts index 8b4e8f6..00b57cb 100644 --- a/src/auth/auth.guard.ts +++ b/src/auth/auth.guard.ts @@ -29,7 +29,7 @@ export class AuthGuard implements CanActivate { try { if ( !(await this.jwtService.verifyAsync(token)) || - !(await this.usersService.has({ access_token: token })) + !(await this.usersService.contains({ accessToken: token })) ) { // noinspection ExceptionCaughtLocallyJS throw new Error(); diff --git a/src/auth/auth.pipe.ts b/src/auth/auth.pipe.ts index d739b54..840a13b 100644 --- a/src/auth/auth.pipe.ts +++ b/src/auth/auth.pipe.ts @@ -1,5 +1,4 @@ import { - ArgumentMetadata, Injectable, PipeTransform, UnauthorizedException, @@ -16,12 +15,12 @@ export class UserFromTokenPipe implements PipeTransform { ) {} async transform(token: string): Promise { - const jwt_user: { id: string } = await this.jwtService.decode(token); + const jwtUser: { id: string } = await this.jwtService.decode(token); - if (!jwt_user) + if (!jwtUser) throw new UnauthorizedException("Передан некорректный токен!"); - const user = await this.usersService.findUnique({ id: jwt_user.id }); + const user = await this.usersService.findUnique({ id: jwtUser.id }); if (!user) throw new UnauthorizedException("Передан некорректный токен!"); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 60853b6..6cd65dd 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -26,7 +26,7 @@ export class AuthService { ) {} async signUp(signUpDto: SignUpDto): Promise { - if (await this.usersService.has({ username: signUpDto.username })) + if (await this.usersService.contains({ username: signUpDto.username })) throw new ConflictException( "Пользователь с таким именем уже существует!", ); @@ -39,7 +39,7 @@ export class AuthService { username: signUpDto.username, salt: salt, password: await hash(signUpDto.password, salt), - access_token: await this.jwtService.signAsync({ + accessToken: await this.jwtService.signAsync({ id: id, }), }; @@ -47,7 +47,7 @@ export class AuthService { return this.usersService.create(input).then((user) => { return { id: user.id, - access_token: user.access_token, + accessToken: user.accessToken, }; }); } @@ -66,21 +66,21 @@ export class AuthService { ); } - const access_token = await this.jwtService.signAsync({ id: user.id }); + const accessToken = await this.jwtService.signAsync({ id: user.id }); await this.usersService.update({ where: { id: user.id }, - data: { access_token: access_token }, + data: { accessToken: accessToken }, }); - return { id: user.id, access_token: access_token }; + return { id: user.id, accessToken: accessToken }; } async updateToken( updateTokenDto: UpdateTokenDto, ): Promise { if ( - !(await this.jwtService.verifyAsync(updateTokenDto.access_token, { + !(await this.jwtService.verifyAsync(updateTokenDto.accessToken, { ignoreExpiration: true, })) ) { @@ -89,24 +89,24 @@ export class AuthService { ); } - const jwt_user: { id: string } = await this.jwtService.decode( - updateTokenDto.access_token, + const jwtUser: { id: string } = await this.jwtService.decode( + updateTokenDto.accessToken, ); - const user = await this.usersService.findUnique({ id: jwt_user.id }); - if (!user || user.access_token !== updateTokenDto.access_token) { + const user = await this.usersService.findUnique({ id: jwtUser.id }); + if (!user || user.accessToken !== updateTokenDto.accessToken) { throw new NotFoundException( "Некорректный или недействительный токен!", ); } - const access_token = await this.jwtService.signAsync({ id: user.id }); + const accessToken = await this.jwtService.signAsync({ id: user.id }); await this.usersService.update({ where: { id: user.id }, - data: { access_token: access_token }, + data: { accessToken: accessToken }, }); - return { access_token: access_token }; + return { accessToken: accessToken }; } } diff --git a/src/dto/auth.dto.ts b/src/dto/auth.dto.ts index abf7149..af9a688 100644 --- a/src/dto/auth.dto.ts +++ b/src/dto/auth.dto.ts @@ -8,15 +8,12 @@ export class SignInDto extends PickType(UserDto, ["username"]) { password: string; } -export class SignInResultDto extends PickType(UserDto, [ - "id", - "access_token", -]) {} +export class SignInResultDto extends PickType(UserDto, ["id", "accessToken"]) {} export class SignUpDto extends SignInDto {} export class SignUpResultDto extends SignInResultDto {} -export class UpdateTokenDto extends PickType(UserDto, ["access_token"]) {} +export class UpdateTokenDto extends PickType(UserDto, ["accessToken"]) {} export class UpdateTokenResultDto extends UpdateTokenDto {} diff --git a/src/dto/user.dto.ts b/src/dto/user.dto.ts index 24cfaa9..343cef3 100644 --- a/src/dto/user.dto.ts +++ b/src/dto/user.dto.ts @@ -24,11 +24,13 @@ export class UserDto { password: string; @ApiProperty({ description: "Последний токен доступа" }) @IsJWT() - access_token: string; + accessToken: string; } +// TODO: Доделать пользователей +// noinspection JSUnusedGlobalSymbols export class ClientUserDto extends OmitType(UserDto, [ "password", "salt", - "access_token", + "accessToken", ]) {} diff --git a/src/schedule/internal/schedule-parser/schedule-parser.ts b/src/schedule/internal/schedule-parser/schedule-parser.ts index ea9fcd6..1a474b2 100644 --- a/src/schedule/internal/schedule-parser/schedule-parser.ts +++ b/src/schedule/internal/schedule-parser/schedule-parser.ts @@ -239,10 +239,6 @@ export class ScheduleParser { }); } - public getLastResult(): ScheduleParseResult | null { - return this.lastResult; - } - private getAffectedDays( cachedGroup: GroupDto | null, group: GroupDto, diff --git a/src/schedule/internal/xls-downloader/basic-xls-downloader.ts b/src/schedule/internal/xls-downloader/basic-xls-downloader.ts index 3e5384b..9b90f6d 100644 --- a/src/schedule/internal/xls-downloader/basic-xls-downloader.ts +++ b/src/schedule/internal/xls-downloader/basic-xls-downloader.ts @@ -28,11 +28,11 @@ ${response.statusText}`); downloadLink: string; updateDate: string; } { - const schedule_block = dom.window.document.getElementById("cont-i"); - if (schedule_block === null) + const scheduleBlock = dom.window.document.getElementById("cont-i"); + if (scheduleBlock === null) throw new Error("Не удалось найти блок расписаний!"); - const schedules = schedule_block.getElementsByTagName("div"); + const schedules = scheduleBlock.getElementsByTagName("div"); if (schedules === null || schedules.length === 0) throw new Error("Не удалось найти строку с расписанием!"); @@ -40,11 +40,11 @@ ${response.statusText}`); const link = poltavskaya.getElementsByTagName("a")[0]!; const spans = poltavskaya.getElementsByTagName("span"); - const update_date = spans[3].textContent!.trimStart(); + const updateDate = spans[3].textContent!.trimStart(); return { downloadLink: link.href, - updateDate: update_date, + updateDate: updateDate, }; } @@ -64,9 +64,11 @@ ${response.statusText}`); return this.getCachedXLS(); const dom = await this.getDOM(); - const parse_data = this.parseData(dom); + const parseData = this.parseData(dom); - const response = await axios.get(parse_data.downloadLink, { + // FIX-ME: Что такое Annotator и почему он выдаёт пустое предупреждение? + // noinspection Annotator + const response = await axios.get(parseData.downloadLink, { responseType: "arraybuffer", }); if (response.status !== 200) { @@ -77,7 +79,7 @@ ${response.statusText}`); const result: XlsDownloaderResult = { fileData: response.data.buffer, - updateDate: parse_data.updateDate, + updateDate: parseData.updateDate, etag: response.headers["etag"], new: this.cacheMode === XlsDownloaderCacheMode.NONE diff --git a/src/schedule/schedule.service.ts b/src/schedule/schedule.service.ts index 2899551..066f126 100644 --- a/src/schedule/schedule.service.ts +++ b/src/schedule/schedule.service.ts @@ -1,8 +1,5 @@ import { Injectable } from "@nestjs/common"; -import { - ScheduleParser, - ScheduleParseResult, -} from "./internal/schedule-parser/schedule-parser"; +import { ScheduleParser } from "./internal/schedule-parser/schedule-parser"; import { BasicXlsDownloader } from "./internal/xls-downloader/basic-xls-downloader"; import { XlsDownloaderCacheMode } from "./internal/xls-downloader/xls-downloader.base"; import { ScheduleDto } from "../dto/schedule.dto"; diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 463e911..61c834d 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -10,10 +10,6 @@ export class UsersService { return this.prismaService.user.findUnique({ where: where }); } - async findOne(where: Prisma.userWhereInput): Promise { - return this.prismaService.user.findFirst({ where: where }); - } - async update(params: { where: Prisma.userWhereUniqueInput; data: Prisma.userUpdateInput; @@ -25,7 +21,7 @@ export class UsersService { return this.prismaService.user.create({ data }); } - async has(where: Prisma.userWhereUniqueInput): Promise { + async contains(where: Prisma.userWhereUniqueInput): Promise { return (await this.prismaService.user.count({ where })) > 0; } } diff --git a/src/utility/parse-pipe/object-id.pipe.ts b/src/utility/parse-pipe/object-id.pipe.ts index 10c5fe9..a639dd4 100644 --- a/src/utility/parse-pipe/object-id.pipe.ts +++ b/src/utility/parse-pipe/object-id.pipe.ts @@ -11,10 +11,10 @@ export class ObjectIdPipe implements PipeTransform { ) throw new BadRequestException("Invalid ObjectId"); - const return_string = value.toLowerCase(); - if (!/^[0-9a-f]{24}$/.test(return_string)) + const returnString = value.toLowerCase(); + if (!/^[0-9a-f]{24}$/.test(returnString)) throw new BadRequestException("Invalid ObjectId"); - return return_string; + return returnString; } } diff --git a/src/utility/prisma/convert.helper.ts b/src/utility/prisma/convert.helper.ts deleted file mode 100644 index a592d48..0000000 --- a/src/utility/prisma/convert.helper.ts +++ /dev/null @@ -1,9 +0,0 @@ -type Nullable = { - [P in keyof T]: T[P] | null | Array; -}; - -export function convertToPrismaInput(dto: Nullable): T { - return Object.entries(dto) - .filter((x) => x[1] !== undefined) - .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) as T; -} diff --git a/src/utility/string.util.ts b/src/utility/string.util.ts index 0f7570d..77beb45 100644 --- a/src/utility/string.util.ts +++ b/src/utility/string.util.ts @@ -1,31 +1,3 @@ export function trimAll(str: string): string { return str.replace(/\s\s+/g, " ").trim(); } - -const customLessonIdxToTextPresets = [ - "Первое", - "Второе", - "Третье", - "Четвёртое", - "Пятое", - "Шестое", - "Седьмое", -]; - -export function customLessonIdxToText(num: number): string { - return customLessonIdxToTextPresets[num]; -} - -const defaultLessonIdxToTextPresets = [ - "Первая", - "Вторая", - "Третья", - "Четвёртая", - "Пятая", - "Шестая", - "Седьмая", -]; - -export function defaultLessonIdxToText(num: number): string { - return defaultLessonIdxToTextPresets[num]; -} diff --git a/src/utility/validation/class-validator.interceptor.ts b/src/utility/validation/class-validator.interceptor.ts index 04d3f20..a54a8a2 100644 --- a/src/utility/validation/class-validator.interceptor.ts +++ b/src/utility/validation/class-validator.interceptor.ts @@ -19,7 +19,7 @@ export class ClassValidatorInterceptor implements NestInterceptor { intercept( context: ExecutionContext, - next: CallHandler, + next: CallHandler, ): Observable | Promise> { return next.handle().pipe( map(async (returnValue: any) => { @@ -71,6 +71,7 @@ export class ClassValidatorInterceptor implements NestInterceptor { } } +// noinspection FunctionNamingConventionJS export function ResultDto(type: any) { return (target: NonNullable, propertyKey: string | symbol) => { Reflect.defineMetadata("design:result-dto", type, target, propertyKey);