Skip to content

Commit eef389d

Browse files
committed
feat: add field transpilation to mongo object
1 parent b8d8e9d commit eef389d

File tree

2 files changed

+101
-3
lines changed

2 files changed

+101
-3
lines changed

src/common/pipes/query.pipe.ts

+92-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
2+
import { Value } from 'src/movie/schemas/movie.schema';
23
import { IQuery } from '../interfaces/query.interface';
4+
import { normalizeDate } from '../utils/query/parse-date.util';
35

46
const SYSTEM_KEYS = [
57
'sortField',
@@ -11,6 +13,58 @@ const SYSTEM_KEYS = [
1113
'search',
1214
];
1315

16+
const FIELDS = {
17+
idKeys: ['id', 'externalId.imdb'],
18+
regexSearchKeys: [
19+
'name',
20+
'alternativeName',
21+
'enName',
22+
'names.name',
23+
'tagline',
24+
'slogan',
25+
'description',
26+
'persons.name',
27+
'persons.enName',
28+
'persons.description',
29+
],
30+
dateSearchKeys: [
31+
'premiere.world',
32+
'premiere.russia',
33+
'premiere.digital',
34+
'premiere.bluray',
35+
'premiere.dvd',
36+
],
37+
numberSearchKeys: [
38+
'id',
39+
'externalId.imdb',
40+
'externalId.tmdb',
41+
'typeNumber',
42+
'movieLength',
43+
'year',
44+
'rating.kp',
45+
'rating.imdb',
46+
'rating.tmdb',
47+
'votes.kp',
48+
'votes.imdb',
49+
'votes.tmdb',
50+
'ratingAgeLimits',
51+
'persons.id',
52+
'budget.value',
53+
'fees.world',
54+
'fees.usa',
55+
'fees.russia',
56+
'image.postersCount',
57+
'image.backdropsCount',
58+
'image.framesCount',
59+
'reviewInfo.count',
60+
'reviewInfo.positiveCount',
61+
'seasonsInfo.number',
62+
'seasonsInfo.episodesCount',
63+
'videos.trailers.size',
64+
'videos.teasers.size',
65+
],
66+
};
67+
1468
@Injectable()
1569
export class QueryPipe implements PipeTransform {
1670
transform(value: any, metadata: ArgumentMetadata): IQuery {
@@ -31,6 +85,37 @@ export class QueryPipe implements PipeTransform {
3185
}
3286
};
3387

88+
const transformFieldValue = (field: string, value: string): any => {
89+
const isNullValue = value === '!null';
90+
const isNumberField = FIELDS.numberSearchKeys.includes(field);
91+
const isDateField = FIELDS.dateSearchKeys.includes(field);
92+
const isRegexField = FIELDS.regexSearchKeys.includes(field);
93+
94+
if (isNullValue) {
95+
return { $ne: null };
96+
}
97+
98+
if ((isNumberField || isDateField) && value.includes('-')) {
99+
const [minValue, maxValue] = value.split('-');
100+
const result = maxValue
101+
? {
102+
$gte: isDateField ? normalizeDate(minValue) : minValue,
103+
$lte: isDateField ? normalizeDate(maxValue) : maxValue,
104+
}
105+
: isDateField
106+
? normalizeDate(minValue)
107+
: minValue;
108+
109+
return result;
110+
}
111+
112+
if (isRegexField) {
113+
return { $regex: new RegExp(`.*${value}.*`, 'i') };
114+
}
115+
116+
return value;
117+
};
118+
34119
// Парсим параметры поиска в старом формате
35120
if (value.field && value.search) {
36121
if (Array.isArray(value.field) && Array.isArray(value.search)) {
@@ -50,10 +135,14 @@ export class QueryPipe implements PipeTransform {
50135
// Форматируем данные, под валидный для mongo запрос
51136
for (const [key, keyValue] of Object.entries(filter)) {
52137
if (!SYSTEM_KEYS.includes(key)) {
53-
if (Array.isArray(keyValue)) {
54-
filter[key] = { $in: keyValue };
138+
const isArray = Array.isArray(keyValue);
139+
140+
if (isArray) {
141+
filter[key] = {
142+
$in: keyValue.map((val) => transformFieldValue(key, val)),
143+
};
55144
} else {
56-
filter[key] = keyValue;
145+
filter[key] = transformFieldValue(key, keyValue as string);
57146
}
58147
}
59148
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { DateTime } from 'luxon';
2+
3+
export const normalizeDate = (dateString: string) => {
4+
const dateTime = DateTime.fromFormat(dateString, 'dd.MM.yyyy HH.mm.ss');
5+
if (!dateTime.isValid) {
6+
throw new Error('Invalid date format');
7+
}
8+
return dateTime.toJSDate();
9+
};

0 commit comments

Comments
 (0)