import { Transform, Type } from 'class-transformer'; import { ArrayMaxSize, IsArray, IsInt, IsOptional, IsString, Max, Min, } from 'class-validator'; function toStringArray(value: unknown): string[] | undefined { if (value == null || value === '') return undefined; if (Array.isArray(value)) { return value.map((item) => String(item)).filter(Boolean); } if (typeof value === 'string') { const trimmed = value.trim(); if (!trimmed) return undefined; try { const parsed = JSON.parse(trimmed) as unknown; if (Array.isArray(parsed)) { return parsed.map((item) => String(item)).filter(Boolean); } } catch { // comma-separated fallback } return trimmed .split(',') .map((item) => item.trim()) .filter(Boolean); } return undefined; } export class ListGalleryDto { @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(1) @Max(100) pageSize?: number; } export class AddGalleryDto { /** Attach existing business media (also accepted as multipart field). */ @IsOptional() @Transform(({ value }) => toStringArray(value)) @IsArray() @ArrayMaxSize(50) @IsString({ each: true }) mediaIds?: string[]; }