Skip to content

Commit 10545e9

Browse files
committed
feat: add fields for all entities
1 parent 0fd1671 commit 10545e9

File tree

2 files changed

+173
-62
lines changed

2 files changed

+173
-62
lines changed

src/common/decorators/paginated.decorator.ts

+157-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,164 @@ import { ToolsQueryDto } from '../dto/query/tools.query.dto';
55
import { QueryPipe } from '../pipes/query.pipe';
66
import { ApiDotNotationQuery } from './api-dot-notation-query.decorator';
77

8-
export const Paginated = (entityDto: any, entity?: any) => {
8+
export interface EntityFields {
9+
allowFieldsFindAll: string[];
10+
idKeys: string[];
11+
regexSearchKeys: string[];
12+
dateSearchKeys: string[];
13+
numberSearchKeys: string[];
14+
blacklistFields?: string[];
15+
}
16+
17+
export interface Entities {
18+
movie: EntityFields;
19+
person: EntityFields;
20+
review: EntityFields;
21+
season: EntityFields;
22+
image: EntityFields;
23+
}
24+
25+
const entitiesField: Entities = {
26+
movie: {
27+
allowFieldsFindAll: [
28+
'id',
29+
'externalId',
30+
'name',
31+
'logo',
32+
'color',
33+
'shortDescription',
34+
'horizontalPoster',
35+
'alternativeName',
36+
'enName',
37+
'names',
38+
'type',
39+
'movieLength',
40+
'description',
41+
'year',
42+
'poster',
43+
'votes',
44+
'rating',
45+
'watchability',
46+
'releaseYears',
47+
],
48+
idKeys: ['id', 'externalId.imdb'],
49+
regexSearchKeys: [
50+
'name',
51+
'alternativeName',
52+
'enName',
53+
'names.name',
54+
'tagline',
55+
'slogan',
56+
'description',
57+
'persons.name',
58+
'persons.enName',
59+
'persons.description',
60+
],
61+
dateSearchKeys: ['premiere.world', 'premiere.russia', 'premiere.digital', 'premiere.bluray', 'premiere.dvd'],
62+
numberSearchKeys: [
63+
'id',
64+
'externalId.imdb',
65+
'externalId.tmdb',
66+
'typeNumber',
67+
'movieLength',
68+
'year',
69+
'rating.kp',
70+
'rating.imdb',
71+
'rating.tmdb',
72+
'votes.kp',
73+
'votes.imdb',
74+
'votes.tmdb',
75+
'ratingAgeLimits',
76+
'persons.id',
77+
'budget.value',
78+
'fees.world',
79+
'fees.usa',
80+
'fees.russia',
81+
'image.postersCount',
82+
'image.backdropsCount',
83+
'image.framesCount',
84+
'reviewInfo.count',
85+
'reviewInfo.positiveCount',
86+
'seasonsInfo.number',
87+
'seasonsInfo.episodesCount',
88+
'videos.trailers.size',
89+
'videos.teasers.size',
90+
],
91+
},
92+
person: {
93+
blacklistFields: [
94+
'-_id',
95+
'-profession._id',
96+
'-birthPlace._id',
97+
'-deathPlace._id',
98+
'-facts._id',
99+
'-movies._id',
100+
'-isParse',
101+
],
102+
allowFieldsFindAll: ['id', 'name', 'enName', 'photo', 'age', 'sex'],
103+
idKeys: ['id'],
104+
regexSearchKeys: [
105+
'name',
106+
'enName',
107+
'movies.name',
108+
'slogan',
109+
'description',
110+
'persons.name',
111+
'persons.enName',
112+
'persons.description',
113+
],
114+
dateSearchKeys: ['birthday', 'death'],
115+
numberSearchKeys: [
116+
'id',
117+
'movies.id',
118+
'movies.rating',
119+
'age',
120+
'countAwards',
121+
'growth',
122+
'spouses.id',
123+
'spouses.children',
124+
'spouses.name',
125+
],
126+
},
127+
review: {
128+
blacklistFields: ['-_id', '-episodes._id'],
129+
allowFieldsFindAll: ['movieId', 'id', 'title', 'type', 'review', 'author', 'date'],
130+
idKeys: ['id'],
131+
regexSearchKeys: [],
132+
dateSearchKeys: ['date'],
133+
numberSearchKeys: ['movieId', 'id'],
134+
},
135+
season: {
136+
blacklistFields: ['-_id', '-episodes._id'],
137+
allowFieldsFindAll: [
138+
'movieId',
139+
'number',
140+
'episodesCount',
141+
'episodes.number',
142+
'episodes.name',
143+
'episodes.enName',
144+
'episodes.date',
145+
'episodes.description',
146+
],
147+
idKeys: ['id'],
148+
regexSearchKeys: [],
149+
dateSearchKeys: ['episodes.date'],
150+
numberSearchKeys: ['movieId', 'number', 'episodesCount', 'episodes.number'],
151+
},
152+
image: {
153+
blacklistFields: ['-_id'],
154+
allowFieldsFindAll: ['url', 'previewUrl', 'width', 'language', 'height', 'type', 'movieId'],
155+
idKeys: ['id'],
156+
regexSearchKeys: [],
157+
dateSearchKeys: [],
158+
numberSearchKeys: ['movieId', 'height', 'width'],
159+
},
160+
};
161+
162+
export const Paginated = (entityDto: any, entity: any, findForAllProperties?: boolean) => {
9163
return applyDecorators(
10-
UsePipes(new QueryPipe()),
11-
entity
164+
UsePipes(new QueryPipe(entitiesField[entity.name.toLowerCase()])),
165+
findForAllProperties
12166
? ApiDotNotationQuery(ToolsQueryDto, PaginatedQueryDto, entity)
13167
: ApiDotNotationQuery(ToolsQueryDto, PaginatedQueryDto),
14168
ApiResponse({ type: entityDto, isArray: true }),

src/common/pipes/query.pipe.ts

+16-59
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,14 @@
11
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
2-
import { Value } from 'src/movie/schemas/movie.schema';
2+
import { EntityFields } from '../decorators/paginated.decorator';
33
import { IQuery } from '../interfaces/query.interface';
44
import { normalizeDate } from '../utils/query/parse-date.util';
55

66
const SYSTEM_KEYS = ['sortField', 'sortType', 'selectFields', 'page', 'limit', 'field', 'search'];
77

8-
const FIELDS = {
9-
idKeys: ['id', 'externalId.imdb'],
10-
regexSearchKeys: [
11-
'name',
12-
'alternativeName',
13-
'enName',
14-
'names.name',
15-
'tagline',
16-
'slogan',
17-
'description',
18-
'persons.name',
19-
'persons.enName',
20-
'persons.description',
21-
],
22-
dateSearchKeys: ['premiere.world', 'premiere.russia', 'premiere.digital', 'premiere.bluray', 'premiere.dvd'],
23-
numberSearchKeys: [
24-
'id',
25-
'externalId.imdb',
26-
'externalId.tmdb',
27-
'typeNumber',
28-
'movieLength',
29-
'year',
30-
'rating.kp',
31-
'rating.imdb',
32-
'rating.tmdb',
33-
'votes.kp',
34-
'votes.imdb',
35-
'votes.tmdb',
36-
'ratingAgeLimits',
37-
'persons.id',
38-
'budget.value',
39-
'fees.world',
40-
'fees.usa',
41-
'fees.russia',
42-
'image.postersCount',
43-
'image.backdropsCount',
44-
'image.framesCount',
45-
'reviewInfo.count',
46-
'reviewInfo.positiveCount',
47-
'seasonsInfo.number',
48-
'seasonsInfo.episodesCount',
49-
'videos.trailers.size',
50-
'videos.teasers.size',
51-
],
52-
};
53-
548
@Injectable()
559
export class QueryPipe implements PipeTransform {
10+
constructor(private readonly FIELDS: EntityFields) {}
11+
5612
transform(value: any, metadata: ArgumentMetadata): IQuery {
5713
const filter: any = {};
5814
const sort: any = {};
@@ -81,9 +37,9 @@ export class QueryPipe implements PipeTransform {
8137

8238
const transformFieldValue = (field: string, value: string): any => {
8339
const isNullValue = value === '!null';
84-
const isNumberField = FIELDS.numberSearchKeys.includes(field);
85-
const isDateField = FIELDS.dateSearchKeys.includes(field);
86-
const isRegexField = FIELDS.regexSearchKeys.includes(field);
40+
const isNumberField = this.FIELDS.numberSearchKeys.includes(field);
41+
const isDateField = this.FIELDS.dateSearchKeys.includes(field);
42+
const isRegexField = this.FIELDS.regexSearchKeys.includes(field);
8743

8844
if (isNullValue) {
8945
return { $ne: null };
@@ -93,14 +49,16 @@ export class QueryPipe implements PipeTransform {
9349
const [minValue, maxValue] = value.split('-');
9450
const result = maxValue
9551
? {
96-
$gte: isDateField ? normalizeDate(minValue) : minValue,
97-
$lte: isDateField ? normalizeDate(maxValue) : maxValue,
52+
$gte: isDateField ? normalizeDate(minValue) : parseInt(minValue),
53+
$lte: isDateField ? normalizeDate(maxValue) : parseInt(maxValue),
9854
}
9955
: isDateField
10056
? normalizeDate(minValue)
101-
: minValue;
57+
: parseInt(minValue);
10258

10359
return result;
60+
} else if (isNumberField) {
61+
return parseInt(value);
10462
}
10563

10664
if (isRegexField) {
@@ -150,12 +108,11 @@ export class QueryPipe implements PipeTransform {
150108
}
151109

152110
// Парсим параметры для выбора полей
153-
if (value.selectFields) {
154-
const fields = Array.isArray(value.selectFields) ? value.selectFields.join(' ') : value.selectFields;
155-
fields.split(' ').forEach((field: string) => {
156-
select[field] = 1;
157-
});
158-
}
111+
let selectFields = Array.isArray(value.selectFields) ? value.selectFields : value?.selectFields?.split(' ');
112+
if (!selectFields) selectFields = this.FIELDS.allowFieldsFindAll;
113+
selectFields.forEach((field: string) => {
114+
select[field] = 1;
115+
});
159116

160117
// Парсим параметры для пагинации
161118
if (value.page) page = parseInt(value.page, 10);

0 commit comments

Comments
 (0)