Expose Organization/LocalBusiness and Product/BlogPosting jsonLd, optional seoMeta fields on content/categories, and continue mass SMS after per-recipient failures. Co-authored-by: Cursor <cursoragent@cursor.com>
194 lines
2.9 KiB
TypeScript
194 lines
2.9 KiB
TypeScript
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;
|
|
|
|
@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;
|
|
|
|
@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;
|
|
}
|