Skip to content
File

Blob: src/worker/serializers/email.ts

typescript67 lines
1import { EmailDetail, NewEmailNotification } from "@/shared/contracts";
2import { emails } from "@/worker/db/schema";
3 
4type EmailSummarySource = Pick<
5 typeof emails.$inferSelect,
6 | "id"
7 | "recipientAddress"
8 | "fromAddress"
9 | "fromName"
10 | "subject"
11 | "receivedAt"
12 | "isRead"
13 | "hasAttachments"
14 | "sizeBytes"
15>;
16 
17interface EmailAttachmentLike {
18 id: string;
19 filename: string | null;
20 contentType: string | null;
21 sizeBytes: number | null;
22}
23 
24interface EmailDetailSource extends EmailSummarySource {
25 attachments: EmailAttachmentLike[];
26}
27 
28export function toEmailSummary(email: EmailSummarySource) {
29 return {
30 id: email.id,
31 recipientAddress: email.recipientAddress,
32 fromAddress: email.fromAddress,
33 fromName: email.fromName,
34 subject: email.subject ?? "(no subject)",
35 receivedAt: email.receivedAt.toISOString(),
36 isRead: email.isRead,
37 hasAttachments: email.hasAttachments,
38 sizeBytes: email.sizeBytes ?? 0,
39 };
40}
41 
42export function toEmailDetail(
43 email: EmailDetailSource,
44 body: { text: string | null; html: string | null },
45 isRead: boolean,
46) {
47 return EmailDetail.create({
48 ...toEmailSummary({ ...email, isRead }),
49 text: body.text,
50 html: body.html,
51 attachments: email.attachments.map((attachment) => ({
52 id: attachment.id,
53 filename: attachment.filename,
54 contentType: attachment.contentType,
55 sizeBytes: attachment.sizeBytes ?? 0,
56 })),
57 });
58}
59 
60export function toNewEmailNotification(email: EmailSummarySource) {
61 return NewEmailNotification.create({
62 email: {
63 ...toEmailSummary(email),
64 },
65 });
66}