UNPKG

react-email-sender-adapters

Version:

A unified interface for sending react-email emails across multiple email services.

107 lines (106 loc) 4.15 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { renderAsync } from '@react-email/render'; import { defaultEmailOptions } from './index.js'; export function mailContactToType(contact) { if (typeof contact === 'string') { return { email: contact }; } return contact; } export function mailContactsToType(contacts) { return Array.isArray(contacts) ? contacts.map(mailContactToType) : [mailContactToType(contacts)]; } export function parseMail(email, options) { return __awaiter(this, void 0, void 0, function* () { var _a; const [html, text] = yield Promise.all([ renderAsync(email), renderAsync(email, { plainText: true }), ]); const data = { from: mailContactToType(options.from), to: mailContactsToType(options.to), cc: options.cc ? mailContactsToType(options.cc) : undefined, bcc: options.bcc ? mailContactsToType(options.bcc) : undefined, reply_to: options.replyTo ? mailContactToType(options.replyTo) : undefined, text, html, }; const useConsoleLogInDevMode = (_a = options.useConsoleLogInDevMode) !== null && _a !== void 0 ? _a : defaultEmailOptions.useConsoleLogInDevMode; if (process.env.NODE_ENV === 'development' && useConsoleLogInDevMode) { const toContact = data.to.map((c) => (c.name ? `${c.name} <${c.email}>` : c.email)) .join(', '); // eslint-disable-next-line no-console console.log(`\n📧 to ${toContact}: ${options.subject}\n${text}\n`); return; } return data; }); } export function quotedPrintableEncode(input) { const encoder = new TextEncoder(); // encodes to UTF-8 bytes const bytes = encoder.encode(input); let result = ''; let lineLength = 0; const softBreak = () => { result += '=\r\n'; lineLength = 0; }; for (let i = 0; i < bytes.length; i++) { const byte = bytes[i]; // Printable ASCII range excluding '=' (equals) const isPrintable = (byte >= 33 && byte <= 60) || (byte >= 62 && byte <= 126); let toAppend; if (byte === 0x3D || !isPrintable) { // Needs encoding (e.g. "=" or non-printable) toAppend = '=' + byte.toString(16).toUpperCase().padStart(2, '0'); } else { toAppend = String.fromCharCode(byte); } // Line length: soft wrap at 76 characters if (lineLength + toAppend.length > 75) { softBreak(); } result += toAppend; lineLength += toAppend.length; } return result; } function bytesToBase64(bytes) { let binary = ''; const CHUNK_SIZE = 0x8000; // 32KB for (let i = 0; i < bytes.length; i += CHUNK_SIZE) { const chunk = bytes.subarray(i, i + CHUNK_SIZE); binary += String.fromCharCode.apply(null, chunk); } return btoa(binary); } export function encodeAttachmentToBase64(content) { if (typeof content === 'string') { return content; } else if (content instanceof ArrayBuffer) { return bytesToBase64(new Uint8Array(content)); } else if (Buffer.isBuffer(content)) { return content.toString('base64'); } else { throw new Error('Unsupported attachment content format (supported: string, Buffer, ArrayBuffer)'); } }