This commit is contained in:
giancarlo
2024-03-24 02:23:22 +08:00
parent 648d77b430
commit bce3479368
589 changed files with 37067 additions and 9596 deletions

View File

@@ -0,0 +1,59 @@
import 'server-only';
import { z } from 'zod';
import { Mailer } from '../mailer';
import { MailerSchema } from '../mailer-schema';
type Config = z.infer<typeof MailerSchema>;
/**
* A class representing a mailer using Nodemailer library.
* @implements {Mailer}
*/
export class Nodemailer implements Mailer {
async sendEmail(config: Config) {
const transporter = await getSMTPTransporter();
return transporter.sendMail(config);
}
}
/**
* @description SMTP Transporter for production use. Add your favorite email
* API details (Mailgun, Sendgrid, etc.) to the appConfig.
*/
async function getSMTPTransporter() {
const { createTransport } = await import('nodemailer');
return createTransport(getSMTPConfiguration());
}
function getSMTPConfiguration() {
const user = process.env.EMAIL_USER;
const pass = process.env.EMAIL_PASSWORD;
const host = process.env.EMAIL_HOST;
const port = Number(process.env.EMAIL_PORT);
const secure = process.env.EMAIL_TLS !== 'false';
// validate that we have all the required appConfig
if (!user || !pass || !host || !port) {
throw new Error(
`Missing email configuration. Please add the following environment variables:
EMAIL_USER
EMAIL_PASSWORD
EMAIL_HOST
EMAIL_PORT
`,
);
}
return {
host,
port,
secure,
auth: {
user,
pass,
},
};
}

View File

@@ -0,0 +1,19 @@
import { Nodemailer } from './impl/nodemailer';
/**
* @description A mailer interface that can be implemented by any mailer.
* We export a single mailer implementation using Nodemailer. You can add more mailers or replace the existing one.
* @example
* ```ts
* import { Mailer } from '@kit/mailers';
*
* const mailer = new Mailer();
*
* mailer.sendEmail({
* from: '',
* to: '',
* subject: 'Hello',
* text: 'Hello, World!'
* });
*/
export const Mailer = Nodemailer;

View File

@@ -0,0 +1,18 @@
import { z } from 'zod';
export const MailerSchema = z
.object({
to: z.string().email(),
from: z.string().email(),
subject: z.string(),
})
.and(
z.union([
z.object({
text: z.string(),
}),
z.object({
html: z.string(),
}),
]),
);

View File

@@ -0,0 +1,7 @@
import { z } from 'zod';
import { MailerSchema } from './mailer-schema';
export abstract class Mailer<Res = unknown> {
abstract sendEmail(data: z.infer<typeof MailerSchema>): Promise<Res>;
}