@454creative/easy-email
Version:
A framework-agnostic email service library for Node.js with observability and monitoring
128 lines • 5.39 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProviderFactory = void 0;
const nodemailer_1 = __importDefault(require("nodemailer"));
const mail_1 = __importDefault(require("@sendgrid/mail"));
const client_ses_1 = require("@aws-sdk/client-ses");
const credential_providers_1 = require("@aws-sdk/credential-providers");
const email_options_interface_1 = require("../interfaces/email-options.interface");
const errors_1 = require("../errors");
/**
* Factory for creating email provider configurations
*/
class ProviderFactory {
/**
* Create SMTP transporter
*/
static createSmtpTransporter(config) {
return nodemailer_1.default.createTransport(config);
}
/**
* Configure SendGrid
*/
static configureSendGrid(config) {
mail_1.default.setApiKey(config.apiKey);
}
/**
* Create AWS SES client
*/
static createSesClient(config) {
const clientConfig = {
region: config.region,
apiVersion: config.apiVersion || '2010-12-01',
maxAttempts: config.maxRetries || 3,
};
// Configure AWS credentials
if (config.credentials) {
clientConfig.credentials = config.credentials;
}
else if (config.accessKeyId && config.secretAccessKey) {
clientConfig.credentials = {
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
sessionToken: config.sessionToken,
};
}
else {
// Use AWS credential providers chain (environment variables, IAM roles, etc.)
clientConfig.credentials = (0, credential_providers_1.fromEnv)();
}
// Configure AWS SES endpoint if provided
if (config.endpoint) {
clientConfig.endpoint = config.endpoint;
}
// Configure AWS SES HTTP options
if (config.httpOptions) {
clientConfig.requestHandler = {
httpOptions: config.httpOptions,
};
}
return new client_ses_1.SESClient(clientConfig);
}
/**
* Create provider configuration from legacy SMTP config
*/
static createProviderConfig(config) {
if (!('type' in config)) {
return {
type: email_options_interface_1.EmailProviderType.SMTP,
config: config,
};
}
return config;
}
/**
* Validate provider configuration
*/
static validateProviderConfig(config) {
if (!config.type) {
throw new errors_1.ConfigurationError('Provider type is required');
}
if (!config.config) {
throw new errors_1.ConfigurationError('Provider configuration is required');
}
switch (config.type) {
case email_options_interface_1.EmailProviderType.SMTP:
const smtpConfig = config.config;
if (!smtpConfig.host || !smtpConfig.port) {
throw new errors_1.ConfigurationError('SMTP host and port are required');
}
break;
case email_options_interface_1.EmailProviderType.SENDGRID:
const sendGridConfig = config.config;
if (!sendGridConfig.apiKey) {
throw new errors_1.ConfigurationError('SendGrid API key is required');
}
// Check for basic API key format (SendGrid keys typically start with "SG.")
if (typeof sendGridConfig.apiKey === 'string' && !sendGridConfig.apiKey.startsWith('SG.')) {
throw new errors_1.ConfigurationError('SendGrid API key appears to be invalid. Valid SendGrid API keys typically start with "SG."');
}
// Check for minimum length (SendGrid keys are typically 69 characters)
if (typeof sendGridConfig.apiKey === 'string' && sendGridConfig.apiKey.length < 20) {
throw new errors_1.ConfigurationError('SendGrid API key appears to be too short. Please verify your API key.');
}
break;
case email_options_interface_1.EmailProviderType.SES:
// AWS SES Configuration Validation
const sesConfig = config.config;
if (!sesConfig.region) {
throw new errors_1.ConfigurationError('AWS SES region is required');
}
// Validate that at least one credential method is provided
const hasCredentials = sesConfig.credentials ||
(sesConfig.accessKeyId && sesConfig.secretAccessKey) ||
process.env.AWS_ACCESS_KEY_ID;
if (!hasCredentials) {
throw new errors_1.ConfigurationError('AWS SES credentials are required (accessKeyId/secretAccessKey, credentials object, or AWS environment variables)');
}
break;
default:
throw new errors_1.ConfigurationError(`Unsupported provider type: ${config.type}`);
}
}
}
exports.ProviderFactory = ProviderFactory;
//# sourceMappingURL=provider-factory.js.map