npm package: @salvadorlimones/dinamail
Description: A unified SDK for email sending across multiple providers (SendGrid, Mailgun, etc.)
Latest version: 0.2.2

# Dinamail

A unified SDK for sending emails across multiple providers. TypeScript-first with optional Nest.js integration. Currently supports SendGrid.

---

## For end users

### Installation

```bash
npm install @salvadorlimones/dinamail
```

### Nest.js setup

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { DinamailModule } from '@salvadorlimones/dinamail/nest';

@Module({
  imports: [
    DinamailModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => ({
        provider: 'sendgrid',
        sendgrid: {
          apiKey: config.get('SENDGRID_API_KEY'),
          fromEmail: config.get('SENDGRID_SENDER_EMAIL'),
          fromName: config.get('SENDGRID_SENDER_NAME'),
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}
```

### Sending emails

Inject `DinamailService` and use it:

```typescript
import { Injectable } from '@nestjs/common';
import { DinamailService } from '@salvadorlimones/dinamail/nest';

@Injectable()
export class MyService {
  constructor(private readonly dinamail: DinamailService) {}

  async sendPlainEmail() {
    await this.dinamail.sendEmailOrThrow({
      to: 'user@example.com',
      subject: 'Hello',
      text: 'Plain text body',
      html: '<p>HTML body</p>',
    });
  }

  async sendTemplateEmail(template: EmailTemplate) {
    await this.dinamail.sendEmailWithTemplateOrThrow({
      to: 'user@example.com',
      template,
    });
  }
}
```

**Methods:**

- `sendEmail` / `sendEmailOrThrow` – plain or HTML emails (OrThrow throws on failure)
- `sendEmailWithTemplate` / `sendEmailWithTemplateOrThrow` – templated emails (OrThrow throws on failure)

### Type-safe templates

Extend `EmailTemplate` for SendGrid dynamic templates:

```typescript
import { EmailTemplate } from '@salvadorlimones/dinamail';

class ForgotPasswordEmail extends EmailTemplate<{ resetUrl: string }> {
  templateId = 'd-your-sendgrid-template-id';

  constructor(private data: { token: string; baseUrl: string }) {
    super();
  }

  getParams() {
    return {
      resetUrl: `${this.data.baseUrl}?token=${this.data.token}`,
    };
  }
}

// Usage
await this.dinamail.sendEmailWithTemplateOrThrow({
  to: user.email,
  template: new ForgotPasswordEmail({ token, baseUrl }),
});
```

### Standalone usage (without Nest.js)

```typescript
import { DinamailClient } from '@salvadorlimones/dinamail';

const client = new DinamailClient({
  provider: 'sendgrid',
  sendgrid: {
    apiKey: process.env.SENDGRID_API_KEY,
    fromEmail: 'noreply@example.com',
    fromName: 'My App',
  },
});

await client.sendEmailOrThrow({
  to: 'user@example.com',
  subject: 'Hello',
  text: 'Hello world',
});
```

### Environment variables

- `DINAMAIL_PROVIDER` – `sendgrid` (default)
- `SENDGRID_API_KEY` – required for SendGrid
- `SENDGRID_SENDER_EMAIL` – default from address
- `SENDGRID_SENDER_NAME` – default from name

---

## For developers (dinamail maintainers)

### Scripts

```bash
npm run build    # Build the package (tsup)
npm run dev      # Watch mode
npm run lint     # Type check
```

### Releasing a new version

1. Add a changeset for your changes:
   ```bash
   npx changeset
   ```
   Choose the version bump (patch/minor/major) and describe the change.

2. Apply changesets and bump versions:
   ```bash
   npx changeset version
   ```

3. Build and publish:
   ```bash
   npm run build
   npm publish
   ```

### Project structure

- `src/client.ts` – core `DinamailClient`
- `src/nest/` – Nest.js module and service
- `src/providers/` – provider implementations (SendGrid, etc.)
- `src/types.ts` – shared types and `EmailTemplate` base class