# Scaleway Transactional Email (TEM) Node.js Library

A clean, type-safe, and fluent Node.js library for sending emails via Scaleway's Transactional Email (TEM) service. It also supports the **Strategy Pattern** to allow switching between different email providers (e.g., SMTP/Mailpit for testing).

## Features

- 🚀 **Fluent Builder Pattern**: Easily construct complex emails.
- 🛡️ **Type-Safe**: Written in TypeScript with full type definitions.
- 🔌 **Strategy Pattern**: Switch between Scaleway TEM and SMTP (e.g., Mailpit) easily.
- 🛠️ **Utilities**: Helper functions like `fileToBase64` for easy attachment handling.
- 🌍 **Scaleway Specific**: Tailored for Scaleway's TEM API (v1alpha1).

## Table of Contents

- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Configuration](#configuration)
  - [Scaleway TEM](#scaleway-tem)
  - [SMTP (Development/Testing)](#smtp-developmenttesting)
- [Usage](#usage)
  - [1. Initialize the Client](#1-initialize-the-client)
  - [2. Build and Send an Email](#2-build-and-send-an-email)
  - [3. Advanced Usage](#3-advanced-usage)
- [API Reference](#api-reference)
  - [EmailClient](#emailclient)
  - [EmailBuilder](#emailbuilder)
  - [Transporters](#transporters)
- [Error Handling](#error-handling)
- [Contributing](#contributing)
- [License](#license)

## Prerequisites

- Node.js >= 18.0.0
- A Scaleway account with Transactional Email activated (for production use).

## Installation

```bash
npm install scaleway-tem-node
# or
yarn add scaleway-tem-node
# or
pnpm add scaleway-tem-node
```

## Configuration

### Scaleway TEM

To use Scaleway's Transactional Email service, you need a `ScalewayTransporter`.

```typescript
import { ScalewayTransporter } from 'scaleway-tem-node';

const transporter = new ScalewayTransporter({
  secretKey: process.env.SCW_SECRET_KEY, // Your Scaleway Secret Key
  projectId: process.env.SCW_DEFAULT_PROJECT_ID, // Your Project ID
  region: 'fr-par', // Optional: defaults to 'fr-par'
});
```

### SMTP (Development/Testing)

For local development or testing, you can use the `SmtpTransporter`. This is compatible with tools like [Mailpit](https://github.com/axllent/mailpit) or any standard SMTP server.

```typescript
import { SmtpTransporter } from 'scaleway-tem-node';

const transporter = new SmtpTransporter({
  host: 'localhost',
  port: 1025,
  // secure: false, // true for 465, false for other ports
  // auth: {
  //   user: 'user',
  //   pass: 'pass',
  // },
});
```

## Usage

### 1. Initialize the Client

Pass your configured transporter to the `EmailClient`.

```typescript
import { EmailClient, ScalewayTransporter } from 'scaleway-tem-node';

const transporter = new ScalewayTransporter({ /* config */ });
const client = new EmailClient(transporter);
```

### 2. Build and Send an Email

Use the `EmailBuilder` to construct your email.

```typescript
import { EmailBuilder, fileToBase64 } from 'scaleway-tem-node';

async function sendEmail() {
  // Helper to read file as base64
  const pdfContent = await fileToBase64('./invoice.pdf');

  const email = new EmailBuilder()
    .setFrom('no-reply@my-domain.com', 'My Service')
    .addTo('user@example.com', 'John Doe')
    .setSubject('Your Invoice')
    .setText('Please find your invoice attached.')
    .setHtml('<p>Please find your <b>invoice</b> attached.</p>')
    .addAttachment('invoice.pdf', 'application/pdf', pdfContent)
    .build();

  const result = await client.sendEmail(email);
  console.log('Email sent with ID:', result.id);
}
```

### 3. Advanced Usage

The builder supports CC, BCC, custom headers, and scheduling.

```typescript
const email = new EmailBuilder()
  .setFrom('me@domain.com')
  .addTo('primary@example.com')
  .addCc('manager@example.com')
  .addBcc('audit@example.com')
  .addHeader('X-Custom-ID', '12345')
  .setSendBefore(new Date(Date.now() + 3600 * 1000)) // Send before 1 hour from now
  .build();
```

## API Reference

### EmailClient

The main entry point for sending emails.

- **`constructor(transporter: EmailTransporter)`**
- **`sendEmail(email: DraftEmail | CreateEmailRequest): Promise<Email>`**
  - Sends the email using the configured transporter.
- **`setTransporter(transporter: EmailTransporter): void`**
  - Switch the transporter at runtime (e.g., based on environment).

### EmailBuilder

A fluent interface for creating email objects.

- **`setFrom(email: string, name?: string)`**: Set sender.
- **`addTo(email: string, name?: string)`**: Add primary recipient.
- **`addCc(email: string, name?: string)`**: Add carbon copy recipient.
- **`addBcc(email: string, name?: string)`**: Add blind carbon copy recipient.
- **`setSubject(subject: string)`**: Set email subject.
- **`setText(text: string)`**: Set plain text content.
- **`setHtml(html: string)`**: Set HTML content.
- **`addAttachment(name: string, type: string, content: string)`**: Add attachment (content must be Base64).
- **`addHeader(key: string, value: string)`**: Add custom header.
- **`setSendBefore(date: Date)`**: Set expiration time (Scaleway specific).
- **`build(): DraftEmail`**: Returns the constructed email object.

### Transporters

#### `ScalewayTransporter`
- Implements `EmailTransporter`.
- Uses Scaleway's REST API.
- **Config**: `{ secretKey: string; projectId: string; region?: 'fr-par' }`

#### `SmtpTransporter`
- Implements `EmailTransporter`.
- Uses `nodemailer` under the hood.
- **Config**: Standard Nodemailer SMTP transport options (`host`, `port`, `auth`, etc.).

## Error Handling

The library throws errors if the API call fails or validation fails.

```typescript
try {
  await client.sendEmail(email);
} catch (error) {
  if (error instanceof Error) {
    console.error('Error message:', error.message);
  }
  // Scaleway specific errors might contain more details in the message
}
```

## Contributing

Contributions are welcome!

1. Clone the repository.
2. Install dependencies: `npm install`
3. Run tests: `npm test`
4. Build: `npm run build`

## License

MIT
