import { BadRequestException } from '@nestjs/common'; import { ErrorMessages } from '../constants/error-messages'; /** * Validate UUID format */ export function isValidUUID(id: string): boolean { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; return uuidRegex.test(id); } /** * Validate and throw if UUID is invalid */ export function validateUUID(id: string, fieldName: string = 'ID'): void { if (!isValidUUID(id)) { throw new BadRequestException(`Некорректный формат ${fieldName}`); } } /** * Validate email format */ export function isValidEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * Validate date string format (YYYY-MM-DD) */ export function isValidDateString(dateStr: string): boolean { const dateRegex = /^\d{4}-\d{2}-\d{2}$/; if (!dateRegex.test(dateStr)) return false; const date = new Date(dateStr); return !isNaN(date.getTime()); } /** * Validate pagination parameters */ export interface PaginationParams { page: number; limit: number; } export function validatePagination(page?: number, limit?: number): PaginationParams { const validPage = Math.max(1, page || 1); const validLimit = Math.min(100, Math.max(1, limit || 20)); return { page: validPage, limit: validLimit }; } /** * Calculate pagination offset */ export function calculateOffset(page: number, limit: number): number { return (page - 1) * limit; } /** * Create pagination response metadata */ export interface PaginationMeta { page: number; limit: number; total: number; totalPages: number; hasNext: boolean; hasPrev: boolean; } export function createPaginationMeta( page: number, limit: number, total: number, ): PaginationMeta { const totalPages = Math.ceil(total / limit); return { page, limit, total, totalPages, hasNext: page < totalPages, hasPrev: page > 1, }; } /** * Validate date range */ export function validateDateRange(startDate: string, endDate: string): void { if (!isValidDateString(startDate)) { throw new BadRequestException('Некорректная дата начала'); } if (!isValidDateString(endDate)) { throw new BadRequestException('Некорректная дата окончания'); } if (new Date(startDate) > new Date(endDate)) { throw new BadRequestException('Дата начала не может быть позже даты окончания'); } } /** * Validate transaction amount */ export function validateTransactionAmount(amount: number): void { if (typeof amount !== 'number' || isNaN(amount)) { throw new BadRequestException(ErrorMessages.INVALID_AMOUNT); } if (amount <= 0) { throw new BadRequestException(ErrorMessages.AMOUNT_MUST_BE_POSITIVE); } if (amount > 1_000_000_000) { throw new BadRequestException(ErrorMessages.AMOUNT_TOO_LARGE); } }