npm package: @lantern-ai/email-core-utility
Description: Server-first email utility package (SendGrid helpers, config helpers, small React hook)
Latest version: 0.1.0

# @lantern/email-core-utility

A powerful, framework-agnostic utility for sending transactional emails using SendGrid. It provides a simple, unified API for both server-side (Node.js) and client-side (React) applications.

## Features and Functionalities

This utility is designed to abstract away the complexities of email delivery, providing a robust and easy-to-use interface for sending dynamic, template-based emails.

### Core Concepts

-   **Configuration First**: The library operates on a "configure-once, use-anywhere" principle. You initialize it with your SendGrid credentials on server startup, and the configuration is securely managed in memory.
-   **Server-Side Focus**: All sensitive operations, including API key management and email sending, are designed to be run on the server to prevent exposing credentials to the client.
-   **React Hook for Client-Side**: A `useSendEmail` hook is provided to trigger server-side email functions from your React components, while managing loading and error states.

### Configuration Management

-   **`setSendGridConfig(config)`**: The primary function to initialize the utility with your SendGrid API key, "from" email, and a map of your transactional template IDs.
-   **`getSendGridConfig()`**: Retrieves the current SendGrid configuration.
-   **`setEmailCoreConfig(config)` / `getEmailCoreConfig()`**: More generic functions for managing the entire email configuration object, allowing for future expansion to other email providers.

### Email Sending (Server-Side)

-   **`sendTemplateEmail(...)`**: Sends an email using a dynamic SendGrid template. You provide the recipient, template ID, and a data object to populate the template.
-   **`sendRawEmail(...)`**: Sends a standard HTML email with a subject and body, for cases where a dynamic template isn't needed.
-   **`sendEmail(...)`**: A versatile function that can send either a template-based or a raw HTML email based on the options provided.

### React Hook (Client-Side)

-   **`useSendEmail()`**: A hook that simplifies the process of calling an email-sending function from your frontend. It returns:
    -   `loading`: A boolean that is `true` while the email is being sent.
    -   `error`: An `Error` object if the sending fails.
    -   `send(sendFn)`: A wrapper function that you call with your server-side email function. It handles setting the loading and error states for you.

## Installation

```bash
npm install email-core-utility
```

## API Reference

### sendEmail
A single, reusable function for sending emails:

```typescript
import { configureSendgrid, sendEmail, EmailOptions } from 'email-core-utility';

const sg = configureSendgrid(process.env.SENDGRID_API_KEY!);

// Send a template email
await sendEmail(sg, {
  to: 'user@example.com',
  templateId: 'd-xxxxxx',
  dynamicTemplateData: { name: 'User' }
});

// Send a raw email
await sendEmail(sg, {
  to: 'user@example.com',
  subject: 'Welcome',
  html: '<b>Hello!</b>'
});
```

**EmailOptions**:
- `to` (string): Recipient email address
- `subject` (string, optional): Subject for raw emails
- `html` (string, optional): HTML body for raw emails
- `templateId` (string, optional): SendGrid template ID
- `dynamicTemplateData` (object, optional): Data for dynamic templates
- `from` (string, optional): Sender address (default: )

### Error Handling
All errors are wrapped as `Email send failed: ...` for consistent logging and debugging.

### Other Helpers
- `configureSendgrid(apiKey: string)`
- `buildMailSettings()`
- `setConfig(cfg)` / `getConfig()` / `clearConfig()`
- `useSendEmail()` (React hook)

## Advanced Configuration System

The package now includes a comprehensive configuration system designed for projects like **PetWell.com** that need to manage multiple email templates and settings.

### 🔧 Environment-Based Configuration

The recommended approach is to use environment variables for configuration:

```bash
# SendGrid Configuration
SENDGRID_API_KEY=SG.your_sendgrid_api_key
SENDGRID_FROM_EMAIL=noreply@petwell.com
SUPPORT_EMAIL=support@petwell.com

# SendGrid Template IDs (create these in SendGrid)
SENDGRID_PREORDER_CONFIRMATION_TEMPLATE=d-preorder-confirmation
SENDGRID_CHARGE_UPCOMING_TEMPLATE=d-charge-upcoming
SENDGRID_CHARGE_SUCCESSFUL_TEMPLATE=d-charge-successful
SENDGRID_CHARGE_FAILED_TEMPLATE=d-charge-failed
SENDGRID_PAYMENT_UPDATED_TEMPLATE=d-payment-updated
SENDGRID_ORDER_CANCELLED_TEMPLATE=d-order-cancelled
SENDGRID_SHIPPING_TEMPLATE=d-shipping-notification
```

Initialize the configuration in your server startup:

```typescript
import { initializeFromEnv } from 'email-core-utility';

// Initialize from environment variables
try {
  const config = initializeFromEnv();
  console.log('✅ Email system initialized');
} catch (error) {
  console.error('❌ Email initialization failed:', error.message);
  process.exit(1);
}
```

### 📧 Pre-built Email Functions

The package includes convenient functions for common email types:

```typescript
import {
  sendPreorderConfirmation,
  sendChargeSuccessful,
  sendChargeFailed,
  sendPaymentUpdated,
  sendOrderCancelled,
  sendShippingNotification
} from 'email-core-utility';

// Send preorder confirmation
await sendPreorderConfirmation('customer@example.com', {
  customerName: 'John Doe',
  orderNumber: 'PW-12345',
  orderTotal: '$29.99',
  estimatedDelivery: 'March 15, 2024'
});

// Send charge successful notification
await sendChargeSuccessful('customer@example.com', {
  customerName: 'John Doe',
  chargeAmount: '$29.99',
  paymentMethod: '**** 1234',
  transactionId: 'txn_abc123'
});

// Send shipping notification
await sendShippingNotification('customer@example.com', {
  customerName: 'John Doe',
  trackingNumber: 'TRK123456789',
  carrier: 'UPS',
  estimatedDelivery: 'March 20, 2024'
});
```

### 🎯 Generic Email Function

For maximum flexibility, use the `sendConfiguredEmail` function:

```typescript
import { sendConfiguredEmail } from 'email-core-utility';

// Send using template name
await sendConfiguredEmail({
  to: 'customer@example.com',
  templateName: 'preorderConfirmation',
  dynamicTemplateData: { orderNumber: '12345' }
});

// Send using direct template ID
await sendConfiguredEmail({
  to: 'customer@example.com',
  templateId: 'd-custom-template-id',
  dynamicTemplateData: { customData: 'value' }
});

// Send raw HTML email
await sendConfiguredEmail({
  to: 'customer@example.com',
  subject: 'Custom Subject',
  html: '<h1>Custom HTML content</h1>'
});
```

### 🏗️ Manual Configuration

For testing or custom setups, you can configure manually:

```typescript
import { setSendGridConfig } from 'email-core-utility';

setSendGridConfig({
  apiKey: 'SG.your_api_key',
  fromEmail: 'noreply@petwell.com',
  supportEmail: 'support@petwell.com',
  templates: {
    preorderConfirmation: 'd-template-1',
    chargeSuccessful: 'd-template-2',
    // Add custom templates
    customWelcome: 'd-welcome-123'
  }
});
```

### 🔍 Helper Functions

Access configuration values anywhere in your application:

```typescript
import { 
  getTemplateId, 
  getFromEmail, 
  getSupportEmail 
} from 'email-core-utility';

const templateId = getTemplateId('preorderConfirmation');
const fromEmail = getFromEmail();
const supportEmail = getSupportEmail();
```

### 💡 Express.js Integration Example

```typescript
import express from 'express';
import { initializeFromEnv, sendPreorderConfirmation } from 'email-core-utility';

const app = express();
app.use(express.json());

// Initialize on startup
initializeFromEnv();

app.post('/api/orders/:id/confirm', async (req, res) => {
  try {
    const { customerEmail, orderData } = req.body;
    
    await sendPreorderConfirmation(customerEmail, {
      customerName: orderData.customerName,
      orderNumber: orderData.orderNumber,
      orderTotal: orderData.total,
      estimatedDelivery: orderData.estimatedDelivery
    });

    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
```

### 🔒 Security Features

- **Server-only configuration**: All configuration functions include browser guards
- **Environment validation**: Required fields are validated on initialization
- **Type safety**: Full TypeScript support with interfaces for all data structures
- **Error standardization**: Consistent error handling across all functions

### 📋 TypeScript Interfaces

```typescript
interface SendGridConfig {
  apiKey: string;
  fromEmail: string;
  supportEmail?: string;
  templates: {
    preorderConfirmation?: string;
    chargeUpcoming?: string;
    chargeSuccessful?: string;
    chargeFailed?: string;
    paymentUpdated?: string;
    orderCancelled?: string;
    shipping?: string;
    [key: string]: string | undefined; // Custom templates
  };
}
```

## Example Apps
- **Express demo server**: See `examples/demo/server.ts` for API usage.
- **React demo app**: See `examples/react/` for client usage (calls demo server).

## Tests
Test cases for the main utility are included in `src/sendgrid/index.test.ts`:

```typescript
import { sendEmail } from 'email-core-utility';
// ...see test file for details
```

## Security Notes
- **Never expose API keys in client-side code.** Always set secrets in server-side `.env` files or environment variables.
- The package enforces server-only guards for sensitive operations.

## Demo Applications

The package includes a complete demo setup with a beautiful, modern UI:

### 🎨 Beautiful React Frontend (`examples/react/`)
- **Modern Design**: Glassmorphism UI with gradient backgrounds and smooth animations
- **Responsive Layout**: Works perfectly on desktop and mobile devices
- **Real-time Status**: Loading states, success/error feedback with animated icons
- **Smart Validation**: Email validation and disabled states for better UX
- **Accessibility**: Proper ARIA labels and keyboard navigation

### 🚀 Express Backend (`examples/demo/`)
- **CORS Enabled**: Secure cross-origin requests between frontend/backend
- **Health Check**: `/health` endpoint for monitoring
- **Email Endpoints**: `/send/raw` and `/send/template` for different email types
- **Error Handling**: Comprehensive error responses and logging

### ⚡ Optimized SendGrid Settings
- **Instant Delivery**: Optimized mail settings for fastest delivery
- **Single Bypass**: Uses `bypassListManagement` to avoid SendGrid conflicts
- **Production Ready**: Sandbox mode disabled, tracking enabled

### Running the Demo
1. Set up your SendGrid API key in `examples/demo/.env`
2. Start the Express server: `cd examples/demo && npx tsx server.ts`
3. Start the React app: `cd examples/react && npm run dev`
4. Open http://localhost:5174 to see the beautiful interface
5. Send test emails using the elegant form interface

## Development
- Clone the repo and run `npm install` in the root and example folders
- Use `.env.example` files to set up local secrets (never commit real keys)
- Run tests with `npm test` (98%+ coverage achieved!)
- Check coverage reports in `coverage/lcov-report/index.html`

## Performance & Delivery
- **Fast Delivery**: Emails typically deliver within seconds using optimized settings
- **High Deliverability**: Uses verified sender domains and proper headers
- **Error Recovery**: Robust error handling with detailed error messages

## License
MIT