mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-19 03:41:23 +02:00
- Backend (NestJS): Complete API with accounts, folders, emails, labels, compose, attachments, sync providers (IMAP, Gmail, Outlook), AI features (summarize, smart replies, categorization), and OAuth support - Web (SvelteKit): Full email client UI with Svelte 5 runes, sidebar navigation, email list/detail views, compose modal, and theme support - Mobile (Expo): React Native app with drawer navigation, email list/detail, compose screen, account management, and theme provider - Landing (Astro): Marketing page with features, pricing, FAQ sections using shared-landing-ui components - Storage: Added mail bucket and createMailStorage to shared-storage package - Branding: Added MailLogo component Note: Run `pnpm install` to install new dependencies (mailparser) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
161 lines
2.6 KiB
TypeScript
161 lines
2.6 KiB
TypeScript
import {
|
|
IsString,
|
|
IsOptional,
|
|
IsUUID,
|
|
IsArray,
|
|
IsDateString,
|
|
ValidateNested,
|
|
IsEmail,
|
|
IsIn,
|
|
} from 'class-validator';
|
|
import { Type, Transform } from 'class-transformer';
|
|
|
|
export class EmailAddressDto {
|
|
@IsEmail()
|
|
email: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
name?: string;
|
|
}
|
|
|
|
export class CreateDraftDto {
|
|
@IsUUID()
|
|
accountId: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
subject?: string;
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
toAddresses?: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
ccAddresses?: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
bccAddresses?: EmailAddressDto[];
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyHtml?: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyPlain?: string;
|
|
|
|
@IsUUID()
|
|
@IsOptional()
|
|
replyToEmailId?: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
@IsIn(['reply', 'reply-all', 'forward'])
|
|
replyType?: string;
|
|
|
|
@IsDateString()
|
|
@IsOptional()
|
|
scheduledAt?: string;
|
|
}
|
|
|
|
export class UpdateDraftDto {
|
|
@IsString()
|
|
@IsOptional()
|
|
subject?: string;
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
toAddresses?: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
ccAddresses?: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
bccAddresses?: EmailAddressDto[];
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyHtml?: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyPlain?: string;
|
|
|
|
@IsDateString()
|
|
@IsOptional()
|
|
scheduledAt?: string;
|
|
}
|
|
|
|
export class SendEmailDto {
|
|
@IsUUID()
|
|
accountId: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
subject?: string;
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
toAddresses: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
ccAddresses?: EmailAddressDto[];
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => EmailAddressDto)
|
|
@IsOptional()
|
|
bccAddresses?: EmailAddressDto[];
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyHtml?: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
bodyPlain?: string;
|
|
|
|
@IsUUID()
|
|
@IsOptional()
|
|
replyToEmailId?: string;
|
|
|
|
@IsString()
|
|
@IsOptional()
|
|
@IsIn(['reply', 'reply-all', 'forward'])
|
|
replyType?: string;
|
|
}
|
|
|
|
export class DraftQueryDto {
|
|
@IsUUID()
|
|
@IsOptional()
|
|
accountId?: string;
|
|
|
|
@IsOptional()
|
|
@Transform(({ value }) => parseInt(value, 10))
|
|
limit?: number;
|
|
|
|
@IsOptional()
|
|
@Transform(({ value }) => parseInt(value, 10))
|
|
offset?: number;
|
|
}
|