Something went wrong. Try again.
Comail's webmail client, based on Bulwark. Public source mirror
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364// Projection helpers - convert host-internal types into the read-only views// that plugins consume. Keeping this in one place ensures every slot/hook// hands plugins the same shape declared in plugin-types.ts.
import type { Email } from '@/lib/jmap/types';import type { EmailReadView } from '@/lib/plugin-types';import { generateEmailSource } from '@/lib/email-source';
// Resolve a message's plain-text body from its JMAP body parts. Plugins that// translate or scan content need the real body, not just the short `preview`// snippet. Prefers text/plain parts; falls back to stripped HTML, then preview.function plainTextFromEmail(email: Email): string { const values = email.bodyValues || {}; const collect = (parts?: { partId: string }[]) => (parts || []) .map((p) => values[p.partId]?.value) .filter((v): v is string => typeof v === 'string' && v.length > 0) .join('\n') .trim();
const text = collect(email.textBody); if (text) return text;
const html = collect(email.htmlBody); if (html) { return html .replace(/<(script|style)[\s\S]*?<\/\1>/gi, ' ') .replace(/<[^>]+>/g, ' ') .replace(/ /gi, ' ') .replace(/&/gi, '&') .replace(/</gi, '<') .replace(/>/gi, '>') .replace(/'|'/gi, "'") .replace(/"/gi, '"') .replace(/[ \t]{2,}/g, ' ') .replace(/\n{3,}/g, '\n\n') .trim(); }
return (email.preview || '').trim();}
export function emailToReadView(email: Email): EmailReadView { return { id: email.id, threadId: email.threadId, mailboxIds: Object.keys(email.mailboxIds || {}).filter(k => email.mailboxIds[k]), from: (email.from || []).map(a => ({ name: a.name || '', email: a.email })), to: (email.to || []).map(a => ({ name: a.name || '', email: a.email })), cc: (email.cc || []).map(a => ({ name: a.name || '', email: a.email })), subject: email.subject || '', receivedAt: email.receivedAt, isRead: !!email.keywords?.['$seen'], isFlagged: !!email.keywords?.['$flagged'], hasAttachment: email.hasAttachment, preview: email.preview || '', text: plainTextFromEmail(email), headers: email.headers, source: generateEmailSource(email), keywords: Object.keys(email.keywords || {}).filter(k => email.keywords[k]), auth: email.authenticationResults, };}