backend v4 half
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
export { UserMapper } from './user.mapper';
|
||||
export { CompanyMapper } from './company.mapper';
|
||||
export { CardsMapper } from './cards.mapper';
|
||||
export { ChatMapper } from './chat.mapper';
|
||||
export { ContactMapper } from './contact.mapper';
|
||||
export { CompanyContactMapper } from './companyContact.mapper';
|
||||
|
||||
export * from '../dto/user.dto';
|
||||
export * from '../dto/company.dto';
|
||||
export * from '../dto/cards.dto';
|
||||
export * from '../dto/chat.dto';
|
||||
export * from '../dto/contact.dto';
|
||||
export * from '../dto/companyContact.dto';
|
||||
|
||||
export * from '../entities/user.entity';
|
||||
export * from '../entities/company.entity';
|
||||
export * from '../entities/cards.entity';
|
||||
export * from '../entities/chat.entity';
|
||||
export * from '../entities/contact.entity';
|
||||
export * from '../entities/companyContact.entity';
|
||||
export interface MapperConfig {
|
||||
includeRelations?: boolean;
|
||||
includePrivateFields?: boolean;
|
||||
userId?: number;
|
||||
userCompanyId?: number;
|
||||
}
|
||||
|
||||
export interface IMapper<TEntity, TCreateDto, TUpdateDto, TResponseDto> {
|
||||
toEntity(createDto: TCreateDto): TEntity;
|
||||
toResponseDto(entity: TEntity): TResponseDto;
|
||||
updateEntity(entity: TEntity, updateDto: TUpdateDto): TEntity;
|
||||
toResponseDtoArray(entities: TEntity[]): TResponseDto[];
|
||||
canMapToResponse(entity: TEntity): boolean;
|
||||
}
|
||||
|
||||
export class MapperUtils {
|
||||
|
||||
static applyPagination<T>(items: T[], page?: number, limit?: number): T[] {
|
||||
if (!page || !limit) return items;
|
||||
const startIndex = (page - 1) * limit;
|
||||
return items.slice(startIndex, startIndex + limit);
|
||||
}
|
||||
|
||||
static applySorting<T>(items: T[], sortBy?: string, sortOrder?: 'ASC' | 'DESC'): T[] {
|
||||
if (!sortBy) return items;
|
||||
|
||||
return items.sort((a, b) => {
|
||||
const aValue = (a as any)[sortBy];
|
||||
const bValue = (b as any)[sortBy];
|
||||
|
||||
if (aValue < bValue) return sortOrder === 'DESC' ? 1 : -1;
|
||||
if (aValue > bValue) return sortOrder === 'DESC' ? -1 : 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
static applyTextFilter<T>(items: T[], searchText: string, searchFields: string[]): T[] {
|
||||
if (!searchText) return items;
|
||||
|
||||
const lowerSearchText = searchText.toLowerCase();
|
||||
return items.filter(item => {
|
||||
return searchFields.some(field => {
|
||||
const fieldValue = (item as any)[field];
|
||||
return fieldValue && fieldValue.toString().toLowerCase().includes(lowerSearchText);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static applyDateRangeFilter<T>(items: T[], dateField: string, fromDate?: Date, toDate?: Date): T[] {
|
||||
return items.filter(item => {
|
||||
const itemDate = (item as any)[dateField];
|
||||
if (!itemDate) return false;
|
||||
|
||||
if (fromDate && itemDate < fromDate) return false;
|
||||
if (toDate && itemDate > toDate) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static enumToDisplayString(enumValue: any): string {
|
||||
return enumValue.toString().replace(/_/g, ' ').toLowerCase()
|
||||
.replace(/\b\w/g, (char: string) => char.toUpperCase());
|
||||
}
|
||||
|
||||
static isValidEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
static sanitizeSearchString(searchText: string): string {
|
||||
return searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
static generateMessagePreview(message: string, length: number = 100): string {
|
||||
if (message.length <= length) return message;
|
||||
return message.substring(0, length).trim() + '...';
|
||||
}
|
||||
|
||||
static getTimeAgo(date: Date): string {
|
||||
const now = new Date();
|
||||
const diff = now.getTime() - date.getTime();
|
||||
const minutes = Math.floor(diff / (1000 * 60));
|
||||
const hours = Math.floor(diff / (1000 * 60 * 60));
|
||||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (minutes < 60) return `${minutes} minutes ago`;
|
||||
if (hours < 24) return `${hours} hours ago`;
|
||||
if (days < 30) return `${days} days ago`;
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
|
||||
static deepClone<T>(obj: T): T {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
static hasRequiredProperties<T>(obj: any, requiredProps: (keyof T)[]): boolean {
|
||||
return requiredProps.every(prop => obj.hasOwnProperty(prop) && obj[prop] !== undefined);
|
||||
}
|
||||
|
||||
static removeUndefinedProperties<T>(obj: T): T {
|
||||
const cleaned = { ...obj } as any;
|
||||
Object.keys(cleaned).forEach(key => {
|
||||
if (cleaned[key] === undefined) {
|
||||
delete cleaned[key];
|
||||
}
|
||||
});
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
static groupBy<T, K extends keyof T>(array: T[], property: K): Map<T[K], T[]> {
|
||||
const map = new Map<T[K], T[]>();
|
||||
array.forEach(item => {
|
||||
const key = item[property];
|
||||
if (!map.has(key)) {
|
||||
map.set(key, []);
|
||||
}
|
||||
map.get(key)!.push(item);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
static getUniqueValues<T>(array: T[]): T[] {
|
||||
return [...new Set(array)];
|
||||
}
|
||||
|
||||
static calculateStats(numbers: number[]): { min: number; max: number; avg: number; sum: number } {
|
||||
if (numbers.length === 0) return { min: 0, max: 0, avg: 0, sum: 0 };
|
||||
|
||||
const sum = numbers.reduce((acc, num) => acc + num, 0);
|
||||
const avg = sum / numbers.length;
|
||||
const min = Math.min(...numbers);
|
||||
const max = Math.max(...numbers);
|
||||
|
||||
return { min, max, avg, sum };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user