|
| 1 | +import { |
| 2 | + PipeTransform, |
| 3 | + Injectable, |
| 4 | + ArgumentMetadata, |
| 5 | + BadRequestException, |
| 6 | +} from '@nestjs/common'; |
| 7 | +import { Types } from 'mongoose'; |
| 8 | +import { IQuery } from '../interfaces/query.interface'; |
| 9 | + |
| 10 | +const SYSTEM_KEYS = [ |
| 11 | + 'sortField', |
| 12 | + 'sortType', |
| 13 | + 'selectFields', |
| 14 | + 'page', |
| 15 | + 'limit', |
| 16 | + 'field', |
| 17 | + 'search', |
| 18 | +]; |
| 19 | + |
| 20 | +@Injectable() |
| 21 | +export class QueryPipe implements PipeTransform { |
| 22 | + transform(value: any, metadata: ArgumentMetadata): IQuery { |
| 23 | + const query: any = {}; |
| 24 | + const sort: any = {}; |
| 25 | + const select: any = {}; |
| 26 | + let page = 1; |
| 27 | + let limit = 10; |
| 28 | + |
| 29 | + // Парсим параметры для поиска |
| 30 | + if (value.search) { |
| 31 | + if (Array.isArray(value.field) && Array.isArray(value.search)) { |
| 32 | + value.field.forEach((field: string, index: number) => { |
| 33 | + query[field] = value.search[index]; |
| 34 | + }); |
| 35 | + } else if ( |
| 36 | + typeof value.field === 'string' && |
| 37 | + typeof value.search === 'string' |
| 38 | + ) { |
| 39 | + query[value.field] = value.search; |
| 40 | + } else { |
| 41 | + throw new BadRequestException('Invalid search parameters'); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + // Парсим параметры для поиска |
| 46 | + for (const [key, val] of Object.entries(value)) { |
| 47 | + if (SYSTEM_KEYS.includes(key)) { |
| 48 | + query[key] = val; |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + // Парсим параметры для сортировки |
| 53 | + if (value.sortField) { |
| 54 | + const fields = Array.isArray(value.sortField) |
| 55 | + ? value.sortField |
| 56 | + : [value.sortField]; |
| 57 | + const types = Array.isArray(value.sortType) |
| 58 | + ? value.sortType |
| 59 | + : [value.sortType]; |
| 60 | + |
| 61 | + fields.forEach((field: string, index: number) => { |
| 62 | + sort[field] = types[index] === '1' ? 1 : -1; |
| 63 | + }); |
| 64 | + } |
| 65 | + |
| 66 | + // Парсим параметры для выбора полей |
| 67 | + if (value.selectFields) { |
| 68 | + const fields = Array.isArray(value.selectFields) |
| 69 | + ? value.selectFields.join(' ') |
| 70 | + : value.selectFields; |
| 71 | + fields.split(' ').forEach((field: string) => { |
| 72 | + select[field] = 1; |
| 73 | + }); |
| 74 | + } |
| 75 | + |
| 76 | + // Парсим параметры для пагинации |
| 77 | + if (value.page) { |
| 78 | + page = parseInt(value.page, 10); |
| 79 | + } |
| 80 | + if (value.limit) { |
| 81 | + limit = parseInt(value.limit, 10); |
| 82 | + } |
| 83 | + |
| 84 | + return { query, sort, select, limit, skip: (page - 1) * limit }; |
| 85 | + } |
| 86 | +} |
0 commit comments