import { ApiPropertyOptional, PickType } from "@nestjs/swagger"; import { Transform, Type } from "class-transformer"; import { IsBoolean, IsDateString, IsEnum, IsNumber, IsObject, IsOptional, IsString, Min } from "class-validator"; import { PaginationDto } from "../../../common/DTO/pagination.dto"; import { CommonMessage, EmailMessage } from "../../../common/enums/message.enum"; export class MessageListQueryDto extends PaginationDto { @ApiPropertyOptional({ description: "Sort order", enum: ["asc", "desc"], example: "desc" }) @IsOptional() @IsEnum(["asc", "desc"], { message: EmailMessage.ORDER_MUST_BE_VALID }) order?: "asc" | "desc"; } export class SearchMessagesQueryDto extends PaginationDto { @IsOptional() @IsString({ message: EmailMessage.SEARCH_QUERY_PARAMETER_MUST_BE_STRING }) @ApiPropertyOptional({ description: "Additional query string" }) q?: string; @IsOptional() @IsString({ message: EmailMessage.MAILBOX_ID_MUST_BE_STRING }) @ApiPropertyOptional({ description: "ID of the Mailbox" }) mailbox?: string; @ApiPropertyOptional({ description: "Message ID values, only applies when used in combination with mailbox. Either comma separated numbers (1,2,3) or colon separated range (3:15), or a range from UID to end (3:*)", }) @IsOptional() @IsString({ message: EmailMessage.MESSAGE_IDS_MUST_BE_STRING }) id?: string; @IsOptional() @IsString({ message: EmailMessage.THREAD_ID_MUST_BE_STRING }) @ApiPropertyOptional({ description: "Thread ID" }) thread?: string; @IsOptional() @IsObject({ message: EmailMessage.OR_QUERY_MUST_BE_OBJECT }) @ApiPropertyOptional({ description: "At least one of the included terms must match" }) or?: object; @IsOptional() @IsString({ message: CommonMessage.SEARCH_QUERY_STRING }) @ApiPropertyOptional({ description: "Search string" }) search?: string; @IsOptional() @IsDateString({}, { message: EmailMessage.DATE_START_MUST_BE_DATE_STRING }) @ApiPropertyOptional({ description: "Datestring for the earliest message storing time", example: "2024-01-01T12:00:00.000Z" }) datestart?: string; @IsOptional() @IsDateString({}, { message: EmailMessage.DATE_END_MUST_BE_DATE_STRING }) @ApiPropertyOptional({ description: "Datestring for the latest message storing time", example: "2024-01-01T12:00:00.000Z" }) dateend?: string; @IsOptional() @IsString() @ApiPropertyOptional({ description: "Partial match for the From: header line", example: "john@example.com" }) from?: string; @IsOptional() @IsString({ message: EmailMessage.TO_ADDRESS_MUST_BE_STRING }) @ApiPropertyOptional({ description: "Partial match for the To: and Cc: header lines", example: "john@example.com" }) to?: string; @IsOptional() @IsString({ message: EmailMessage.SUBJECT_MUST_BE_STRING }) @ApiPropertyOptional({ description: "Partial match for the Subject: header line", example: "important meeting" }) subject?: string; @IsOptional() @Type(() => Number) @IsNumber({}, { message: EmailMessage.MIN_SIZE_MUST_BE_NUMBER }) @Min(0, { message: EmailMessage.MIN_SIZE_MUST_BE_NON_NEGATIVE }) @ApiPropertyOptional({ description: "Minimal message size in bytes", example: 100 }) minSize?: number; @IsOptional() @Type(() => Number) @IsNumber({}, { message: EmailMessage.MAX_SIZE_MUST_BE_NUMBER }) @Min(0, { message: EmailMessage.MAX_SIZE_MUST_BE_NON_NEGATIVE }) @ApiPropertyOptional({ description: "Maximal message size in bytes", example: 1000000 }) maxSize?: number; @IsOptional() @IsBoolean({ message: EmailMessage.ATTACHMENTS_FILTER_MUST_BE_BOOLEAN }) @ApiPropertyOptional({ description: "If true, then matches only messages with attachments", example: true }) attachments?: boolean; @IsOptional() @Transform(({ value }) => value === "true") @IsBoolean({ message: EmailMessage.FLAGGED_FILTER_MUST_BE_BOOLEAN }) @ApiPropertyOptional({ description: "If true, then matches only messages with \\Flagged flags", example: true }) flagged?: boolean; @IsOptional() @Transform(({ value }) => value === "true") @IsBoolean({ message: EmailMessage.UNSEEN_FILTER_MUST_BE_BOOLEAN }) @ApiPropertyOptional({ description: "If true, then matches only messages without \\Seen flags", example: true }) unseen?: boolean; @ApiPropertyOptional({ description: "Comma separated list of header keys to include in the response", example: "List-ID, MIME-Version", }) @IsOptional() @IsString({ message: EmailMessage.INCLUDE_HEADERS_MUST_BE_STRING }) includeHeaders?: string; @ApiPropertyOptional({ description: "If true, then matches messages not in Junk or Trash", example: true }) @IsOptional() @IsBoolean({ message: EmailMessage.SEARCHABLE_FILTER_MUST_BE_BOOLEAN }) searchable?: boolean; @ApiPropertyOptional({ description: "If true, then includes threadMessageCount in the response. Counters come with some overhead", default: false }) @IsOptional() @IsBoolean({ message: EmailMessage.THREAD_COUNTERS_MUST_BE_BOOLEAN }) threadCounters?: boolean; @ApiPropertyOptional({ description: "Ordering of the records by insert date. If no order is supplied, results are sorted by their mongoDB ObjectId", enum: ["asc", "desc"], }) @IsOptional() @IsString({ message: EmailMessage.ORDER_MUST_BE_VALID }) order?: "asc" | "desc"; @ApiPropertyOptional({ description: "Cursor value for next page, retrieved from nextCursor response value", example: "eyIkb2lkIjoiNWRmMWZkMmQ3NzkyNTExOGI2MDdjNjg0In0", }) @IsOptional() @IsString({ message: EmailMessage.NEXT_CURSOR_MUST_BE_STRING }) next?: string; @ApiPropertyOptional({ description: "Cursor value for previous page, retrieved from previousCursor response value", example: "TMIjjIy23ZGM2kk0lIixygWomEknQDWdmzMNIkbNeO0NNjR", }) @IsOptional() @IsString({ message: EmailMessage.PREVIOUS_CURSOR_MUST_BE_STRING }) previous?: string; } export class EmailSuggestionsQueryDto extends PickType(PaginationDto, ["limit"]) { @IsOptional() @IsString({ message: CommonMessage.SEARCH_QUERY_STRING }) @ApiPropertyOptional({ description: "Email address search query for autocomplete", example: "john@" }) query?: string; }