npm package: @jamx-framework/mailer
Description: JAMX Framework â€” Transactional email
Author: Stiven-21
Latest version: 1.0.0

# @jamx-framework/mailer

## Descripción
Módulo de envío de correos electrónicos para JAMX Framework. Proporciona una API type-safe para enviar emails con múltiples drivers (SMTP, consola, servicios en la nube), soporte para plantillas (Handlebars, MJML), adjuntos, y gestión de colas. Ideal para aplicaciones que necesitan enviar emails transaccionales, newsletters o notificaciones.

## Cómo funciona
El módulo implementa un sistema de envío de emails con drivers intercambiables:

1. **Mailer**: Clase principal que construye y envía emails
2. **Drivers**: Implementaciones concretas (SmtpDriver, ConsoleDriver) para diferentes métodos de envío
3. **Templates**: Motor de plantillas con soporte para Handlebars y MJML
4. **Queue**: Integración opcional con colas para envío asíncrono

## Componentes principales
- **src/mailer.ts**: Clase `Mailer` que construye y envía emails
- **src/drivers/smtp.ts**: Driver que envía via SMTP
- **src/drivers/console.ts**: Driver que imprime a consola (desarrollo/testing)
- **src/drivers/types.ts**: Tipos compartidos (`MailDriver`, `MailMessage`, etc.)
- **src/templates/engine.ts**: Motor de plantillas (Handlebars)
- **src/templates/defaults.ts**: Plantillas predefinidas (welcome, reset password, etc.)
- **src/index.ts**: Punto de exportación

## Uso básico
```typescript
import { Mailer, SmtpDriver } from '@jamx-framework/mailer';

// Configurar driver SMTP
const driver = new SmtpDriver({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    user: 'tu-email@gmail.com',
    pass: 'tu-contraseña',
  },
});

const mailer = new Mailer(driver);

// Enviar email simple
await mailer.send({
  from: 'noreply@miapp.com',
  to: 'usuario@example.com',
  subject: 'Bienvenido',
  text: '¡Hola! Bienvenido a nuestra app.',
  html: '<p>¡Hola! Bienvenido a nuestra app.</p>',
});
```

### Con plantillas
```typescript
import { Mailer, SmtpDriver } from '@jamx-framework/mailer';

const mailer = new Mailer(new SmtpDriver(config));

// Renderizar plantilla con datos
const html = await mailer.render('welcome', {
  userName: 'Juan',
  activationLink: 'https://miapp.com/activate?token=abc123',
});

await mailer.send({
  from: 'noreply@miapp.com',
  to: 'juan@example.com',
  subject: 'Bienvenido a MiApp',
  html,
});
```

## Ejemplos
### Email con adjuntos
```typescript
await mailer.send({
  from: 'support@miapp.com',
  to: 'user@example.com',
  subject: 'Tu reporte',
  text: 'Adjunto encontrarás tu reporte.',
  attachments: [
    {
      filename: 'reporte.pdf',
      content: Buffer.from('PDF content here'),
      contentType: 'application/pdf',
    },
    {
      filename: 'imagen.png',
      path: '/ruta/a/imagen.png', // también se puede usar path
    },
  ],
});
```

### Email con CC y BCC
```typescript
await mailer.send({
  from: 'admin@miapp.com',
  to: 'principal@example.com',
  cc: ['cc1@example.com', 'cc2@example.com'],
  bcc: ['hidden@example.com'],
  subject: 'Notificación importante',
  html: '<p>Este es un mensaje importante.</p>',
});
```

### Uso con plantillas Handlebars
```typescript
// Registrar plantilla personalizada
mailer.registerTemplate('invoice', {
  subject: 'Factura #{{invoiceNumber}}',
  html: `
    <h1>Factura {{invoiceNumber}}</h1>
    <p>Hola {{customerName}},</p>
    <p>El total a pagar es: ${{total}}</p>
  `,
});

// Usar la plantilla
await mailer.send({
  from: 'billing@miapp.com',
  to: 'customer@example.com',
  template: 'invoice',
  data: {
    invoiceNumber: 'INV-2024-001',
    customerName: 'Juan Pérez',
    total: '150.00',
  },
});
```

### Driver de consola (desarrollo)
```typescript
import { Mailer, ConsoleDriver } from '@jamx-framework/mailer';

// En desarrollo, usar ConsoleDriver para no enviar emails reales
const mailer = new Mailer(new ConsoleDriver());

await mailer.send({
  from: 'test@localhost',
  to: 'user@example.com',
  subject: 'Test',
  html: '<p>Esto se imprime en consola</p>',
});
// Output: [Mailer] Sending email to user@example.com with subject "Test"
```

### Envío con cola (Queue integration)
```typescript
import { Mailer, SmtpDriver } from '@jamx-framework/mailer';
import { Queue } from '@jamx-framework/queue';

const mailer = new Mailer(new SmtpDriver(config));
const queue = new Queue();

// Encolar email para envío asíncrono
await queue.add('send-email', {
  message: {
    from: 'noreply@miapp.com',
    to: 'user@example.com',
    subject: 'Notificación',
    html: '<p>Contenido</p>',
  },
});

// Worker que procesa la cola
queue.process('send-email', async (job) => {
  await mailer.send(job.data.message);
});
```

### Inyección de dependencias
```typescript
import { Container } from '@jamx-framework/core';
import { Mailer, SmtpDriver } from '@jamx-framework/mailer';

// Registrar en contenedor
Container.registerSingleton('mailer', () => {
  const driver = new SmtpDriver({
    host: process.env.SMTP_HOST,
    port: Number(process.env.SMTP_PORT),
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASS,
    },
  });
  return new Mailer(driver);
});

// Usar en cualquier parte
const mailer = Container.resolve<Mailer>('mailer');
await mailer.send({
  from: 'noreply@miapp.com',
  to: 'user@example.com',
  subject: 'Hello',
  text: 'Hello world',
});
```

## Flujo interno
1. **Configuración**: Se crea un driver (SMTP, Console, etc.) y se pasa al `Mailer`
2. **Construcción**: `mailer.send()` construye un `MailMessage` con from, to, subject, content, attachments
3. **Validación**: Se validan campos obligatorios (from, to, subject)
4. **Renderizado**: Si se usa `template`, se renderiza con los datos proporcionados
5. **Envío**: El driver recibe el mensaje y lo envía por el medio correspondiente
6. **Respuesta**: El driver retorna un `SendResult` con status, messageId, etc.
7. **Error handling**: Los errores se capturan y se lanzan como `MailerError`

## API Reference (Resumen)
### Mailer
- `constructor(driver: MailDriver)`
- `async send(message: MailMessage | Partial<MailMessage> & { template: string, data: any }): Promise<SendResult>`
- `async render(templateName: string, data: any): Promise<string>`
- `registerTemplate(name: string, template: MailTemplate): void`
- `hasTemplate(name: string): boolean`

### MailMessage
- `from: string | { name: string, address: string }`
- `to: string | string[] | { name: string, address: string }[]`
- `cc?: string | string[]`
- `bcc?: string | string[]`
- `subject: string`
- `text?: string`
- `html?: string`
- `attachments?: Attachment[]`
- `headers?: Record<string, string>`

### Attachment
- `filename: string`
- `content?: Buffer | string`
- `path?: string`
- `contentType?: string`

### MailDriver (interface)
- `async send(message: MailMessage): Promise<SendResult>`
- `async verifyConnection(): Promise<boolean>`

### SendResult
- `success: boolean`
- `messageId?: string`
- `error?: string`
- `accepted?: number`
- `rejected?: number`

## Performance Considerations
- **Connection pooling**: SMTP driver reutiliza conexiones cuando es posible
- **Batch sending**: Se pueden enviar múltiples emails concurrentemente
- **Template caching**: Las plantillas compiladas se cachean en memoria
- **Lazy rendering**: Las plantillas se renderizan solo cuando se usan
- **Queue integration**: Para alto volumen, usar colas para procesamiento asíncrono

## Configuration Options
```typescript
// SMTP Driver
const smtpDriver = new SmtpDriver({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false, // true para SSL/TLS
  auth: {
    user: 'user@example.com',
    pass: 'password',
  },
  pool: {
    maxConnections: 5,
    maxMessages: 100,
  },
});

// Console Driver (desarrollo)
const consoleDriver = new ConsoleDriver({
  verbose: true, // imprime detalles completos
  format: 'json', // 'json' | 'text'
});
```

## Testing
Tests en `packages/mailer/tests/unit/`:

```bash
pnpm test
```

Cubre:
- Envío de emails básicos
- Adjuntos y CC/BCC
- Renderizado de plantillas
- Drivers múltiples (SMTP mock, console)
- Validación de mensajes
- Manejo de errores

## Compatibility
- Compatible con Node.js 18+
- Funciona con cualquier servidor SMTP (Gmail, SendGrid, Mailgun, etc.)
- Soporta TLS/SSL
- No requiere dependencias nativas

## CLI Integration
- `jamx mail:send`: Envía un email desde CLI
- `jamx mail:test`: Prueba la configuración SMTP
- `jamx mail:template:compile`: Compila plantillas MJML a HTML
- `jamx mail:queue:process`: Procesa cola de emails pendientes

## Security Considerations
- **Never hardcode credentials**: Usar variables de entorno para SMTP credentials
- **Validate inputs**: Sanitizar datos de plantillas para evitar XSS
- **Use TLS**: Siempre usar secure: true en producción
- **Rate limiting**: Limitar envíos para evitar spam
- **BCC for bulk**: Usar BCC para emails masivos (no revelar direcciones)

## Best Practices
1. **Usar templates**: Mantener HTML en plantillas, no en código
2. **Separar drivers**: Usar ConsoleDriver en dev, SmtpDriver en prod
3. **Manejar errores**: Capturar `MailerError` y loguear
4. **Queue for async**: Para alto volumen, usar colas (RabbitMQ, Redis)
5. **Test emails**: Enviar emails de prueba antes de campañas masivas
6. **Monitor delivery**: Revisar bounce rates y spam complaints
7. **Use DKIM/SPF**: Configurar autenticación de email en dominio

This mailer module provides a flexible, type-safe email sending solution for JAMX applications, enabling developers to send transactional and marketing emails with multiple drivers, template support, and queue integration.