import type { MailContent, MailData } from "@sendgrid/helpers/classes/mail.js" import type { ResponseError } from "@sendgrid/mail" import { Context, Data, type Effect, type NonEmptyReadonlyArray, type Redacted } from "effect-app" import type { Email } from "effect-app/Schema" export class SendMailError extends Data.TaggedError("SendMailError")<{ readonly raw: Error | ResponseError }> {} export class Emailer extends Context.Opaque Effect.Effect }>()("effect-app/Emailer") {} export type EmailData = Email | { name?: string email: Email } export interface SendgridConfig { defaultReplyTo?: EmailData subjectPrefix: string realMail: boolean defaultFrom: EmailData apiKey: Redacted.Redacted /** * Email address used for fake/test recipients. Use `{i}` as a placeholder for an auto-incrementing index to ensure uniqueness. * * @example "test+{i}@example.com" */ fakeMailAddress: string } export type EmailTemplateMsg = MailData & { templateId: string } export type EmailRecipients = EmailData | NonEmptyReadonlyArray export type EmailMsgBase = & Omit & { to: EmailData | NonEmptyReadonlyArray cc?: EmailData | NonEmptyReadonlyArray bcc?: EmailData | NonEmptyReadonlyArray from: EmailData /** * should multiple `to` addresess be considered multiple emails? * defaults to `true`, not to leak email addresses */ isMultiple?: boolean } export type EmailContent = { text: string } | { html: string } | { templateId: string } | { content: NonEmptyReadonlyArray } export type EmailMsg = & EmailMsgBase & EmailContent export type EmailMsgOptionalFrom = Omit & Partial> & EmailContent