mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
Чистка.
Удалены неиспользуемые функции. Были исправлены несоблюдения стиля кода.
This commit is contained in:
86
README.md
86
README.md
@@ -1,85 +1,3 @@
|
|||||||
<p align="center">
|
# Schedule Parser Next
|
||||||
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
|
Based on [Nest](https://github.com/nestjs/nest) framework.
|
||||||
[circleci-url]: https://circleci.com/gh/nestjs/nest
|
|
||||||
|
|
||||||
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
|
||||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
|
||||||
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
|
|
||||||
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
|
|
||||||
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
|
|
||||||
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
|
||||||
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
|
||||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
|
||||||
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
|
|
||||||
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
|
||||||
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
|
|
||||||
</p>
|
|
||||||
<!--[](https://opencollective.com/nest#backer)
|
|
||||||
[](https://opencollective.com/nest#sponsor)-->
|
|
||||||
|
|
||||||
## 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).
|
|
||||||
@@ -14,12 +14,12 @@ datasource db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model user {
|
model user {
|
||||||
id String @id @map("_id") @db.ObjectId
|
id String @id @map("_id") @db.ObjectId
|
||||||
//
|
//
|
||||||
username String @unique
|
username String @unique
|
||||||
//
|
//
|
||||||
salt String
|
salt String
|
||||||
password String
|
password String
|
||||||
//
|
//
|
||||||
access_token String @unique
|
accessToken String @unique
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
|
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
|
||||||
import { AuthGuard } from "./auth.guard";
|
import { AuthGuard } from "./auth.guard";
|
||||||
|
|
||||||
|
// TODO: Найти применение этой функции
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
export const UserId = createParamDecorator((_, context: ExecutionContext) => {
|
export const UserId = createParamDecorator((_, context: ExecutionContext) => {
|
||||||
return AuthGuard.extractTokenFromRequest(
|
return AuthGuard.extractTokenFromRequest(
|
||||||
context.switchToHttp().getRequest(),
|
context.switchToHttp().getRequest(),
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class AuthGuard implements CanActivate {
|
|||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
!(await this.jwtService.verifyAsync(token)) ||
|
!(await this.jwtService.verifyAsync(token)) ||
|
||||||
!(await this.usersService.has({ access_token: token }))
|
!(await this.usersService.contains({ accessToken: token }))
|
||||||
) {
|
) {
|
||||||
// noinspection ExceptionCaughtLocallyJS
|
// noinspection ExceptionCaughtLocallyJS
|
||||||
throw new Error();
|
throw new Error();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ArgumentMetadata,
|
|
||||||
Injectable,
|
Injectable,
|
||||||
PipeTransform,
|
PipeTransform,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
@@ -16,12 +15,12 @@ export class UserFromTokenPipe implements PipeTransform {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async transform(token: string): Promise<user | null> {
|
async transform(token: string): Promise<user | null> {
|
||||||
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("Передан некорректный токен!");
|
throw new UnauthorizedException("Передан некорректный токен!");
|
||||||
|
|
||||||
const user = await this.usersService.findUnique({ id: jwt_user.id });
|
const user = await this.usersService.findUnique({ id: jwtUser.id });
|
||||||
if (!user)
|
if (!user)
|
||||||
throw new UnauthorizedException("Передан некорректный токен!");
|
throw new UnauthorizedException("Передан некорректный токен!");
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class AuthService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async signUp(signUpDto: SignUpDto): Promise<SignUpResultDto> {
|
async signUp(signUpDto: SignUpDto): Promise<SignUpResultDto> {
|
||||||
if (await this.usersService.has({ username: signUpDto.username }))
|
if (await this.usersService.contains({ username: signUpDto.username }))
|
||||||
throw new ConflictException(
|
throw new ConflictException(
|
||||||
"Пользователь с таким именем уже существует!",
|
"Пользователь с таким именем уже существует!",
|
||||||
);
|
);
|
||||||
@@ -39,7 +39,7 @@ export class AuthService {
|
|||||||
username: signUpDto.username,
|
username: signUpDto.username,
|
||||||
salt: salt,
|
salt: salt,
|
||||||
password: await hash(signUpDto.password, salt),
|
password: await hash(signUpDto.password, salt),
|
||||||
access_token: await this.jwtService.signAsync({
|
accessToken: await this.jwtService.signAsync({
|
||||||
id: id,
|
id: id,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -47,7 +47,7 @@ export class AuthService {
|
|||||||
return this.usersService.create(input).then((user) => {
|
return this.usersService.create(input).then((user) => {
|
||||||
return {
|
return {
|
||||||
id: user.id,
|
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({
|
await this.usersService.update({
|
||||||
where: { id: user.id },
|
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(
|
async updateToken(
|
||||||
updateTokenDto: UpdateTokenDto,
|
updateTokenDto: UpdateTokenDto,
|
||||||
): Promise<UpdateTokenResultDto> {
|
): Promise<UpdateTokenResultDto> {
|
||||||
if (
|
if (
|
||||||
!(await this.jwtService.verifyAsync(updateTokenDto.access_token, {
|
!(await this.jwtService.verifyAsync(updateTokenDto.accessToken, {
|
||||||
ignoreExpiration: true,
|
ignoreExpiration: true,
|
||||||
}))
|
}))
|
||||||
) {
|
) {
|
||||||
@@ -89,24 +89,24 @@ export class AuthService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const jwt_user: { id: string } = await this.jwtService.decode(
|
const jwtUser: { id: string } = await this.jwtService.decode(
|
||||||
updateTokenDto.access_token,
|
updateTokenDto.accessToken,
|
||||||
);
|
);
|
||||||
|
|
||||||
const user = await this.usersService.findUnique({ id: jwt_user.id });
|
const user = await this.usersService.findUnique({ id: jwtUser.id });
|
||||||
if (!user || user.access_token !== updateTokenDto.access_token) {
|
if (!user || user.accessToken !== updateTokenDto.accessToken) {
|
||||||
throw new NotFoundException(
|
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({
|
await this.usersService.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: { access_token: access_token },
|
data: { accessToken: accessToken },
|
||||||
});
|
});
|
||||||
|
|
||||||
return { access_token: access_token };
|
return { accessToken: accessToken };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ export class SignInDto extends PickType(UserDto, ["username"]) {
|
|||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SignInResultDto extends PickType(UserDto, [
|
export class SignInResultDto extends PickType(UserDto, ["id", "accessToken"]) {}
|
||||||
"id",
|
|
||||||
"access_token",
|
|
||||||
]) {}
|
|
||||||
|
|
||||||
export class SignUpDto extends SignInDto {}
|
export class SignUpDto extends SignInDto {}
|
||||||
|
|
||||||
export class SignUpResultDto extends SignInResultDto {}
|
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 {}
|
export class UpdateTokenResultDto extends UpdateTokenDto {}
|
||||||
|
|||||||
@@ -24,11 +24,13 @@ export class UserDto {
|
|||||||
password: string;
|
password: string;
|
||||||
@ApiProperty({ description: "Последний токен доступа" })
|
@ApiProperty({ description: "Последний токен доступа" })
|
||||||
@IsJWT()
|
@IsJWT()
|
||||||
access_token: string;
|
accessToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Доделать пользователей
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
export class ClientUserDto extends OmitType(UserDto, [
|
export class ClientUserDto extends OmitType(UserDto, [
|
||||||
"password",
|
"password",
|
||||||
"salt",
|
"salt",
|
||||||
"access_token",
|
"accessToken",
|
||||||
]) {}
|
]) {}
|
||||||
|
|||||||
@@ -239,10 +239,6 @@ export class ScheduleParser {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLastResult(): ScheduleParseResult | null {
|
|
||||||
return this.lastResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getAffectedDays(
|
private getAffectedDays(
|
||||||
cachedGroup: GroupDto | null,
|
cachedGroup: GroupDto | null,
|
||||||
group: GroupDto,
|
group: GroupDto,
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ ${response.statusText}`);
|
|||||||
downloadLink: string;
|
downloadLink: string;
|
||||||
updateDate: string;
|
updateDate: string;
|
||||||
} {
|
} {
|
||||||
const schedule_block = dom.window.document.getElementById("cont-i");
|
const scheduleBlock = dom.window.document.getElementById("cont-i");
|
||||||
if (schedule_block === null)
|
if (scheduleBlock === null)
|
||||||
throw new Error("Не удалось найти блок расписаний!");
|
throw new Error("Не удалось найти блок расписаний!");
|
||||||
|
|
||||||
const schedules = schedule_block.getElementsByTagName("div");
|
const schedules = scheduleBlock.getElementsByTagName("div");
|
||||||
if (schedules === null || schedules.length === 0)
|
if (schedules === null || schedules.length === 0)
|
||||||
throw new Error("Не удалось найти строку с расписанием!");
|
throw new Error("Не удалось найти строку с расписанием!");
|
||||||
|
|
||||||
@@ -40,11 +40,11 @@ ${response.statusText}`);
|
|||||||
const link = poltavskaya.getElementsByTagName("a")[0]!;
|
const link = poltavskaya.getElementsByTagName("a")[0]!;
|
||||||
|
|
||||||
const spans = poltavskaya.getElementsByTagName("span");
|
const spans = poltavskaya.getElementsByTagName("span");
|
||||||
const update_date = spans[3].textContent!.trimStart();
|
const updateDate = spans[3].textContent!.trimStart();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
downloadLink: link.href,
|
downloadLink: link.href,
|
||||||
updateDate: update_date,
|
updateDate: updateDate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,9 +64,11 @@ ${response.statusText}`);
|
|||||||
return this.getCachedXLS();
|
return this.getCachedXLS();
|
||||||
|
|
||||||
const dom = await this.getDOM();
|
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",
|
responseType: "arraybuffer",
|
||||||
});
|
});
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
@@ -77,7 +79,7 @@ ${response.statusText}`);
|
|||||||
|
|
||||||
const result: XlsDownloaderResult = {
|
const result: XlsDownloaderResult = {
|
||||||
fileData: response.data.buffer,
|
fileData: response.data.buffer,
|
||||||
updateDate: parse_data.updateDate,
|
updateDate: parseData.updateDate,
|
||||||
etag: response.headers["etag"],
|
etag: response.headers["etag"],
|
||||||
new:
|
new:
|
||||||
this.cacheMode === XlsDownloaderCacheMode.NONE
|
this.cacheMode === XlsDownloaderCacheMode.NONE
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { Injectable } from "@nestjs/common";
|
import { Injectable } from "@nestjs/common";
|
||||||
import {
|
import { ScheduleParser } from "./internal/schedule-parser/schedule-parser";
|
||||||
ScheduleParser,
|
|
||||||
ScheduleParseResult,
|
|
||||||
} from "./internal/schedule-parser/schedule-parser";
|
|
||||||
import { BasicXlsDownloader } from "./internal/xls-downloader/basic-xls-downloader";
|
import { BasicXlsDownloader } from "./internal/xls-downloader/basic-xls-downloader";
|
||||||
import { XlsDownloaderCacheMode } from "./internal/xls-downloader/xls-downloader.base";
|
import { XlsDownloaderCacheMode } from "./internal/xls-downloader/xls-downloader.base";
|
||||||
import { ScheduleDto } from "../dto/schedule.dto";
|
import { ScheduleDto } from "../dto/schedule.dto";
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ export class UsersService {
|
|||||||
return this.prismaService.user.findUnique({ where: where });
|
return this.prismaService.user.findUnique({ where: where });
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(where: Prisma.userWhereInput): Promise<user | null> {
|
|
||||||
return this.prismaService.user.findFirst({ where: where });
|
|
||||||
}
|
|
||||||
|
|
||||||
async update(params: {
|
async update(params: {
|
||||||
where: Prisma.userWhereUniqueInput;
|
where: Prisma.userWhereUniqueInput;
|
||||||
data: Prisma.userUpdateInput;
|
data: Prisma.userUpdateInput;
|
||||||
@@ -25,7 +21,7 @@ export class UsersService {
|
|||||||
return this.prismaService.user.create({ data });
|
return this.prismaService.user.create({ data });
|
||||||
}
|
}
|
||||||
|
|
||||||
async has(where: Prisma.userWhereUniqueInput): Promise<boolean> {
|
async contains(where: Prisma.userWhereUniqueInput): Promise<boolean> {
|
||||||
return (await this.prismaService.user.count({ where })) > 0;
|
return (await this.prismaService.user.count({ where })) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ export class ObjectIdPipe implements PipeTransform<any, string> {
|
|||||||
)
|
)
|
||||||
throw new BadRequestException("Invalid ObjectId");
|
throw new BadRequestException("Invalid ObjectId");
|
||||||
|
|
||||||
const return_string = value.toLowerCase();
|
const returnString = value.toLowerCase();
|
||||||
if (!/^[0-9a-f]{24}$/.test(return_string))
|
if (!/^[0-9a-f]{24}$/.test(returnString))
|
||||||
throw new BadRequestException("Invalid ObjectId");
|
throw new BadRequestException("Invalid ObjectId");
|
||||||
|
|
||||||
return return_string;
|
return returnString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
type Nullable<T> = {
|
|
||||||
[P in keyof T]: T[P] | null | Array<any>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function convertToPrismaInput<T>(dto: Nullable<T>): T {
|
|
||||||
return Object.entries(dto)
|
|
||||||
.filter((x) => x[1] !== undefined)
|
|
||||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) as T;
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,3 @@
|
|||||||
export function trimAll(str: string): string {
|
export function trimAll(str: string): string {
|
||||||
return str.replace(/\s\s+/g, " ").trim();
|
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];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export class ClassValidatorInterceptor implements NestInterceptor {
|
|||||||
|
|
||||||
intercept(
|
intercept(
|
||||||
context: ExecutionContext,
|
context: ExecutionContext,
|
||||||
next: CallHandler<any>,
|
next: CallHandler,
|
||||||
): Observable<any> | Promise<Observable<any>> {
|
): Observable<any> | Promise<Observable<any>> {
|
||||||
return next.handle().pipe(
|
return next.handle().pipe(
|
||||||
map(async (returnValue: any) => {
|
map(async (returnValue: any) => {
|
||||||
@@ -71,6 +71,7 @@ export class ClassValidatorInterceptor implements NestInterceptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// noinspection FunctionNamingConventionJS
|
||||||
export function ResultDto(type: any) {
|
export function ResultDto(type: any) {
|
||||||
return (target: NonNullable<unknown>, propertyKey: string | symbol) => {
|
return (target: NonNullable<unknown>, propertyKey: string | symbol) => {
|
||||||
Reflect.defineMetadata("design:result-dto", type, target, propertyKey);
|
Reflect.defineMetadata("design:result-dto", type, target, propertyKey);
|
||||||
|
|||||||
Reference in New Issue
Block a user