import * as aws from "@aws-sdk/client-ses"; import { defaultProvider } from "@aws-sdk/credential-provider-node"; import { renderAsync } from "@react-email/render"; import { createTransport, Transporter } from "nodemailer"; import type Mail from "nodemailer/lib/mailer"; import previewEmail from "preview-email"; import React from "react"; import * as templates from "./templates"; import { EmailContext } from "./templates/_components/email-context"; type Templates = typeof templates; type TemplateName = keyof typeof templates; type TemplateProps = Omit< React.ComponentProps>, "ctx" >; type TemplateComponent = Templates[T]; type SendEmailOptions = { to: string; subject: string; props: TemplateProps; attachments?: Mail.Options["attachments"]; }; type EmailProviderConfig = | { name: "ses"; // config defined through env vars } | { name: "smtp"; // config defined through env vars }; export type SupportedEmailProviders = EmailProviderConfig["name"]; type EmailClientConfig = { /** * Whether to open previews of each email in the browser */ openPreviews?: boolean; /** * Whether to send emails to the test server */ useTestServer: boolean; /** * Email provider config */ provider: EmailProviderConfig; /** * Mail config */ mail: { from: { name: string; address: string; }; }; /** * Context to pass to each email */ context: EmailContext; }; export class EmailClient { private config: EmailClientConfig; private cachedTransport?: Transporter; constructor(config: EmailClientConfig) { this.config = config; } async sendTemplate( templateName: T, options: SendEmailOptions, ) { const Template = templates[templateName] as TemplateComponent; const component = (