import { ContentStatus } from '@prisma/client'; import { Transform, Type } from 'class-transformer'; import { IsArray, IsBoolean, IsEnum, IsInt, IsNumber, IsOptional, IsString, Matches, Min, MinLength, MaxLength, } from 'class-validator'; export class ListProductsDto { @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(1) pageSize?: number; @IsOptional() @IsEnum(ContentStatus) status?: ContentStatus; @IsOptional() @IsString() name?: string; } export class ListPublicProductsDto { @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number; @IsOptional() @Type(() => Number) @IsInt() @Min(1) pageSize?: number; @IsOptional() @IsString() name?: string; @IsOptional() @IsString() categoryId?: string; @IsOptional() @IsString() brandId?: string; @IsOptional() @IsString() tag?: string; @IsOptional() @Transform(({ value }) => value === 'true' || value === true) @IsBoolean() inStore?: boolean; } export class CreateProductDto { @IsString() @MinLength(2) title!: string; @IsOptional() @IsString() nameFa?: string; @IsOptional() @IsString() summary?: string; @IsOptional() @IsString() descriptionHtml?: string; @IsOptional() @IsString() categoryId?: string; @IsOptional() @IsString() brandId?: string; @IsOptional() @IsEnum(ContentStatus) status?: ContentStatus; @IsOptional() @IsString() featuredMediaId?: string; /** Optional PDF catalog file (media id; application/pdf, max 2MB). */ @IsOptional() @IsString() catalogMediaId?: string; @IsOptional() @IsArray() @IsString({ each: true }) galleryMediaIds?: string[]; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsString() @MaxLength(70) seoMetaTitle?: string | null; @IsOptional() @IsString() @MaxLength(160) seoMetaDescription?: string | null; @IsOptional() @IsString() @Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/) slug?: string; } export class UpdateProductDto { @IsOptional() @IsString() @MinLength(2) title?: string; @IsOptional() @IsString() nameFa?: string | null; @IsOptional() @IsString() summary?: string | null; @IsOptional() @IsString() descriptionHtml?: string | null; @IsOptional() @IsString() categoryId?: string | null; @IsOptional() @IsString() brandId?: string | null; @IsOptional() @IsEnum(ContentStatus) status?: ContentStatus; @IsOptional() @IsString() featuredMediaId?: string | null; /** Optional PDF catalog file (media id). Pass null to clear. */ @IsOptional() @IsString() catalogMediaId?: string | null; @IsOptional() @IsArray() @IsString({ each: true }) galleryMediaIds?: string[]; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsString() @MaxLength(70) seoMetaTitle?: string | null; @IsOptional() @IsString() @MaxLength(160) seoMetaDescription?: string | null; @IsOptional() @IsString() @Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/) slug?: string; }