UNPKG

@synet/email

Version:

Secure, production ready, multi-provider email unit following Unit Architecture principles. Supports SMTP, AWS SES, and Resend.

412 lines (326 loc) 9.78 kB
# @synet/email ```bash _______ .___ ___. ___ __ __ | ____|| \/ | / \ | | | | | |__ | \ / | / ^ \ | | | | | __| | |\/| | / /_\ \ | | | | | |____ | | | | / _____ \ | | | `----. |_______||__| |__| /__/ \__\ |__| |_______| __ __ .__ __. __ .___________. | | | | | \ | | | | | | | | | | | \| | | | `---| |----` | | | | | . ` | | | | | | `--' | | |\ | | | | | \______/ |__| \__| |__| |__| version: 1.0.2 ``` Production ready, secure email sending library following Unit Architecture principles. ```bash npm i @synet/email ``` ## Quick Start ```typescript import { Email } from "@synet/email"; // Create email unit const email = Email.create({ type: "smtp", options: { host: "smtp.gmail.com", port: 587, secure: false, auth: { user: "your-email@gmail.com", pass: "your-app-password", }, }, }); // Send email const result = await email.send({ from: "sender@example.com", to: "recipient@example.com", subject: "Hello from SYNET!", text: "This is a test email from the SYNET Email Unit.", html: "<h1>Hello from SYNET!</h1><p>This is a <strong>test email</strong> from the SYNET Email Unit.</p>", }); if (result.success) { console.log("Email sent! Message ID:", result.messageId); } else { console.error("Failed to send:", result.error); } ``` ## Email Adapters The library provides multiple email adapters for different providers and use cases. ### SMTP Adapter Production-ready SMTP implementation using nodemailer for reliable email delivery. ```typescript import { SMTPEmail } from "@synet/email"; const smtp = new SMTPEmail({ host: "email-smtp.eu-west-1.amazonaws.com", // AWS SES port: 587, secure: false, // false for STARTTLS, true for SSL auth: { user: "AKIA...", // AWS SES SMTP username pass: "BIG...", // AWS SES SMTP password }, }); // Test connection const canConnect = await smtp.checkConnection(); console.log("Can connect:", canConnect); // Send email const result = await smtp.send({ from: "noreply@yourapp.com", to: "user@example.com", subject: "Welcome!", text: "Welcome to our service!", }); ``` #### Supported SMTP Providers - **AWS SES**: `email-smtp.{region}.amazonaws.com:587` - **Gmail**: `smtp.gmail.com:587` (requires app password) - **Outlook/Office365**: `smtp.office365.com:587` - **SendGrid**: `smtp.sendgrid.net:587` - **Resend**: `smtp.resend.com:587` - **Custom SMTP**: Any RFC-compliant SMTP server ### Resend Adapter HTTP API implementation for Resend.com transactional email service. ```typescript import { ResendEmail } from "@synet/email"; const resend = new ResendEmail({ apiKey: "re_your_api_key_here", }); // Test connection const canConnect = await resend.checkConnection(); // Send email const result = await resend.send({ from: "onboarding@yourapp.com", to: "user@example.com", subject: "Welcome to our platform!", html: "<h1>Welcome!</h1><p>Thanks for joining us.</p>", }); ``` ## Unit Architecture Email follows the Unit Architecture pattern - conscious software components that can teach capabilities to other units and learn from them. ### Basic Unit Usage ```typescript import { Email } from "@synet/email"; // Create email unit const emailUnit = Email.create({ type: "smtp", options: { host: "smtp.resend.com", port: 587, secure: false, auth: { user: "resend", pass: "your-api-key", }, }, }); // Unit information console.log("Unit identity:", emailUnit.whoami()); console.log("Capabilities:", emailUnit.capabilities()); console.log("Can send emails:", emailUnit.capableOf("send")); // Test capabilities const isValid = await emailUnit.validateEmail("test@example.com"); const canConnect = await emailUnit.checkConnection(); ``` ### Teaching and Learning Email units can teach their capabilities to other units in the SYNET consciousness network: ```typescript // Get teaching contract const contract = emailUnit.teach(); console.log("Teaching contract:", contract); // Example teaching contract: // { // unitId: "email", // capabilities: { // validateEmail: [Function], // checkConnection: [Function], // send: [Function] // } // } // Another unit can learn from this contract const learnerUnit = SomeOtherUnit.create().learn([contract]); // Now the learner can execute email capabilities const result = await learnerUnit.execute("email.send", { from: "system@app.com", to: "user@example.com", subject: "Automated notification", text: "This email was sent by a unit that learned email capabilities!" }); ``` ### Unit Evolution Units are immutable but can evolve to new versions: ```typescript // Evolve unit with new configuration const evolvedUnit = emailUnit.evolve({ type: "resend", options: { apiKey: "new-resend-api-key", }, }); // Original unit unchanged, evolved unit has new config console.log("Original provider:", emailUnit.getConfig().type); // "smtp" console.log("Evolved provider:", evolvedUnit.getConfig().type); // "resend" ``` ### Multi-Provider Setup ```typescript // Create multiple email units for different purposes const transactionalEmail = Email.create({ type: "resend", options: { apiKey: "re_..." }, }); const marketingEmail = Email.create({ type: "smtp", options: { host: "smtp.sendgrid.net", port: 587, auth: { user: "apikey", pass: "SG...." }, }, }); // Use appropriate unit for each use case await transactionalEmail.send({ from: "noreply@app.com", to: "user@example.com", subject: "Password Reset", // ... }); await marketingEmail.send({ from: "newsletter@app.com", to: "subscribers@example.com", subject: "Weekly Newsletter", // ... }); ``` ## API Reference ### Email Unit #### `Email.create(config)` Creates a new email unit with the specified provider configuration. **Parameters:** - `config.type`: `"smtp" | "resend"` - Email provider type - `config.options`: Provider-specific configuration object **Returns:** `Email` unit instance #### Instance Methods - `send(message)`: Send an email message - `validateEmail(email)`: Validate email address format - `checkConnection()`: Test connection to email provider - `teach()`: Get teaching contract with capabilities - `learn(contracts)`: Learn capabilities from other units - `evolve(config)`: Create evolved unit with new configuration ### Email Message ```typescript interface EmailMessage { from: string; to: string | string[]; subject: string; text?: string; html?: string; cc?: string | string[]; bcc?: string | string[]; replyTo?: string; attachments?: EmailAttachment[]; } ``` ### Email Result ```typescript interface EmailResult { success: boolean; messageId?: string; error?: string; } ``` ## Configuration ### SMTP Configuration ```typescript interface SMTPConfig { host: string; // SMTP server hostname port: number; // SMTP port (587 for STARTTLS, 465 for SSL) secure?: boolean; // true for SSL, false for STARTTLS auth?: { user: string; // SMTP username pass: string; // SMTP password or API key }; timeout?: number; // Connection timeout in milliseconds } ``` ### Resend Configuration ```typescript interface ResendConfig { apiKey: string; // Resend API key baseUrl?: string; // API base URL (default: https://api.resend.com) timeout?: number; // Request timeout in milliseconds } ``` ## Testing ```bash # Run all tests npm test # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch ``` ## Examples ### AWS SES Example ```typescript const email = Email.create({ type: "smtp", options: { host: "email-smtp.eu-west-1.amazonaws.com", port: 587, secure: false, auth: { user: process.env.AWS_SES_SMTP_USER, pass: process.env.AWS_SES_SMTP_PASS, }, }, }); ``` ### Gmail Example ```typescript const email = Email.create({ type: "smtp", options: { host: "smtp.gmail.com", port: 587, secure: false, auth: { user: "your-email@gmail.com", pass: "your-app-password", // Generate in Google Account settings }, }, }); ``` ### Resend Example ```typescript const email = Email.create({ type: "resend", options: { apiKey: process.env.RESEND_API_KEY, }, }); ``` ## Architecture This library follows the SYNET Unit Architecture principles: - **Zero Dependencies**: Core units have no external dependencies (nodemailer is used for SMTP reliability) - **Teach/Learn Paradigm**: Units can teach capabilities to other units - **Props Contain Everything**: No private field duplication, props are single source of truth - **Immutable Evolution**: Units evolve to new versions rather than mutating - **Capability-Based Composition**: Acquire capabilities through learning, not inheritance ## Requirements - Node.js 18.0.0 - TypeScript 5.0.0 (for development) ## License MIT ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass 6. Submit a pull request ## See also - [@synet/unit](https://github.com/synthetism/unit) - Core Unit Architecture framework - [@synet/fs](https://github.com/synthetism/fs) - File system operations with Unit Architecture - [@synet/ai](https://github.com/synthetism/ai) - AI Operator unit - control your units with AI. - [JOIN SYNET](https://synthetism.ai)