import type { MailContent, MailData } from "@sendgrid/helpers/classes/mail.js" import type { ResponseError } from "@sendgrid/mail" import type { NonEmptyReadonlyArray } from "effect-app/Array" import * as Context from "effect-app/Context" import type * as Effect from "effect-app/Effect" import type { Email } from "effect-app/Schema" import * as Data from "effect/Data" import type * as Redacted from "effect/Redacted" 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