waitlist-mailer
Version:
Modern, modular TypeScript library for managing waitlists with pluggable storage and mail providers. Supports MongoDB, SQL databases, and custom adapters with zero required dependencies for basic usage.
154 lines (152 loc) • 5.49 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// lib/adapters/mail/NodemailerProvider.ts
var NodemailerProvider_exports = {};
__export(NodemailerProvider_exports, {
NodemailerProvider: () => NodemailerProvider
});
module.exports = __toCommonJS(NodemailerProvider_exports);
var import_nodemailer = __toESM(require("nodemailer"));
var NodemailerProvider = class {
/**
* Create a new NodemailerProvider instance.
* @param config - SMTP configuration
* @throws {Error} If nodemailer is not installed
*/
constructor(config) {
this.config = config;
try {
if (!import_nodemailer.default || !import_nodemailer.default.createTransport) {
throw new Error("nodemailer is not properly initialized");
}
} catch (error) {
throw new Error(
"NodemailerProvider requires nodemailer to be installed. Install it with: npm install nodemailer"
);
}
this.fromEmail = config.from || config.user;
this.fromName = config.name || "Waitlist Manager";
this.transporter = import_nodemailer.default.createTransport({
host: config.host,
port: config.port,
secure: config.secure ?? config.port === 465,
auth: {
user: config.user,
pass: config.pass
}
});
}
/**
* Verify the transporter configuration.
* @returns true if configuration is valid
*/
async verify() {
try {
await this.transporter.verify();
return true;
} catch (error) {
console.error("Nodemailer verification failed:", error);
return false;
}
}
/**
* Send a confirmation email.
* @param email - Recipient email address
* @param context - Template context with variables
* @returns true if the email was sent successfully
*/
async sendConfirmation(email, context) {
try {
const subject = this.buildSubject(context);
const html = this.buildHtml(context);
const mailOptions = {
from: `"${this.fromName}" <${this.fromEmail}>`,
to: email,
subject,
html
};
await this.transporter.sendMail(mailOptions);
return true;
} catch (error) {
console.error(`Failed to send email to ${email}:`, error);
return false;
}
}
/**
* Build the email subject.
* Allows customization through context.
*/
buildSubject(context) {
return context.subject || `Welcome to ${context.companyName || "our platform"}`;
}
/**
* Build the HTML body.
* Provides a default template if customHtml is not provided.
*/
buildHtml(context) {
if (context.customHtml) {
return context.customHtml;
}
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background-color: #007bff; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; }
.footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome to ${context.companyName || "Our Platform"}</h1>
</div>
<div class="content">
<p>Hello,</p>
<p>Thank you for joining our waitlist! We're excited to have you on board.</p>
<p>You'll be among the first to know when we launch.</p>
${context.customUrl ? `<p><a href="${context.customUrl}" style="background-color: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px; display: inline-block;">Learn More</a></p>` : ""}
</div>
<div class="footer">
<p>© 2024 ${context.companyName || "Our Platform"}. All rights reserved.</p>
</div>
</div>
</body>
</html>
`;
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
NodemailerProvider
});