UNPKG

waitlist-mailer

Version:

Modern, modular TypeScript library for managing waitlists with pluggable storage and mail providers. Supports MongoDB, SQL databases, and custom adapters with zero required dependencies for basic usage.

144 lines (142 loc) 4.74 kB
/** * @fileoverview Core types and interfaces for the waitlist-mailer library. * Defines contracts for storage providers, mail providers, and data structures. */ /** * Represents a single entry in the waitlist. * @template T - Optional metadata type for custom fields */ interface WaitlistEntry<T = any> { /** Email address */ email: string; /** Custom metadata (e.g., name, referral source, etc.) */ metadata?: T; /** Entry creation timestamp */ createdAt: Date; } /** * Result of a join operation. */ interface JoinResult { success: boolean; message: string; email?: string; } /** * Storage provider interface that must be implemented by all storage adapters. * Allows pluggable backends (memory, MongoDB, PostgreSQL, MySQL, etc.) * @template T - Optional metadata type for custom fields */ interface StorageProvider<T = any> { /** * Optional lifecycle hook: connect to the storage backend. * Called during initialization if provided. */ connect?(): Promise<void>; /** * Add an email to storage with optional metadata. * @param email - The email address to add * @param data - Optional custom metadata * @throws {Error} If email already exists or storage fails */ add(email: string, data?: T): Promise<void>; /** * Remove an email from storage. * @param email - The email address to remove * @returns true if the email was found and removed, false otherwise */ remove(email: string): Promise<boolean>; /** * Check if an email exists in storage. * @param email - The email address to check * @returns true if the email exists, false otherwise */ exists(email: string): Promise<boolean>; /** * Retrieve all entries from storage. * @returns Array of WaitlistEntry objects */ getAll(): Promise<WaitlistEntry<T>[]>; /** * Search entries by email pattern. * Delegates filtering to the storage layer for efficiency. * @param pattern - The pattern to search for (partial email match) * @param options - Optional search options * @returns Array of matching WaitlistEntry objects */ search?(pattern: string, options?: SearchOptions): Promise<WaitlistEntry<T>[]>; /** * Iterate over entries using a cursor/stream pattern. * Useful for processing large datasets without loading everything into memory. * @param batchSize - Number of entries to fetch per batch * @returns AsyncIterableIterator for streaming entries */ iterate?(batchSize?: number): AsyncIterableIterator<WaitlistEntry<T>>; /** * Count total entries in storage. */ count(): Promise<number>; /** * Clear all entries from storage. */ clear(): Promise<void>; /** * Optional lifecycle hook: disconnect from the storage backend. * Called during cleanup if provided. */ disconnect?(): Promise<void>; } /** * Mail provider interface that must be implemented by all mail adapters. * Allows pluggable mail backends (Nodemailer, SendGrid, Mailgun, etc.) */ interface MailProvider { /** * Send a confirmation email to the specified address. * @param email - The recipient email address * @param context - Context object with template variables * @returns true if the email was sent successfully, false otherwise */ sendConfirmation(email: string, context: Record<string, any>): Promise<boolean>; /** * Optional lifecycle hook: verify mail provider configuration. */ verify?(): Promise<boolean>; } /** * Configuration options for WaitlistManager. * @template T - Optional metadata type for custom fields */ interface WaitlistManagerConfig<T = any> { /** * Storage provider instance. * Defaults to MemoryStorage if not provided. */ storage?: StorageProvider<T>; /** Optional mail provider instance */ mailer?: MailProvider; /** Optional company name for email context */ companyName?: string; /** Enable automatic initialization on construction */ autoConnect?: boolean; } /** * Email sending context passed to mail providers. */ interface EmailContext { email: string; companyName?: string; customUrl?: string; [key: string]: any; } /** * Options for search operations. */ interface SearchOptions { /** Maximum number of results to return */ limit?: number; /** Number of results to skip (for pagination) */ offset?: number; /** Whether to use case-insensitive matching (default: true) */ caseInsensitive?: boolean; } export type { EmailContext, JoinResult, MailProvider, SearchOptions, StorageProvider, WaitlistEntry, WaitlistManagerConfig };