UNPKG

payload-plugin-newsletter

Version:

Complete newsletter management plugin for Payload CMS with subscriber management, magic link authentication, and email service integration

1 lines 322 kB
{"version":3,"sources":["../src/types/newsletter.ts","../src/types/broadcast.ts","../src/types/channel.ts","../src/types/providers.ts","../src/types/index.ts","../src/providers/broadcast/broadcast.ts","../src/providers/resend/broadcast.ts","../src/index.ts","../src/utils/access.ts","../src/emails/render.tsx","../src/emails/MagicLink.tsx","../src/emails/styles.ts","../src/emails/Welcome.tsx","../src/emails/SignIn.tsx","../src/collections/Subscribers.ts","../src/globals/NewsletterSettings.ts","../src/providers/resend.ts","../src/providers/types.ts","../src/providers/broadcast.ts","../src/providers/index.ts","../src/utils/validation.ts","../src/utils/jwt.ts","../src/endpoints/subscribe.ts","../src/endpoints/verify-magic-link.ts","../src/endpoints/preferences.ts","../src/endpoints/unsubscribe.ts","../src/utils/rate-limiter.ts","../src/endpoints/signin.ts","../src/endpoints/me.ts","../src/endpoints/signout.ts","../src/endpoints/broadcasts/send.ts","../src/utils/auth.ts","../src/endpoints/broadcasts/schedule.ts","../src/utils/emailSafeHtml.ts","../src/endpoints/broadcasts/test.ts","../src/endpoints/broadcasts/index.ts","../src/endpoints/index.ts","../src/fields/newsletterScheduling.ts","../src/jobs/sync-unsubscribes.ts","../src/collections/Channels.ts","../src/collections/Broadcasts.ts","../src/fields/emailContent.ts","../src/utilities/session.ts"],"sourcesContent":["/**\n * Core types for newsletter management functionality\n */\n\n/**\n * Represents a newsletter/broadcast in the system\n */\nexport interface Newsletter {\n  id: string;\n  name: string;\n  subject: string;\n  preheader?: string;\n  content: string; // HTML content\n  status: NewsletterStatus;\n  trackOpens: boolean;\n  trackClicks: boolean;\n  replyTo?: string;\n  recipientCount?: number;\n  sentAt?: Date;\n  scheduledAt?: Date;\n  createdAt: Date;\n  updatedAt: Date;\n  // Provider-specific data stored here\n  providerData?: Record<string, any>;\n  // Provider information\n  providerId?: string;\n  providerType?: 'broadcast' | 'resend';\n}\n\n/**\n * Possible statuses for a newsletter\n */\nexport enum NewsletterStatus {\n  DRAFT = 'draft',\n  SCHEDULED = 'scheduled',\n  SENDING = 'sending',\n  SENT = 'sent',\n  FAILED = 'failed',\n  PAUSED = 'paused',\n  CANCELED = 'canceled'\n}\n\n/**\n * Options for listing newsletters\n */\nexport interface ListNewsletterOptions {\n  limit?: number;\n  offset?: number;\n  status?: NewsletterStatus;\n  sortBy?: 'createdAt' | 'updatedAt' | 'sentAt' | 'name';\n  sortOrder?: 'asc' | 'desc';\n}\n\n/**\n * Response from listing newsletters\n */\nexport interface ListNewsletterResponse<T = Newsletter> {\n  items: T[];\n  total: number;\n  limit: number;\n  offset: number;\n  hasMore: boolean;\n}\n\n/**\n * Input for creating a new newsletter\n */\nexport interface CreateNewsletterInput {\n  name: string;\n  subject: string;\n  preheader?: string;\n  content: string;\n  trackOpens?: boolean;\n  trackClicks?: boolean;\n  replyTo?: string;\n  audienceIds?: string[]; // Maps to segments/audiences\n}\n\n/**\n * Input for updating an existing newsletter\n */\nexport interface UpdateNewsletterInput {\n  name?: string;\n  subject?: string;\n  preheader?: string;\n  content?: string;\n  trackOpens?: boolean;\n  trackClicks?: boolean;\n  replyTo?: string;\n  audienceIds?: string[];\n}\n\n/**\n * Options for sending a newsletter\n */\nexport interface SendNewsletterOptions {\n  audienceIds?: string[]; // Target specific audiences\n  testMode?: boolean; // Send test email\n  testRecipients?: string[]; // Email addresses for test send\n}\n\n/**\n * Analytics data for a newsletter\n */\nexport interface NewsletterAnalytics {\n  sent: number;\n  delivered: number;\n  opened: number;\n  clicked: number;\n  bounced: number;\n  complained: number;\n  unsubscribed: number;\n  deliveryRate?: number;\n  openRate?: number;\n  clickRate?: number;\n  bounceRate?: number;\n}\n\n/**\n * Capabilities that a newsletter provider supports\n */\nexport interface NewsletterProviderCapabilities {\n  supportsScheduling: boolean;\n  supportsSegmentation: boolean;\n  supportsAnalytics: boolean;\n  supportsABTesting: boolean;\n  supportsTemplates: boolean;\n  supportsPersonalization: boolean;\n  maxRecipientsPerSend?: number;\n  editableStatuses: NewsletterStatus[];\n  supportedContentTypes: ('html' | 'text' | 'react')[];\n}\n\n/**\n * Error types specific to newsletter operations\n */\nexport class NewsletterProviderError extends Error {\n  constructor(\n    message: string,\n    public code: NewsletterErrorCode,\n    public provider: string,\n    public details?: any\n  ) {\n    super(message);\n    this.name = 'NewsletterProviderError';\n  }\n}\n\nexport enum NewsletterErrorCode {\n  NOT_SUPPORTED = 'NOT_SUPPORTED',\n  INVALID_STATUS = 'INVALID_STATUS',\n  PROVIDER_ERROR = 'PROVIDER_ERROR',\n  VALIDATION_ERROR = 'VALIDATION_ERROR',\n  NOT_FOUND = 'NOT_FOUND',\n  PERMISSION_DENIED = 'PERMISSION_DENIED',\n  RATE_LIMITED = 'RATE_LIMITED',\n  CONFIGURATION_ERROR = 'CONFIGURATION_ERROR'\n}\n\n/**\n * Newsletter template for reusable content\n */\nexport interface NewsletterTemplate {\n  id: string;\n  name: string;\n  description?: string;\n  content: string;\n  variables?: NewsletterTemplateVariable[];\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface NewsletterTemplateVariable {\n  name: string;\n  type: 'text' | 'html' | 'image' | 'url';\n  defaultValue?: string;\n  required?: boolean;\n}","/**\n * Core types for broadcast management functionality\n */\n\n/**\n * Represents a broadcast (individual email campaign) in the system\n */\nexport interface Broadcast {\n  id: string;\n  channelId: string; // Reference to the channel this broadcast belongs to\n  name: string;\n  subject: string;\n  preheader?: string;\n  content: string; // HTML content\n  status: BroadcastStatus;\n  trackOpens: boolean;\n  trackClicks: boolean;\n  replyTo?: string;\n  recipientCount?: number;\n  sentAt?: Date;\n  scheduledAt?: Date;\n  createdAt: Date;\n  updatedAt: Date;\n  // Provider-specific data stored here\n  providerData?: Record<string, any>;\n  // Provider information\n  providerId?: string;\n  providerType?: 'broadcast' | 'resend';\n}\n\n/**\n * Possible statuses for a broadcast\n */\nexport enum BroadcastStatus {\n  DRAFT = 'draft',\n  SCHEDULED = 'scheduled',\n  SENDING = 'sending',\n  SENT = 'sent',\n  FAILED = 'failed',\n  PAUSED = 'paused',\n  CANCELED = 'canceled'\n}\n\n/**\n * Options for listing broadcasts\n */\nexport interface ListBroadcastOptions {\n  limit?: number;\n  offset?: number;\n  status?: BroadcastStatus;\n  channelId?: string; // Filter by channel\n  sortBy?: 'createdAt' | 'updatedAt' | 'sentAt' | 'name';\n  sortOrder?: 'asc' | 'desc';\n}\n\n/**\n * Response from listing broadcasts\n */\nexport interface ListBroadcastResponse<T = Broadcast> {\n  items: T[];\n  total: number;\n  limit: number;\n  offset: number;\n  hasMore: boolean;\n}\n\n/**\n * Input for creating a new broadcast\n */\nexport interface CreateBroadcastInput {\n  channelId: string; // Which channel to send to\n  name: string;\n  subject: string;\n  preheader?: string;\n  content: string;\n  trackOpens?: boolean;\n  trackClicks?: boolean;\n  replyTo?: string;\n  audienceIds?: string[]; // Maps to segments/audiences within the channel\n}\n\n/**\n * Input for updating an existing broadcast\n */\nexport interface UpdateBroadcastInput {\n  name?: string;\n  subject?: string;\n  preheader?: string;\n  content?: string;\n  trackOpens?: boolean;\n  trackClicks?: boolean;\n  replyTo?: string;\n  audienceIds?: string[];\n}\n\n/**\n * Options for sending a broadcast\n */\nexport interface SendBroadcastOptions {\n  audienceIds?: string[]; // Target specific audiences within the channel\n  testMode?: boolean; // Send test email\n  testRecipients?: string[]; // Email addresses for test send\n}\n\n/**\n * Analytics data for a broadcast\n */\nexport interface BroadcastAnalytics {\n  sent: number;\n  delivered: number;\n  opened: number;\n  clicked: number;\n  bounced: number;\n  complained: number;\n  unsubscribed: number;\n  deliveryRate?: number;\n  openRate?: number;\n  clickRate?: number;\n  bounceRate?: number;\n}\n\n/**\n * Capabilities that a broadcast provider supports\n */\nexport interface BroadcastProviderCapabilities {\n  supportsScheduling: boolean;\n  supportsSegmentation: boolean;\n  supportsAnalytics: boolean;\n  supportsABTesting: boolean;\n  supportsTemplates: boolean;\n  supportsPersonalization: boolean;\n  maxRecipientsPerSend?: number;\n  editableStatuses: BroadcastStatus[];\n  supportedContentTypes: ('html' | 'text' | 'react')[];\n  // Channel-specific capabilities\n  supportsMultipleChannels: boolean;\n  supportsChannelSegmentation: boolean;\n}\n\n/**\n * Error types specific to broadcast operations\n */\nexport class BroadcastProviderError extends Error {\n  constructor(\n    message: string,\n    public code: BroadcastErrorCode,\n    public provider: string,\n    public details?: any\n  ) {\n    super(message);\n    this.name = 'BroadcastProviderError';\n  }\n}\n\nexport enum BroadcastErrorCode {\n  NOT_SUPPORTED = 'NOT_SUPPORTED',\n  INVALID_STATUS = 'INVALID_STATUS',\n  PROVIDER_ERROR = 'PROVIDER_ERROR',\n  VALIDATION_ERROR = 'VALIDATION_ERROR',\n  NOT_FOUND = 'NOT_FOUND',\n  PERMISSION_DENIED = 'PERMISSION_DENIED',\n  RATE_LIMITED = 'RATE_LIMITED',\n  CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',\n  CHANNEL_NOT_FOUND = 'CHANNEL_NOT_FOUND',\n  INVALID_CHANNEL = 'INVALID_CHANNEL'\n}\n\n/**\n * Broadcast template for reusable content\n */\nexport interface BroadcastTemplate {\n  id: string;\n  channelId?: string; // Optional channel-specific template\n  name: string;\n  description?: string;\n  content: string;\n  variables?: BroadcastTemplateVariable[];\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface BroadcastTemplateVariable {\n  name: string;\n  type: 'text' | 'html' | 'image' | 'url';\n  defaultValue?: string;\n  required?: boolean;\n}\n\n// Re-export newsletter types with deprecation notice for backwards compatibility\nexport {\n  NewsletterStatus,\n  type ListNewsletterOptions,\n  type ListNewsletterResponse,\n  type CreateNewsletterInput,\n  type UpdateNewsletterInput,\n  type SendNewsletterOptions,\n  type NewsletterAnalytics,\n  type NewsletterProviderCapabilities,\n  NewsletterProviderError,\n  NewsletterErrorCode,\n  type NewsletterTemplate,\n  type NewsletterTemplateVariable\n} from './newsletter';","export interface Channel {\n  id: string;\n  name: string;\n  description?: string;\n  fromName: string;\n  fromEmail: string;\n  replyTo?: string;\n  providerId: string;\n  providerType: 'broadcast' | 'resend';\n  subscriberCount?: number;\n  active: boolean;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface CreateChannelInput {\n  name: string;\n  description?: string;\n  fromName: string;\n  fromEmail: string;\n  replyTo?: string;\n}\n\nexport interface UpdateChannelInput {\n  name?: string;\n  description?: string;\n  fromName?: string;\n  fromEmail?: string;\n  replyTo?: string;\n  active?: boolean;\n}\n\nexport interface ListChannelsOptions {\n  limit?: number;\n  offset?: number;\n  active?: boolean;\n}\n\nexport interface ListChannelsResponse {\n  channels: Channel[];\n  total: number;\n  limit: number;\n  offset: number;\n}","/**\n * Provider interfaces for broadcast management\n */\n\n// Import broadcast types\nimport type {\n  Broadcast,\n  BroadcastStatus,\n  ListBroadcastOptions,\n  ListBroadcastResponse,\n  CreateBroadcastInput,\n  UpdateBroadcastInput,\n  SendBroadcastOptions,\n  BroadcastAnalytics,\n  BroadcastProviderCapabilities\n} from './broadcast'\n\nimport {\n  BroadcastProviderError,\n  BroadcastErrorCode\n} from './broadcast'\n\n// Import channel types\nimport type {\n  Channel,\n  CreateChannelInput,\n  UpdateChannelInput,\n  ListChannelsOptions,\n  ListChannelsResponse\n} from './channel'\n\n// Import legacy newsletter types for backwards compatibility\nimport type {\n  Newsletter,\n  NewsletterStatus,\n  ListNewsletterOptions,\n  ListNewsletterResponse,\n  CreateNewsletterInput,\n  UpdateNewsletterInput,\n  SendNewsletterOptions,\n  NewsletterAnalytics,\n  NewsletterProviderCapabilities\n} from './newsletter'\n\nimport {\n  NewsletterProviderError,\n  NewsletterErrorCode\n} from './newsletter'\n\n/**\n * Main interface for broadcast providers\n */\nexport interface BroadcastProvider {\n  /**\n   * Get the provider name\n   */\n  readonly name: string;\n\n  // Channel management methods\n  /**\n   * List channels (newsletter types/publications)\n   */\n  listChannels(options?: ListChannelsOptions): Promise<ListChannelsResponse>;\n  \n  /**\n   * Get a specific channel by ID\n   */\n  getChannel(id: string): Promise<Channel>;\n  \n  /**\n   * Create a new channel\n   */\n  createChannel(data: CreateChannelInput): Promise<Channel>;\n  \n  /**\n   * Update an existing channel\n   */\n  updateChannel(id: string, data: UpdateChannelInput): Promise<Channel>;\n  \n  /**\n   * Delete a channel\n   */\n  deleteChannel(id: string): Promise<void>;\n\n  // Broadcast management methods\n  /**\n   * List broadcasts with pagination\n   */\n  list(options?: ListBroadcastOptions): Promise<ListBroadcastResponse<Broadcast>>;\n  \n  /**\n   * Get a specific broadcast by ID\n   */\n  get(id: string): Promise<Broadcast>;\n  \n  /**\n   * Create a new broadcast\n   */\n  create(data: CreateBroadcastInput): Promise<Broadcast>;\n  \n  /**\n   * Update an existing broadcast\n   */\n  update(id: string, data: UpdateBroadcastInput): Promise<Broadcast>;\n  \n  /**\n   * Delete a broadcast\n   */\n  delete(id: string): Promise<void>;\n  \n  /**\n   * Send a broadcast immediately or to test recipients\n   */\n  send(id: string, options?: SendBroadcastOptions): Promise<Broadcast>;\n  \n  /**\n   * Schedule a broadcast for future sending\n   */\n  schedule(id: string, scheduledAt: Date): Promise<Broadcast>;\n  \n  /**\n   * Cancel a scheduled broadcast\n   */\n  cancelSchedule(id: string): Promise<Broadcast>;\n  \n  /**\n   * Get analytics for a broadcast\n   */\n  getAnalytics(id: string): Promise<BroadcastAnalytics>;\n  \n  /**\n   * Get provider capabilities\n   */\n  getCapabilities(): BroadcastProviderCapabilities;\n  \n  /**\n   * Validate that the provider is properly configured\n   */\n  validateConfiguration(): Promise<boolean>;\n}\n\n/**\n * Legacy newsletter provider interface for backwards compatibility\n * @deprecated Use BroadcastProvider instead\n */\nexport interface NewsletterProvider {\n  /**\n   * Get the provider name\n   */\n  readonly name: string;\n\n  /**\n   * List newsletters with pagination\n   */\n  list(options?: ListNewsletterOptions): Promise<ListNewsletterResponse<Newsletter>>;\n  \n  /**\n   * Get a specific newsletter by ID\n   */\n  get(id: string): Promise<Newsletter>;\n  \n  /**\n   * Create a new newsletter\n   */\n  create(data: CreateNewsletterInput): Promise<Newsletter>;\n  \n  /**\n   * Update an existing newsletter\n   */\n  update(id: string, data: UpdateNewsletterInput): Promise<Newsletter>;\n  \n  /**\n   * Delete a newsletter\n   */\n  delete(id: string): Promise<void>;\n  \n  /**\n   * Send a newsletter immediately or to test recipients\n   */\n  send(id: string, options?: SendNewsletterOptions): Promise<Newsletter>;\n  \n  /**\n   * Schedule a newsletter for future sending\n   */\n  schedule(id: string, scheduledAt: Date): Promise<Newsletter>;\n  \n  /**\n   * Cancel a scheduled newsletter\n   */\n  cancelSchedule(id: string): Promise<Newsletter>;\n  \n  /**\n   * Get analytics for a newsletter\n   */\n  getAnalytics(id: string): Promise<NewsletterAnalytics>;\n  \n  /**\n   * Get provider capabilities\n   */\n  getCapabilities(): NewsletterProviderCapabilities;\n  \n  /**\n   * Validate that the provider is properly configured\n   */\n  validateConfiguration(): Promise<boolean>;\n}\n\n/**\n * Base abstract class for broadcast providers\n */\nexport abstract class BaseBroadcastProvider implements BroadcastProvider {\n  abstract readonly name: string;\n  \n  constructor(protected config: any) {}\n  \n  // Channel management - abstract methods\n  abstract listChannels(options?: ListChannelsOptions): Promise<ListChannelsResponse>;\n  abstract getChannel(id: string): Promise<Channel>;\n  abstract createChannel(data: CreateChannelInput): Promise<Channel>;\n  abstract updateChannel(id: string, data: UpdateChannelInput): Promise<Channel>;\n  abstract deleteChannel(id: string): Promise<void>;\n  \n  // Broadcast management - abstract methods\n  abstract list(options?: ListBroadcastOptions): Promise<ListBroadcastResponse<Broadcast>>;\n  abstract get(id: string): Promise<Broadcast>;\n  abstract create(data: CreateBroadcastInput): Promise<Broadcast>;\n  abstract update(id: string, data: UpdateBroadcastInput): Promise<Broadcast>;\n  abstract delete(id: string): Promise<void>;\n  abstract send(id: string, options?: SendBroadcastOptions): Promise<Broadcast>;\n  abstract getCapabilities(): BroadcastProviderCapabilities;\n  abstract validateConfiguration(): Promise<boolean>;\n  \n  /**\n   * Schedule a broadcast - default implementation throws not supported\n   */\n  async schedule(_id: string, _scheduledAt: Date): Promise<Broadcast> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsScheduling) {\n      throw new BroadcastProviderError(\n        'Scheduling is not supported by this provider',\n        BroadcastErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    throw new Error('Method not implemented');\n  }\n  \n  /**\n   * Cancel scheduled broadcast - default implementation throws not supported\n   */\n  async cancelSchedule(_id: string): Promise<Broadcast> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsScheduling) {\n      throw new BroadcastProviderError(\n        'Scheduling is not supported by this provider',\n        BroadcastErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    throw new Error('Method not implemented');\n  }\n  \n  /**\n   * Get analytics - default implementation returns zeros\n   */\n  async getAnalytics(_id: string): Promise<BroadcastAnalytics> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsAnalytics) {\n      throw new BroadcastProviderError(\n        'Analytics are not supported by this provider',\n        BroadcastErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    \n    return {\n      sent: 0,\n      delivered: 0,\n      opened: 0,\n      clicked: 0,\n      bounced: 0,\n      complained: 0,\n      unsubscribed: 0\n    };\n  }\n  \n  /**\n   * Helper method to validate required fields\n   */\n  protected validateRequiredFields(data: any, fields: string[]): void {\n    const missing = fields.filter(field => !data[field]);\n    if (missing.length > 0) {\n      throw new BroadcastProviderError(\n        `Missing required fields: ${missing.join(', ')}`,\n        BroadcastErrorCode.VALIDATION_ERROR,\n        this.name\n      );\n    }\n  }\n  \n  /**\n   * Helper method to check if a status transition is allowed\n   */\n  protected canEditInStatus(status: BroadcastStatus): boolean {\n    const capabilities = this.getCapabilities();\n    return capabilities.editableStatuses.includes(status);\n  }\n  \n  /**\n   * Helper to build pagination response\n   */\n  protected buildListResponse<T>(\n    items: T[],\n    total: number,\n    options: ListBroadcastOptions = {}\n  ): ListBroadcastResponse<T> {\n    const limit = options.limit || 20;\n    const offset = options.offset || 0;\n    \n    return {\n      items,\n      total,\n      limit,\n      offset,\n      hasMore: offset + items.length < total\n    };\n  }\n}\n\n/**\n * Base abstract class for newsletter providers\n * @deprecated Use BaseBroadcastProvider instead\n */\nexport abstract class BaseNewsletterProvider implements NewsletterProvider {\n  abstract readonly name: string;\n  \n  constructor(protected config: any) {}\n  \n  abstract list(options?: ListNewsletterOptions): Promise<ListNewsletterResponse<Newsletter>>;\n  abstract get(id: string): Promise<Newsletter>;\n  abstract create(data: CreateNewsletterInput): Promise<Newsletter>;\n  abstract update(id: string, data: UpdateNewsletterInput): Promise<Newsletter>;\n  abstract delete(id: string): Promise<void>;\n  abstract send(id: string, options?: SendNewsletterOptions): Promise<Newsletter>;\n  abstract getCapabilities(): NewsletterProviderCapabilities;\n  abstract validateConfiguration(): Promise<boolean>;\n  \n  /**\n   * Schedule a newsletter - default implementation throws not supported\n   */\n  async schedule(_id: string, _scheduledAt: Date): Promise<Newsletter> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsScheduling) {\n      throw new NewsletterProviderError(\n        'Scheduling is not supported by this provider',\n        NewsletterErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    throw new Error('Method not implemented');\n  }\n  \n  /**\n   * Cancel scheduled newsletter - default implementation throws not supported\n   */\n  async cancelSchedule(_id: string): Promise<Newsletter> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsScheduling) {\n      throw new NewsletterProviderError(\n        'Scheduling is not supported by this provider',\n        NewsletterErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    throw new Error('Method not implemented');\n  }\n  \n  /**\n   * Get analytics - default implementation returns zeros\n   */\n  async getAnalytics(_id: string): Promise<NewsletterAnalytics> {\n    const capabilities = this.getCapabilities();\n    if (!capabilities.supportsAnalytics) {\n      throw new NewsletterProviderError(\n        'Analytics are not supported by this provider',\n        NewsletterErrorCode.NOT_SUPPORTED,\n        this.name\n      );\n    }\n    \n    return {\n      sent: 0,\n      delivered: 0,\n      opened: 0,\n      clicked: 0,\n      bounced: 0,\n      complained: 0,\n      unsubscribed: 0\n    };\n  }\n  \n  /**\n   * Helper method to validate required fields\n   */\n  protected validateRequiredFields(data: any, fields: string[]): void {\n    const missing = fields.filter(field => !data[field]);\n    if (missing.length > 0) {\n      throw new NewsletterProviderError(\n        `Missing required fields: ${missing.join(', ')}`,\n        NewsletterErrorCode.VALIDATION_ERROR,\n        this.name\n      );\n    }\n  }\n  \n  /**\n   * Helper method to check if a status transition is allowed\n   */\n  protected canEditInStatus(status: NewsletterStatus): boolean {\n    const capabilities = this.getCapabilities();\n    return capabilities.editableStatuses.includes(status);\n  }\n  \n  /**\n   * Helper to build pagination response\n   */\n  protected buildListResponse<T>(\n    items: T[],\n    total: number,\n    options: ListNewsletterOptions = {}\n  ): ListNewsletterResponse<T> {\n    const limit = options.limit || 20;\n    const offset = options.offset || 0;\n    \n    return {\n      items,\n      total,\n      limit,\n      offset,\n      hasMore: offset + items.length < total\n    };\n  }\n}","import type { Field } from 'payload'\nimport type { BroadcastProvider } from './providers'\n\n// Export broadcast and channel types\nexport * from './broadcast'\nexport * from './channel'\nexport * from './providers'\n// Export legacy newsletter types for backwards compatibility\nexport * from './newsletter'\n\nexport interface NewsletterPluginConfig {\n  /**\n   * Enable or disable the plugin\n   * @default true\n   */\n  enabled?: boolean\n\n  /**\n   * Slug for the subscribers collection\n   * @default 'subscribers'\n   */\n  subscribersSlug?: string\n  \n  /**\n   * Slug for the newsletter settings global\n   * @default 'newsletter-settings'\n   */\n  settingsSlug?: string\n\n  /**\n   * Authentication configuration for magic links\n   */\n  auth?: {\n    /**\n     * Enable magic link authentication\n     * @default true\n     */\n    enabled?: boolean\n    \n    /**\n     * Token expiration time\n     * @default '7d'\n     */\n    tokenExpiration?: string\n    \n    /**\n     * Path where magic link redirects\n     * @default '/newsletter/verify'\n     */\n    magicLinkPath?: string\n  }\n\n  /**\n   * Access control configuration\n   */\n  access?: {\n    /**\n     * Custom function to determine if a user is an admin\n     * @param user - The authenticated user object\n     * @returns true if the user should have admin access\n     */\n    isAdmin?: (user: any) => boolean\n  }\n\n  /**\n   * Email provider configuration\n   */\n  providers: {\n    /**\n     * Default provider to use\n     */\n    default: 'resend' | 'broadcast' | string\n    \n    /**\n     * Resend provider configuration\n     */\n    resend?: ResendProviderConfig\n    \n    /**\n     * Broadcast provider configuration\n     */\n    broadcast?: BroadcastProviderConfig\n  }\n\n  /**\n   * Field customization options\n   */\n  fields?: {\n    /**\n     * Override default fields\n     */\n    overrides?: (args: { defaultFields: Field[] }) => Field[]\n    \n    /**\n     * Additional custom fields\n     */\n    additional?: Field[]\n  }\n\n  /**\n   * Email template components\n   */\n  templates?: {\n    /**\n     * Welcome email template\n     */\n    welcome?: React.ComponentType<WelcomeEmailProps>\n    \n    /**\n     * Magic link email template\n     */\n    magicLink?: React.ComponentType<MagicLinkEmailProps>\n  }\n\n  /**\n   * Plugin hooks\n   */\n  hooks?: {\n    beforeSubscribe?: (args: BeforeSubscribeArgs) => void | Promise<void>\n    afterSubscribe?: (args: AfterSubscribeArgs) => void | Promise<void>\n    beforeUnsubscribe?: (args: BeforeUnsubscribeArgs) => void | Promise<void>\n    afterUnsubscribe?: (args: AfterUnsubscribeArgs) => void | Promise<void>\n    afterUnsubscribeSync?: (args: AfterUnsubscribeSyncArgs) => void | Promise<void>\n  }\n\n  /**\n   * UI component overrides\n   */\n  components?: {\n    signupForm?: React.ComponentType<SignupFormProps>\n    preferencesForm?: React.ComponentType<PreferencesFormProps>\n  }\n\n  /**\n   * Feature flags\n   */\n  features?: {\n    /**\n     * Lead magnet configuration\n     */\n    leadMagnets?: {\n      enabled?: boolean\n      collection?: string\n    }\n    \n    /**\n     * Post-signup survey configuration\n     */\n    surveys?: {\n      enabled?: boolean\n      questions?: SurveyQuestion[]\n    }\n    \n    /**\n     * UTM tracking configuration\n     */\n    utmTracking?: {\n      enabled?: boolean\n      fields?: string[]\n    }\n    \n    /**\n     * Newsletter scheduling configuration\n     */\n    newsletterScheduling?: {\n      enabled?: boolean\n      /**\n       * Collections to add newsletter fields to\n       * Can be a string for single collection or array for multiple\n       * @example 'articles' or ['articles', 'posts', 'updates']\n       */\n      collections?: string | string[]\n      /**\n       * Field configuration\n       */\n      fields?: {\n        /**\n         * Group name for newsletter fields\n         * @default 'newsletterScheduling'\n         */\n        groupName?: string\n        /**\n         * Rich text field name to use for content\n         * @default 'content'\n         */\n        contentField?: string\n        /**\n         * Whether to create a markdown companion field\n         * @default true\n         */\n        createMarkdownField?: boolean\n      }\n    }\n    \n    /**\n     * Unsubscribe sync configuration\n     */\n    unsubscribeSync?: {\n      /**\n       * Enable sync of unsubscribes from email service to Payload\n       * @default false\n       */\n      enabled?: boolean\n      /**\n       * Cron schedule for sync job (e.g., '0 * * * *' for hourly)\n       * If not provided, job must be triggered manually\n       */\n      schedule?: string\n      /**\n       * Queue name for the sync job\n       * @default 'newsletter-sync'\n       */\n      queue?: string\n    }\n    \n    /**\n     * Newsletter management configuration\n     */\n    newsletterManagement?: {\n      /**\n       * Enable newsletter management features\n       * @default false\n       */\n      enabled?: boolean\n      /**\n       * Collection names for broadcast management\n       */\n      collections?: {\n        /**\n         * Channels collection slug\n         * @default 'channels'\n         */\n        channels?: string\n        /**\n         * Broadcasts collection slug\n         * @default 'broadcasts'\n         */\n        broadcasts?: string\n      }\n      /**\n       * Optional: Custom broadcast provider implementation\n       * If not provided, will use the default email provider\n       */\n      provider?: BroadcastProvider\n    }\n  }\n\n  /**\n   * Internationalization configuration\n   */\n  i18n?: {\n    defaultLocale?: string\n    locales?: string[]\n  }\n}\n\nexport interface ResendProviderConfig {\n  apiKey: string\n  fromEmail?: string\n  fromAddress?: string // Alias for fromEmail\n  fromName?: string\n  replyTo?: string\n  audienceIds?: {\n    [locale: string]: {\n      production?: string\n      development?: string\n    }\n  }\n}\n\nexport interface BroadcastProviderConfig {\n  apiUrl: string\n  tokens: {\n    production?: string\n    development?: string\n  }\n  fromEmail?: string\n  fromAddress?: string // Alias for fromEmail\n  fromName?: string\n  replyTo?: string\n}\n\nexport interface EmailProvider {\n  send(params: SendEmailParams): Promise<void>\n  addContact(contact: Subscriber): Promise<void>\n  updateContact(contact: Subscriber): Promise<void>\n  removeContact(email: string): Promise<void>\n}\n\nexport interface SendEmailParams {\n  to: string | string[]\n  subject: string\n  html?: string\n  text?: string\n  react?: React.ReactElement\n}\n\nexport interface Subscriber {\n  id: string\n  email: string\n  name?: string\n  locale?: string\n  subscriptionStatus: 'active' | 'unsubscribed' | 'pending'\n  emailPreferences?: {\n    newsletter?: boolean\n    announcements?: boolean\n    [key: string]: boolean | undefined\n  }\n  source?: string\n  utmParameters?: {\n    source?: string\n    medium?: string\n    campaign?: string\n    content?: string\n    term?: string\n  }\n  // Additional fields that may exist in the database\n  signupMetadata?: {\n    ipAddress?: string\n    userAgent?: string\n    referrer?: string\n    signupPage?: string\n  }\n  leadMagnet?: string\n  unsubscribedAt?: string\n  magicLinkToken?: string\n  magicLinkTokenExpiry?: string\n  createdAt: string\n  updatedAt: string\n}\n\nexport interface WelcomeEmailProps {\n  subscriber: Subscriber\n  unsubscribeUrl: string\n  preferencesUrl: string\n}\n\nexport interface MagicLinkEmailProps {\n  magicLinkUrl: string\n  subscriber: Subscriber\n}\n\nexport interface SignupFormProps {\n  onSuccess?: (subscriber: Subscriber) => void\n  onError?: (error: Error) => void\n  showName?: boolean\n  showPreferences?: boolean\n  leadMagnet?: {\n    id: string\n    title: string\n    description?: string\n  }\n  className?: string\n  styles?: {\n    form?: React.CSSProperties\n    inputGroup?: React.CSSProperties\n    label?: React.CSSProperties\n    input?: React.CSSProperties\n    button?: React.CSSProperties\n    buttonDisabled?: React.CSSProperties\n    error?: React.CSSProperties\n    success?: React.CSSProperties\n    checkbox?: React.CSSProperties\n    checkboxInput?: React.CSSProperties\n    checkboxLabel?: React.CSSProperties\n  }\n  apiEndpoint?: string\n  buttonText?: string\n  loadingText?: string\n  successMessage?: string\n  placeholders?: {\n    email?: string\n    name?: string\n  }\n  labels?: {\n    email?: string\n    name?: string\n    newsletter?: string\n    announcements?: string\n  }\n}\n\nexport interface PreferencesFormProps {\n  subscriber?: Subscriber\n  onSuccess?: (subscriber: Subscriber) => void\n  onError?: (error: Error) => void\n  className?: string\n  styles?: {\n    container?: React.CSSProperties\n    heading?: React.CSSProperties\n    form?: React.CSSProperties\n    section?: React.CSSProperties\n    sectionTitle?: React.CSSProperties\n    inputGroup?: React.CSSProperties\n    label?: React.CSSProperties\n    input?: React.CSSProperties\n    select?: React.CSSProperties\n    checkbox?: React.CSSProperties\n    checkboxInput?: React.CSSProperties\n    checkboxLabel?: React.CSSProperties\n    buttonGroup?: React.CSSProperties\n    button?: React.CSSProperties\n    primaryButton?: React.CSSProperties\n    secondaryButton?: React.CSSProperties\n    dangerButton?: React.CSSProperties\n    error?: React.CSSProperties\n    success?: React.CSSProperties\n    info?: React.CSSProperties\n  }\n  sessionToken?: string\n  apiEndpoint?: string\n  showUnsubscribe?: boolean\n  locales?: string[]\n  labels?: {\n    title?: string\n    personalInfo?: string\n    emailPreferences?: string\n    name?: string\n    language?: string\n    newsletter?: string\n    announcements?: string\n    saveButton?: string\n    unsubscribeButton?: string\n    saving?: string\n    saved?: string\n    unsubscribeConfirm?: string\n  }\n}\n\nexport interface BeforeSubscribeArgs {\n  data: Partial<Subscriber>\n  req: any\n}\n\nexport interface AfterSubscribeArgs {\n  doc: Subscriber\n  req: any\n}\n\nexport interface BeforeUnsubscribeArgs {\n  email: string\n  req: any\n}\n\nexport interface AfterUnsubscribeArgs {\n  doc: Subscriber\n  req: any\n}\n\nexport interface AfterUnsubscribeSyncArgs {\n  req: any\n  syncedCount: number\n}\n\nexport interface SurveyQuestion {\n  id: string\n  question: string\n  type: 'text' | 'select' | 'multiselect' | 'radio'\n  options?: string[]\n  required?: boolean\n}\n\n// Request data interfaces for endpoints\nexport interface SubscribeRequestData {\n  email: string\n  name?: string\n  source?: string\n  preferences?: { [key: string]: boolean }\n  leadMagnet?: string\n  surveyResponses?: { [key: string]: string | string[] }\n  metadata?: {\n    locale?: string\n    signupPage?: string\n    [key: string]: unknown\n  }\n}\n\nexport interface UnsubscribeRequestData {\n  email?: string\n  token?: string\n}\n\nexport interface VerifyMagicLinkRequestData {\n  token: string\n}\n\nexport interface SigninRequestData {\n  email: string\n}\n\nexport interface UpdatePreferencesRequestData {\n  name?: string\n  locale?: string\n  emailPreferences?: { [key: string]: boolean }\n}\n\n// Extended request types with proper data typing\nexport interface ExtendedPayloadRequest extends Request {\n  payload: any // TODO: Add proper payload type\n  data?: unknown\n  ip?: string\n  connection?: {\n    remoteAddress?: string\n  }\n  cookies?: {\n    [key: string]: string\n  }\n  // Headers are inherited from Request, but we document common ones for reference\n  // Access via: req.headers.get('authorization'), req.headers.get('referer'), etc.\n}","import type { \n  Broadcast,\n  ListBroadcastOptions,\n  ListBroadcastResponse,\n  CreateBroadcastInput,\n  UpdateBroadcastInput,\n  SendBroadcastOptions,\n  BroadcastAnalytics,\n  BroadcastProviderCapabilities,\n  Channel,\n  CreateChannelInput,\n  UpdateChannelInput,\n  ListChannelsOptions,\n  ListChannelsResponse\n} from '../../types'\nimport { \n  BroadcastProviderError, \n  BroadcastErrorCode,\n  BroadcastStatus,\n  BaseBroadcastProvider\n} from '../../types'\nimport type { BroadcastProviderConfig } from '../../types'\n\ninterface BroadcastApiResponse {\n  id: number\n  name: string\n  subject: string\n  preheader?: string\n  body: string\n  status: string\n  track_opens: boolean\n  track_clicks: boolean\n  html_body: boolean\n  reply_to?: string\n  total_recipients: number\n  sent_at?: string\n  scheduled_send_at?: string\n  created_at: string\n  updated_at: string\n}\n\ninterface BroadcastListResponse {\n  data: BroadcastApiResponse[]\n  total: number\n}\n\n// Channel API interfaces\ninterface BroadcastChannelApiResponse {\n  id: number\n  name: string\n  description?: string\n  address: string\n  from: string\n  reply_to?: string\n  total_active_subscribers: number\n  created_at: string\n  updated_at: string\n}\n\nexport class BroadcastApiProvider extends BaseBroadcastProvider {\n  readonly name = 'broadcast'\n  private apiUrl: string\n  private token: string\n  private isDevelopment: boolean\n\n  constructor(config: BroadcastProviderConfig) {\n    super(config)\n    this.apiUrl = config.apiUrl.replace(/\\/$/, '') // Remove trailing slash\n    this.isDevelopment = process.env.NODE_ENV !== 'production'\n    this.token = this.isDevelopment \n      ? config.tokens.development || config.tokens.production || ''\n      : config.tokens.production || config.tokens.development || ''\n    \n    if (!this.token) {\n      throw new BroadcastProviderError(\n        'Broadcast API token is required',\n        BroadcastErrorCode.CONFIGURATION_ERROR,\n        this.name\n      )\n    }\n  }\n\n  // Channel Management Methods\n  async listChannels(options?: ListChannelsOptions): Promise<ListChannelsResponse> {\n    try {\n      const params = new URLSearchParams()\n      if (options?.limit) params.append('limit', options.limit.toString())\n      if (options?.offset) params.append('offset', options.offset.toString())\n\n      const response = await fetch(`${this.apiUrl}/api/v1/channels?${params}`, {\n        method: 'GET',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const data = await response.json()\n      const channels = data.data.map((channel: BroadcastChannelApiResponse) => this.transformChannelFromApi(channel))\n      \n      return {\n        channels,\n        total: data.total || channels.length,\n        limit: options?.limit || 20,\n        offset: options?.offset || 0\n      }\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to list channels: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async getChannel(id: string): Promise<Channel> {\n    try {\n      const response = await fetch(`${this.apiUrl}/api/v1/channels/${id}`, {\n        method: 'GET',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        if (response.status === 404) {\n          throw new BroadcastProviderError(\n            `Channel not found: ${id}`,\n            BroadcastErrorCode.CHANNEL_NOT_FOUND,\n            this.name\n          )\n        }\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const channel: BroadcastChannelApiResponse = await response.json()\n      return this.transformChannelFromApi(channel)\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to get channel: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async createChannel(data: CreateChannelInput): Promise<Channel> {\n    try {\n      const response = await fetch(`${this.apiUrl}/api/v1/channels`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          channel: {\n            name: data.name,\n            description: data.description,\n            from: data.fromName,\n            address: data.fromEmail,\n            reply_to: data.replyTo\n          }\n        })\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const channel: BroadcastChannelApiResponse = await response.json()\n      return this.transformChannelFromApi(channel)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to create channel: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async updateChannel(id: string, data: UpdateChannelInput): Promise<Channel> {\n    try {\n      const updateData: any = { channel: {} }\n      if (data.name !== undefined) updateData.channel.name = data.name\n      if (data.description !== undefined) updateData.channel.description = data.description\n      if (data.fromName !== undefined) updateData.channel.from = data.fromName\n      if (data.fromEmail !== undefined) updateData.channel.address = data.fromEmail\n      if (data.replyTo !== undefined) updateData.channel.reply_to = data.replyTo\n\n      const response = await fetch(`${this.apiUrl}/api/v1/channels/${id}`, {\n        method: 'PATCH',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify(updateData)\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const channel: BroadcastChannelApiResponse = await response.json()\n      return this.transformChannelFromApi(channel)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to update channel: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async deleteChannel(id: string): Promise<void> {\n    try {\n      const response = await fetch(`${this.apiUrl}/api/v1/channels/${id}`, {\n        method: 'DELETE',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to delete channel: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  // Broadcast Management Methods\n  async list(options?: ListBroadcastOptions): Promise<ListBroadcastResponse<Broadcast>> {\n    try {\n      const params = new URLSearchParams()\n      if (options?.limit) params.append('limit', options.limit.toString())\n      if (options?.offset) params.append('offset', options.offset.toString())\n\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts?${params}`, {\n        method: 'GET',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const data: BroadcastListResponse = await response.json()\n      \n      const broadcasts = data.data.map(broadcast => this.transformBroadcastFromApi(broadcast))\n      \n      return this.buildListResponse(broadcasts, data.total, options)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to list broadcasts: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async get(id: string): Promise<Broadcast> {\n    try {\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}`, {\n        method: 'GET',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        if (response.status === 404) {\n          throw new BroadcastProviderError(\n            `Broadcast not found: ${id}`,\n            BroadcastErrorCode.NOT_FOUND,\n            this.name\n          )\n        }\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const broadcast: BroadcastApiResponse = await response.json()\n      return this.transformBroadcastFromApi(broadcast)\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to get broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async create(data: CreateBroadcastInput): Promise<Broadcast> {\n    try {\n      this.validateRequiredFields(data, ['channelId', 'name', 'subject', 'content'])\n\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          broadcast: {\n            channel_id: parseInt(data.channelId), // Broadcast API uses numeric IDs\n            name: data.name,\n            subject: data.subject,\n            preheader: data.preheader,\n            body: data.content,\n            html_body: true,\n            track_opens: data.trackOpens ?? true,\n            track_clicks: data.trackClicks ?? true,\n            reply_to: data.replyTo,\n            segment_ids: data.audienceIds,\n          }\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const result = await response.json()\n      // Broadcast API returns just {id: 123}, so we need to fetch the full object\n      return this.get(result.id.toString())\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to create broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async update(id: string, data: UpdateBroadcastInput): Promise<Broadcast> {\n    try {\n      // First check if the broadcast can be edited\n      const existing = await this.get(id)\n      if (!this.canEditInStatus(existing.status)) {\n        throw new BroadcastProviderError(\n          `Cannot update broadcast in status: ${existing.status}`,\n          BroadcastErrorCode.INVALID_STATUS,\n          this.name\n        )\n      }\n\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}`, {\n        method: 'PATCH',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          broadcast: {\n            name: data.name,\n            subject: data.subject,\n            preheader: data.preheader,\n            body: data.content,\n            track_opens: data.trackOpens,\n            track_clicks: data.trackClicks,\n            reply_to: data.replyTo,\n            segment_ids: data.audienceIds,\n          }\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const broadcast: BroadcastApiResponse = await response.json()\n      return this.transformBroadcastFromApi(broadcast)\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to update broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async delete(id: string): Promise<void> {\n    try {\n      // First check if the broadcast can be deleted\n      const existing = await this.get(id)\n      if (!this.canEditInStatus(existing.status)) {\n        throw new BroadcastProviderError(\n          `Cannot delete broadcast in status: ${existing.status}`,\n          BroadcastErrorCode.INVALID_STATUS,\n          this.name\n        )\n      }\n\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}`, {\n        method: 'DELETE',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to delete broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async send(id: string, options?: SendBroadcastOptions): Promise<Broadcast> {\n    try {\n      // Check if we're in test mode\n      if (options?.testMode && options.testRecipients?.length) {\n        // TODO: Broadcast doesn't have a documented test send API\n        // For now, we'll throw an error\n        throw new BroadcastProviderError(\n          'Test send is not yet implemented for Broadcast provider',\n          BroadcastErrorCode.NOT_SUPPORTED,\n          this.name\n        )\n      }\n\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}/send_broadcast`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          segment_ids: options?.audienceIds\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      // Response includes updated status\n      const result = await response.json()\n      return this.get(result.id.toString())\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to send broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async schedule(id: string, scheduledAt: Date): Promise<Broadcast> {\n    try {\n      // Update the newsletter with scheduled time\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}`, {\n        method: 'PATCH',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          broadcast: {\n            scheduled_send_at: scheduledAt.toISOString(),\n            // TODO: Handle timezone properly\n            scheduled_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone\n          }\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const broadcast: BroadcastApiResponse = await response.json()\n      return this.transformBroadcastFromApi(broadcast)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to schedule broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async cancelSchedule(id: string): Promise<Broadcast> {\n    try {\n      // Clear the scheduled time\n      const response = await fetch(`${this.apiUrl}/api/v1/broadcasts/${id}`, {\n        method: 'PATCH',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          broadcast: {\n            scheduled_send_at: null,\n            scheduled_timezone: null\n          }\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n\n      const broadcast: BroadcastApiResponse = await response.json()\n      return this.transformBroadcastFromApi(broadcast)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to cancel scheduled broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async getAnalytics(_id: string): Promise<BroadcastAnalytics> {\n    // TODO: Broadcast analytics API is not documented in the CRUD API\n    // This would need additional API documentation\n    throw new BroadcastProviderError(\n      'Analytics API not yet implemented for Broadcast provider',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  getCapabilities(): BroadcastProviderCapabilities {\n    return {\n      supportsScheduling: true,\n      supportsSegmentation: true,\n      supportsAnalytics: false, // Not documented yet\n      supportsABTesting: false,\n      supportsTemplates: false,\n      supportsPersonalization: true,\n      supportsMultipleChannels: true,\n      supportsChannelSegmentation: true,\n      editableStatuses: [BroadcastStatus.DRAFT, BroadcastStatus.SCHEDULED],\n      supportedContentTypes: ['html', 'text']\n    }\n  }\n\n  async validateConfiguration(): Promise<boolean> {\n    try {\n      // Try to list broadcasts with limit 1 to validate API access\n      await this.list({ limit: 1 })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  private transformBroadcastFromApi(broadcast: BroadcastApiResponse): Broadcast {\n    // TODO: We need to get the channel_id from the broadcast API response\n    // For now, we'll use a placeholder\n    return {\n      id: broadcast.id.toString(),\n      channelId: '1', // TODO: Get from API response when available\n      name: broadcast.name,\n      subject: broadcast.subject,\n      preheader: broadcast.preheader,\n      content: broadcast.body,\n      status: this.mapBroadcastStatus(broadcast.status),\n      trackOpens: broadcast.track_opens,\n      trackClicks: broadcast.track_clicks,\n      replyTo: broadcast.reply_to,\n      recipientCount: broadcast.total_recipients,\n      sentAt: broadcast.sent_at ? new Date(broadcast.sent_at) : undefined,\n      scheduledAt: broadcast.scheduled_send_at ? new Date(broadcast.scheduled_send_at) : undefined,\n      createdAt: new Date(broadcast.created_at),\n      updatedAt: new Date(broadcast.updated_at),\n      providerData: { broadcast },\n      providerId: broadcast.id.toString(),\n      providerType: 'broadcast'\n    }\n  }\n  \n  private transformChannelFromApi(channel: BroadcastChannelApiResponse): Channel {\n    return {\n      id: channel.id.toString(),\n      name: channel.name,\n      description: channel.description,\n      fromName: channel.from,\n      fromEmail: channel.address,\n      replyTo: channel.reply_to,\n      providerId: channel.id.toString(),\n      providerType: 'broadcast',\n      subscriberCount: channel.total_active_subscribers,\n      active: true, // Broadcast API doesn't have an active field\n      createdAt: new Date(channel.created_at),\n      updatedAt: new Date(channel.updated_at)\n    }\n  }\n\n  private mapBroadcastStatus(status: string): BroadcastStatus {\n    const statusMap: Record<string, BroadcastStatus> = {\n      'draft': BroadcastStatus.DRAFT,\n      'scheduled': BroadcastStatus.SCHEDULED,\n      'queueing': BroadcastStatus.SENDING,\n      'sending': BroadcastStatus.SENDING,\n      'sent': BroadcastStatus.SENT,\n      'failed': BroadcastStatus.FAILED,\n      'partial_failure': BroadcastStatus.FAILED,\n      'paused': BroadcastStatus.PAUSED,\n      'aborted': BroadcastStatus.CANCELED\n    }\n    return statusMap[status] || BroadcastStatus.DRAFT\n  }\n}","import { Resend } from 'resend'\nimport type { \n  Broadcast,\n  ListBroadcastOptions,\n  ListBroadcastResponse,\n  CreateBroadcastInput,\n  UpdateBroadcastInput,\n  SendBroadcastOptions,\n  BroadcastAnalytics,\n  BroadcastProviderCapabilities,\n  Channel,\n  CreateChannelInput,\n  UpdateChannelInput,\n  ListChannelsOptions,\n  ListChannelsResponse\n} from '../../types'\nimport { \n  BroadcastProviderError, \n  BroadcastErrorCode,\n  BroadcastStatus,\n  BaseBroadcastProvider\n} from '../../types'\nimport type { ResendProviderConfig } from '../../types'\n\n/**\n * Resend Broadcast Provider\n * \n * IMPORTANT LIMITATIONS:\n * - Resend's Broadcast API is not fully documented publicly\n * - Many operations may not be available via API\n * - Broadcasts created via API can only be edited via API (not in dashboard)\n * - Channel management maps to Resend's Audience API\n * - Some methods below are marked as TODO pending official API documentation\n */\nexport class ResendBroadcastProvider extends BaseBroadcastProvider {\n  readonly name = 'resend'\n  private client: Resend\n  private audienceIds: ResendProviderConfig['audienceIds']\n  private isDevelopment: boolean\n\n  constructor(config: ResendProviderConfig) {\n    super(config)\n    this.client = new Resend(config.apiKey)\n    this.audienceIds = config.audienceIds || {}\n    this.isDevelopment = process.env.NODE_ENV !== 'production'\n    \n    if (!config.apiKey) {\n      throw new BroadcastProviderError(\n        'Resend API key is required',\n        BroadcastErrorCode.CONFIGURATION_ERROR,\n        this.name\n      )\n    }\n  }\n\n  // Channel Management Methods (map to Resend Audiences)\n  async listChannels(options?: ListChannelsOptions): Promise<ListChannelsResponse> {\n    try {\n      // Resend audiences API\n      const response = await this.client.audiences.list()\n      \n      const channels: Channel[] = response.data?.data?.map(audience => ({\n        id: audience.id,\n        name: audience.name,\n        description: undefined, // Resend doesn't have description\n        fromName: (this.config as ResendProviderConfig).fromName || '',\n        fromEmail: (this.config as ResendProviderConfig).fromEmail || '',\n        replyTo: (this.config as ResendProviderConfig).replyTo,\n        providerId: audience.id,\n        providerType: 'resend' as const,\n        subscriberCount: undefined, // Not available in list API\n        active: true,\n        createdAt: new Date(audience.created_at),\n        updatedAt: new Date(audience.created_at) // No updated_at in Resend\n      })) || []\n      \n      return {\n        channels,\n        total: channels.length,\n        limit: options?.limit || 100,\n        offset: options?.offset || 0\n      }\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to list channels (audiences): ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async getChannel(id: string): Promise<Channel> {\n    try {\n      const response = await this.client.audiences.get(id)\n      \n      if (!response.data) {\n        throw new BroadcastProviderError(\n          `Channel (audience) not found: ${id}`,\n          BroadcastErrorCode.CHANNEL_NOT_FOUND,\n          this.name\n        )\n      }\n      \n      return {\n        id: response.data.id,\n        name: response.data.name,\n        description: undefined,\n        fromName: (this.config as ResendProviderConfig).fromName || '',\n        fromEmail: (this.config as ResendProviderConfig).fromEmail || '',\n        replyTo: (this.config as ResendProviderConfig).replyTo,\n        providerId: response.data.id,\n        providerType: 'resend',\n        subscriberCount: undefined, // Not available\n        active: true,\n        createdAt: new Date(response.data.created_at),\n        updatedAt: new Date(response.data.created_at)\n      }\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to get channel (audience): ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async createChannel(data: CreateChannelInput): Promise<Channel> {\n    try {\n      const response = await this.client.audiences.create({\n        name: data.name\n      })\n      \n      if (!response.data) {\n        throw new Error('Failed to create audience')\n      }\n      \n      return {\n        id: response.data.id,\n        name: response.data.name,\n        description: data.description,\n        fromName: data.fromName,\n        fromEmail: data.fromEmail,\n        replyTo: data.replyTo,\n        providerId: response.data.id,\n        providerType: 'resend',\n        subscriberCount: 0,\n        active: true,\n        createdAt: new Date(),\n        updatedAt: new Date()\n      }\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to create channel (audience): ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async updateChannel(_id: string, _data: UpdateChannelInput): Promise<Channel> {\n    // Resend doesn't support updating audiences via API\n    throw new BroadcastProviderError(\n      'Updating channels (audiences) is not supported by Resend API',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async deleteChannel(id: string): Promise<void> {\n    try {\n      await this.client.audiences.remove(id)\n    } catch (error: unknown) {\n      throw new BroadcastProviderError(\n        `Failed to delete channel (audience): ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  // Broadcast Management Methods\n  async list(_options?: ListBroadcastOptions): Promise<ListBroadcastResponse<Broadcast>> {\n    // TODO: Resend broadcast list API is not documented\n    // The SDK may have undocumented methods we could explore\n    // For now, we throw a not supported error\n    throw new BroadcastProviderError(\n      'Listing broadcasts is not currently supported by Resend API. ' +\n      'This feature may be available in the dashboard only.',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async get(_id: string): Promise<Broadcast> {\n    // TODO: Resend broadcast get API is not documented\n    // We would need to explore if the SDK has undocumented methods\n    throw new BroadcastProviderError(\n      'Getting individual broadcasts is not currently supported by Resend API. ' +\n      'This feature may be available in the dashboard only.',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async create(data: CreateBroadcastInput): Promise<Broadcast> {\n    try {\n      this.validateRequiredFields(data, ['channelId', 'name', 'subject', 'content'])\n\n      // Get the appropriate audience ID\n      const locale = 'en' // TODO: Make this configurable\n      const audienceConfig = this.audienceIds?.[locale]\n      const audienceId = this.isDevelopment \n        ? audienceConfig?.development || audienceConfig?.production\n        : audienceConfig?.production || audienceConfig?.development\n\n      if (!audienceId && data.audienceIds?.length) {\n        // Use provided audience ID if no default configured\n        // Note: Resend might only support one audience per broadcast\n      }\n\n      // TODO: The exact Resend broadcast creation API is not documented\n      // Based on their blog posts, it seems broadcasts can be created via API\n      // but the exact endpoint/method is unclear\n      \n      // Attempt to use broadcasts if available in SDK\n      const resendClient = this.client as any\n      if (resendClient.broadcasts?.create) {\n        const broadcast = await resendClient.broadcasts.create({\n          name: data.name,\n          subject: data.subject,\n          from: `${(this.config as ResendProviderConfig).fromName || 'Newsletter'} <${(this.config as ResendProviderConfig).fromEmail || 'noreply@example.com'}>`,\n          reply_to: data.replyTo,\n          audience_id: audienceId || data.audienceIds?.[0],\n          content: {\n            html: data.content,\n            // TODO: Handle plain text version\n          }\n        })\n\n        // Transform to our Broadcast type\n        return this.transformResendToBroadcast(broadcast)\n      }\n\n      // If broadcasts API not available, throw error\n      throw new BroadcastProviderError(\n        'Creating broadcasts via API is not currently supported. ' +\n        'Please check if Resend has released their Broadcasts API.',\n        BroadcastErrorCode.NOT_SUPPORTED,\n        this.name\n      )\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to create broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async update(_id: string, _data: UpdateBroadcastInput): Promise<Broadcast> {\n    // TODO: Resend broadcast update API is not documented\n    // Important: Resend has restrictions where broadcasts created via API\n    // can only be edited via API (not in dashboard)\n    throw new BroadcastProviderError(\n      'Updating broadcasts is not currently supported by Resend API. ' +\n      'Note: Resend broadcasts can only be edited where they were created.',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async delete(_id: string): Promise<void> {\n    // TODO: Resend broadcast delete API is not documented\n    throw new BroadcastProviderError(\n      'Deleting broadcasts is not currently supported by Resend API.',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async send(id: string, options?: SendBroadcastOptions): Promise<Broadcast> {\n    try {\n      // TODO: The exact Resend broadcast send API is not documented\n      // Based on their features, sending broadcasts is supported\n      \n      const resendClient = this.client as any\n      if (resendClient.broadcasts?.send) {\n        await resendClient.broadcasts.send(id, {\n          audience_id: options?.audienceIds?.[0],\n          // TODO: Handle test mode if supported\n        })\n\n        // We can't get the updated broadcast, so return a mock\n        return {\n          id,\n          channelId: options?.audienceIds?.[0] || '1',\n          name: 'Unknown',\n          subject: 'Unknown',\n          content: '',\n          status: BroadcastStatus.SENDING,\n          trackOpens: true,\n          trackClicks: true,\n          createdAt: new Date(),\n          updatedAt: new Date(),\n          providerType: 'resend'\n        } as Broadcast\n      }\n\n      throw new BroadcastProviderError(\n        'Sending broadcasts via API is not currently supported. ' +\n        'Please check if Resend has released their Broadcasts API.',\n        BroadcastErrorCode.NOT_SUPPORTED,\n        this.name\n      )\n    } catch (error: unknown) {\n      if (error instanceof BroadcastProviderError) throw error\n      \n      throw new BroadcastProviderError(\n        `Failed to send broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        BroadcastErrorCode.PROVIDER_ERROR,\n        this.name,\n        error\n      )\n    }\n  }\n\n  async schedule(_id: string, _scheduledAt: Date): Promise<Broadcast> {\n    // Scheduling is not supported according to our research\n    throw new BroadcastProviderError(\n      'Scheduling broadcasts is not supported by Resend',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  async getAnalytics(_id: string): Promise<BroadcastAnalytics> {\n    // TODO: Resend does support analytics, but the API is not documented\n    // They have dashboard analytics for broadcasts\n    throw new BroadcastProviderError(\n      'Getting broadcast analytics via API is not currently supported. ' +\n      'Analytics may be available in the Resend dashboard.',\n      BroadcastErrorCode.NOT_SUPPORTED,\n      this.name\n    )\n  }\n\n  getCapabilities(): BroadcastProviderCapabilities {\n    return {\n      supportsScheduling: false, // Not documented\n      supportsSegmentation: true, // Via Audiences\n      supportsAnalytics: true, // Available in dashboard, API unclear\n      supportsABTesting: false,\n      supportsTemplates: false, // Not clear from docs\n      supportsPersonalization: true, // Via merge tags\n      supportsMultipleChannels: true, // Via multiple audiences\n      supportsChannelSegmentation: false, // Not within a single audience\n      editableStatuses: [], // Unclear which statuses can be edited\n      supportedContentTypes: ['html'] // React components via SDK\n    }\n  }\n\n  async validateConfiguration(): Promise<boolean> {\n    try {\n      // Try to use the API key to validate it works\n      // We can try to list audiences as a validation check\n      const resendClient = this.client as any\n      if (resendClient.audiences?.list) {\n        await resendClient.audiences.list({ limit: 1 })\n        return true\n      }\n      \n      // Fallback: try to send a test email to validate API key\n      await this.client.emails.send({\n        from: 'onboarding@resend.dev',\n        to: 'delivered@resend.dev',\n        subject: 'Configuration Test',\n        html: '<p>Testing configuration</p>'\n      })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Transform Resend broadcast to our Broadcast type\n   * NOTE: This is speculative based on what the API might return\n   */\n  private transformResendToBroadcast(broadcast: any): Broadcast {\n    return {\n      id: broadcast.id,\n      channelId: broadcast.audience_id || '1', // Map audience_id to channelId\n      name: broadcast.name || 'Untitled',\n      subject: broadcast.subject,\n      preheader: broadcast.preheader,\n      content: broadcast.content?.html || broadcast.html || '',\n      status: this.mapResendStatus(broadcast.status),\n      trackOpens: true, // Resend tracks by default\n      trackClicks: true, // Resend tracks by default\n      replyTo: broadcast.reply_to,\n      recipientCount: broadcast.recipient_count,\n      sentAt: broadcast.sent_at ? new Date(broadcast.sent_at) : undefined,\n      scheduledAt: broadcast.scheduled_at ? new Date(broadcast.scheduled_at) : undefined,\n      createdAt: new Date(broadcast.created_at || Date.now()),\n      updatedAt: new Date(broadcast.updated_at || Date.now()),\n      providerData: { broadcast },\n      providerId: broadcast.id,\n      providerType: 'resend'\n    }\n  }\n\n  private mapResendStatus(status?: string): BroadcastStatus {\n    if (!status) return BroadcastStatus.DRAFT\n    \n    // NOTE: Resend statuses are not documented, these are guesses\n    const statusMap: Record<string, BroadcastStatus> = {\n      'draft': BroadcastStatus.DRAFT,\n      'scheduled': BroadcastStatus.SCHEDULED,\n      'sending': BroadcastStatus.SENDING,\n      'sent': BroadcastStatus.SENT,\n      'failed': BroadcastStatus.FAILED\n    }\n    return statusMap[status.toLowerCase()] || BroadcastStatus.DRAFT\n  }\n}\n\n/**\n * IMPLEMENTATION NOTES:\n * \n * 1. Most methods throw NOT_SUPPORTED errors because Resend's Broadcast API\n *    is not publicly documented\n * \n * 2. The SDK might have undocumented methods (broadcasts.create, broadcasts.send, etc.)\n *    that we attempt to use, but we can't guarantee they exist\n * \n * 3. Important limitation: Broadcasts created via API can only be edited via API,\n *    not in the Resend dashboard\n * \n * 4. Resend uses \"Audiences\" instead of \"Segments\" for targeting\n * \n * 5. Analytics are available in the dashboard but API access is unclear\n * \n * FUTURE IMPROVEMENTS:\n * - Monitor Resend's documentation for Broadcast API updates\n * - Explore SDK source code for undocumented methods\n * - Consider using Resend's email API to simulate broadcasts\n * - Add webhook support for delivery/open/click tracking\n */","import type { Config } from 'payload'\nimport type { NewsletterPluginConfig, BroadcastProvider } from './types'\nimport { createSubscribersCollection } from './collections/Subscribers'\nimport { createNewsletterSettingsGlobal } from './globals/NewsletterSettings'\nimport { createEmailService } from './providers'\nimport { createNewsletterEndpoints } from './endpoints'\nimport { createNewsletterSchedulingFields } from './fields/newsletterScheduling'\nimport { createUnsubscribeSyncJob } from './jobs/sync-unsubscribes'\nimport { createChannelsCollection } from './collections/Channels'\nimport { createBroadcastsCollection } from './collections/Broadcasts'\nimport { BroadcastApiProvider } from './providers/broadcast/broadcast'\nimport { ResendBroadcastProvider } from './providers/resend/broadcast'\n\n// Extend Payload type to include our email service and broadcast provider\ndeclare module 'payload' {\n  interface BasePayload {\n    newsletterEmailService?: any\n    broadcastProvider?: BroadcastProvider\n    // Legacy support\n    newsletterProvider?: BroadcastProvider\n  }\n}\n\nexport const newsletterPlugin = (pluginConfig: NewsletterPluginConfig) => (incomingConfig: Config): Config => {\n  // Validate and set defaults\n  const config: NewsletterPluginConfig = {\n    enabled: true,\n    subscribersSlug: 'subscribers',\n    settingsSlug: 'newsletter-settings',\n    auth: {\n      enabled: true,\n      tokenExpiration: '7d',\n      magicLinkPath: '/newsletter/verify',\n      ...pluginConfig.auth,\n    },\n    ...pluginConfig,\n  }\n\n  // If plugin is disabled, return config unchanged\n  if (!config.enabled) {\n    return incomingConfig\n  }\n\n  // Create plugin collections and globals\n  const subscribersCollection = createSubscribersCollection(config)\n  const settingsGlobal = createNewsletterSettingsGlobal(config)\n\n  // Build collections array\n  let collections = [...(incomingConfig.collections || []), subscribersCollection]\n\n  // Add broadcast management collections if enabled\n  if (config.features?.newsletterManagement?.enabled) {\n    const channelsCollection = createChannelsCollection(config)\n    const broadcastsCollection = createBroadcastsCollection(config)\n    collections.push(channelsCollection, broadcastsCollection)\n  }\n\n  // Extend collections with newsletter scheduling fields if enabled\n  if (config.features?.newsletterScheduling?.enabled) {\n    const targetCollections = config.features.newsletterScheduling.collections || 'articles'\n    const collectionsToExtend = Array.isArray(targetCollections) ? targetCollections : [targetCollections]\n    const schedulingFields = createNewsletterSchedulingFields(config)\n    \n    collections = collections.map(collection => {\n      if (collectionsToExtend.includes(collection.slug)) {\n        return {\n          ...collection,\n          fields: [\n            ...collection.fields,\n            ...schedulingFields,\n          ],\n        }\n      }\n      return collection\n    })\n  }\n\n  // Create API endpoints\n  const endpoints = createNewsletterEndpoints(config)\n\n  // Create sync job if enabled\n  const syncJob = config.features?.unsubscribeSync?.enabled ? createUnsubscribeSyncJob(config) : null\n\n  // Build the modified config\n  const modifiedConfig: Config = {\n    ...incomingConfig,\n    collections,\n    globals: [\n      ...(incomingConfig.globals || []),\n      settingsGlobal,\n    ],\n    endpoints: [\n      ...(incomingConfig.endpoints || []),\n      ...endpoints,\n    ],\n    jobs: syncJob ? {\n      ...(incomingConfig.jobs || {}),\n      tasks: [\n        ...(incomingConfig.jobs?.tasks || []),\n        syncJob,\n      ],\n      // Add cron schedule if specified\n      autoRun: config.features?.unsubscribeSync?.schedule ? (\n        Array.isArray(incomingConfig.jobs?.autoRun) \n          ? [...incomingConfig.jobs.autoRun, {\n              cron: config.features.unsubscribeSync.schedule,\n              queue: 'newsletter-sync',\n              limit: 100,\n            }]\n          : typeof incomingConfig.jobs?.autoRun === 'function'\n            ? async (payload: any) => {\n                const autoRunFn = incomingConfig.jobs!.autoRun as (payload: any) => any[] | Promise<any[]>\n                const existingConfigs = await autoRunFn(payload)\n                return [...existingConfigs, {\n                  cron: config.features!.unsubscribeSync!.schedule,\n                  queue: 'newsletter-sync',\n                  limit: 100,\n                }]\n              }\n            : [{\n                cron: config.features!.unsubscribeSync!.schedule,\n                queue: 'newsletter-sync',\n                limit: 100,\n              }]\n      ) : incomingConfig.jobs?.autoRun,\n    } : incomingConfig.jobs,\n    onInit: async (payload) => {\n      // Initialize email service\n      try {\n        // Get settings from global\n        const settings = await payload.findGlobal({\n          slug: config.settingsSlug || 'newsletter-settings',\n        })\n\n        let emailServiceConfig: any\n        \n        if (settings) {\n          emailServiceConfig = {\n            provider: settings.provider || config.providers.default,\n            fromAddress: settings.fromAddress || config.providers.resend?.fromAddress || config.providers.broadcast?.fromAddress || 'noreply@example.com',\n            fromName: settings.fromName || config.providers.resend?.fromName || config.providers.broadcast?.fromName || 'Newsletter',\n            replyTo: settings.replyTo,\n            resend: settings.provider === 'resend' ? {\n              apiKey: settings.resendSettings?.apiKey || config.providers.resend?.apiKey || '',\n              audienceIds: settings.resendSettings?.audienceIds?.reduce((acc: any, item: any) => {\n                acc[item.locale] = {\n                  production: item.production,\n                  development: item.development,\n                }\n                return acc\n              }, {}) || config.providers.resend?.audienceIds,\n            } : config.providers.resend,\n            broadcast: settings.provider === 'broadcast' ? {\n              apiUrl: settings.broadcastSettings?.apiUrl || config.providers.broadcast?.apiUrl || '',\n              tokens: {\n                production: settings.broadcastSettings?.productionToken || config.providers.broadcast?.tokens.production,\n                development: settings.broadcastSettings?.developmentToken || config.providers.broadcast?.tokens.development,\n              },\n            } : config.providers.broadcast,\n          }\n        } else {\n          // Use config defaults\n          emailServiceConfig = {\n            provider: config.providers.default,\n            fromAddress: config.providers.resend?.fromAddress || config.providers.broadcast?.fromAddress || 'noreply@example.com',\n            fromName: config.providers.resend?.fromName || config.providers.broadcast?.fromName || 'Newsletter',\n            resend: config.providers.resend,\n            broadcast: config.providers.broadcast,\n          }\n        }\n\n        (payload as any).newsletterEmailService = createEmailService(emailServiceConfig)\n\n        console.warn('Newsletter plugin initialized with', (payload as any).newsletterEmailService.getProvider(), 'provider')\n        \n        // Initialize broadcast management provider if enabled\n        if (config.features?.newsletterManagement?.enabled) {\n          try {\n            // Use custom provider if provided\n            let broadcastProvider: BroadcastProvider\n            \n            if (config.features.newsletterManagement.provider) {\n              broadcastProvider = config.features.newsletterManagement.provider\n            } else {\n              // Create provider based on email service config\n              const providerType = emailServiceConfig.provider || config.providers.default\n              \n              if (providerType === 'broadcast' && emailServiceConfig.broadcast) {\n                broadcastProvider = new BroadcastApiProvider(emailServiceConfig.broadcast)\n              } else if (providerType === 'resend' && emailServiceConfig.resend) {\n                broadcastProvider = new ResendBroadcastProvider(emailServiceConfig.resend)\n              } else {\n                throw new Error(`Unsupported broadcast provider: ${providerType}`)\n              }\n            }\n            \n            // Attach broadcast provider to payload instance\n            const payloadWithProvider = payload as any\n            payloadWithProvider.broadcastProvider = broadcastProvider\n            // Legacy support\n            payloadWithProvider.newsletterProvider = broadcastProvider\n            \n            console.warn('Broadcast management initialized with', broadcastProvider.name, 'provider')\n          } catch (error) {\n            console.error('Failed to initialize broadcast management provider:', error)\n          }\n        }\n      } catch (error) {\n        console.error('Failed to initialize newsletter email service:', error)\n      }\n\n      // Call original onInit if it exists\n      if (incomingConfig.onInit) {\n        await incomingConfig.onInit(payload)\n      }\n    },\n  }\n\n  return modifiedConfig\n}\n\nexport { newsletterPlugin as default }\n\n// Export session utilities\nexport * from './utilities/session'","import type { Access, AccessArgs } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\n\n/**\n * Check if a user is an admin based on the plugin configuration\n */\nexport const isAdmin = (user: any, config?: NewsletterPluginConfig): boolean => {\n  if (!user || user.collection !== 'users') {\n    return false\n  }\n\n  // If custom admin check is provided, use it\n  if (config?.access?.isAdmin) {\n    return config.access.isAdmin(user)\n  }\n\n  // Default checks for common admin patterns\n  // 1. Check for admin role\n  if (user.roles?.includes('admin')) {\n    return true\n  }\n\n  // 2. Check for isAdmin boolean field\n  if (user.isAdmin === true) {\n    return true\n  }\n\n  // 3. Check for role field with admin value\n  if (user.role === 'admin') {\n    return true\n  }\n\n  // 4. Check for admin collection relationship\n  if (user.admin === true) {\n    return true\n  }\n\n  return false\n}\n\n/**\n * Create admin-only access control\n */\nexport const adminOnly = (config?: NewsletterPluginConfig): Access => \n  ({ req }: AccessArgs) => {\n    const user = req.user\n    return isAdmin(user, config)\n  }\n\n/**\n * Create admin or owner access control\n */\nexport const adminOrSelf = (config?: NewsletterPluginConfig): Access => \n  ({ req, id }: AccessArgs) => {\n    const user = req.user\n    \n    // No user = no access\n    if (!user) {\n      // For list operations without ID, return impossible condition\n      if (!id) {\n        return {\n          id: {\n            equals: 'unauthorized-no-access',\n          },\n        }\n      }\n      return false\n    }\n    \n    // Admins can access everything\n    if (isAdmin(user, config)) {\n      return true\n    }\n    \n    // Synthetic users (subscribers from magic link) can access their own data\n    if (user.collection === 'subscribers') {\n      // For list operations, scope to their own data\n      if (!id) {\n        return {\n          id: {\n            equals: user.id,\n          },\n        }\n      }\n      // For specific document access, check if it's their own\n      return id === user.id\n    }\n    \n    // Regular users cannot access subscriber data\n    if (!id) {\n      return {\n        id: {\n          equals: 'unauthorized-no-access',\n        },\n      }\n    }\n    return false\n  }","import { render } from '@react-email/render'\nimport { MagicLinkEmail } from './MagicLink'\nimport { WelcomeEmail } from './Welcome'\nimport { SignInEmail } from './SignIn'\n\nexport type EmailTemplate = 'magic-link' | 'welcome' | 'signin'\n\nexport interface BaseEmailData {\n  email?: string\n  siteName?: string\n  [key: string]: any\n}\n\nexport interface MagicLinkData extends BaseEmailData {\n  magicLink?: string\n  verificationUrl?: string\n  magicLinkUrl?: string\n  expiresIn?: string\n}\n\nexport interface WelcomeData extends BaseEmailData {\n  preferencesUrl?: string\n}\n\nexport async function renderEmail(\n  template: EmailTemplate, \n  data: MagicLinkData | WelcomeData\n): Promise<string> {\n  try {\n    switch (template) {\n      case 'magic-link': {\n        const magicLinkData = data as MagicLinkData\n        return render(\n          <MagicLinkEmail\n            magicLink={\n              magicLinkData.magicLink || \n              magicLinkData.verificationUrl || \n              magicLinkData.magicLinkUrl || \n              ''\n            }\n            email={magicLinkData.email || ''}\n            siteName={magicLinkData.siteName}\n            expiresIn={magicLinkData.expiresIn}\n          />\n        )\n      }\n      \n      case 'signin': {\n        const signinData = data as MagicLinkData\n        return render(\n          <SignInEmail\n            magicLink={\n              signinData.magicLink || \n              signinData.verificationUrl || \n              signinData.magicLinkUrl || \n              ''\n            }\n            email={signinData.email || ''}\n            siteName={signinData.siteName}\n            expiresIn={signinData.expiresIn}\n          />\n        )\n      }\n      \n      case 'welcome': {\n        const welcomeData = data as WelcomeData\n        return render(\n          <WelcomeEmail\n            email={welcomeData.email || ''}\n            siteName={welcomeData.siteName}\n            preferencesUrl={welcomeData.preferencesUrl}\n          />\n        )\n      }\n      \n      default:\n        throw new Error(`Unknown email template: ${template}`)\n    }\n  } catch (error) {\n    console.error(`Failed to render email template ${template}:`, error)\n    throw error\n  }\n}\n\n// Export for custom template rendering\nexport { MagicLinkEmail, WelcomeEmail, SignInEmail }","import React from 'react'\nimport {\n  Body,\n  Button,\n  Container,\n  Head,\n  Hr,\n  Html,\n  Preview,\n  Text,\n} from '@react-email/components'\nimport { styles } from './styles'\n\nexport interface MagicLinkEmailProps {\n  magicLink: string\n  email: string\n  siteName?: string\n  expiresIn?: string\n}\n\nexport const MagicLinkEmail: React.FC<MagicLinkEmailProps> = ({\n  magicLink,\n  email,\n  siteName = 'Newsletter',\n  expiresIn = '24 hours',\n}) => {\n  const previewText = `Sign in to ${siteName}`\n  \n  return (\n    <Html>\n      <Head />\n      <Preview>{previewText}</Preview>\n      <Body style={styles.main}>\n        <Container style={styles.container}>\n          <Text style={styles.heading}>Sign in to {siteName}</Text>\n          \n          <Text style={styles.text}>\n            Hi {email.split('@')[0]},\n          </Text>\n          \n          <Text style={styles.text}>\n            We received a request to sign in to your {siteName} account. \n            Click the button below to complete your sign in:\n          </Text>\n          \n          <Button href={magicLink} style={styles.button}>\n            Sign in to {siteName}\n          </Button>\n          \n          <Text style={styles.text}>\n            Or copy and paste this URL into your browser:\n          </Text>\n          \n          <code style={styles.code}>{magicLink}</code>\n          \n          <Hr style={styles.hr} />\n          \n          <Text style={styles.footer}>\n            This link will expire in {expiresIn}. If you didn't request this email, \n            you can safely ignore it.\n          </Text>\n        </Container>\n      </Body>\n    </Html>\n  )\n}\n\nexport default MagicLinkEmail","export const styles = {\n  main: {\n    backgroundColor: '#f6f9fc',\n    fontFamily:\n      '-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Ubuntu,sans-serif',\n  },\n  container: {\n    backgroundColor: '#ffffff',\n    border: '1px solid #f0f0f0',\n    borderRadius: '5px',\n    margin: '0 auto',\n    padding: '45px',\n    marginBottom: '64px',\n    maxWidth: '500px',\n  },\n  heading: {\n    fontSize: '24px',\n    letterSpacing: '-0.5px',\n    lineHeight: '1.3',\n    fontWeight: '600',\n    color: '#484848',\n    margin: '0 0 20px',\n    padding: '0',\n  },\n  text: {\n    fontSize: '16px',\n    lineHeight: '26px',\n    fontWeight: '400',\n    color: '#484848',\n    margin: '16px 0',\n  },\n  button: {\n    backgroundColor: '#000000',\n    borderRadius: '5px',\n    color: '#fff',\n    fontSize: '16px',\n    fontWeight: 'bold',\n    textDecoration: 'none',\n    textAlign: 'center' as const,\n    display: 'block',\n    width: '100%',\n    padding: '14px 20px',\n    margin: '30px 0',\n  },\n  link: {\n    color: '#2754C5',\n    fontSize: '14px',\n    textDecoration: 'underline',\n    wordBreak: 'break-all' as const,\n  },\n  hr: {\n    borderColor: '#e6ebf1',\n    margin: '30px 0',\n  },\n  footer: {\n    fontSize: '14px',\n    lineHeight: '24px',\n    color: '#9ca2ac',\n    textAlign: 'center' as const,\n    margin: '0',\n  },\n  code: {\n    display: 'inline-block',\n    padding: '16px',\n    width: '100%',\n    backgroundColor: '#f4f4f4',\n    borderRadius: '5px',\n    border: '1px solid #eee',\n    fontSize: '14px',\n    fontFamily: 'monospace',\n    textAlign: 'center' as const,\n    margin: '24px 0',\n  },\n}","import React from 'react'\nimport {\n  Body,\n  Button,\n  Container,\n  Head,\n  Hr,\n  Html,\n  Preview,\n  Text,\n} from '@react-email/components'\nimport { styles } from './styles'\n\nexport interface WelcomeEmailProps {\n  email: string\n  siteName?: string\n  preferencesUrl?: string\n}\n\nexport const WelcomeEmail: React.FC<WelcomeEmailProps> = ({\n  email,\n  siteName = 'Newsletter',\n  preferencesUrl,\n}) => {\n  const previewText = `Welcome to ${siteName}!`\n  const firstName = email.split('@')[0]\n  \n  return (\n    <Html>\n      <Head />\n      <Preview>{previewText}</Preview>\n      <Body style={styles.main}>\n        <Container style={styles.container}>\n          <Text style={styles.heading}>Welcome to {siteName}! 🎉</Text>\n          \n          <Text style={styles.text}>\n            Hi {firstName},\n          </Text>\n          \n          <Text style={styles.text}>\n            Thanks for subscribing to {siteName}! We're excited to have you as part \n            of our community.\n          </Text>\n          \n          <Text style={styles.text}>\n            You'll receive our newsletter based on your preferences. Speaking of which, \n            you can update your preferences anytime:\n          </Text>\n          \n          {preferencesUrl && (\n            <Button href={preferencesUrl} style={styles.button}>\n              Manage Preferences\n            </Button>\n          )}\n          \n          <Text style={styles.text}>\n            Here's what you can expect from us:\n          </Text>\n          \n          <Text style={styles.text}>\n            • Regular updates based on your chosen frequency<br />\n            • Content tailored to your interests<br />\n            • Easy unsubscribe options in every email<br />\n            • Your privacy respected always\n          </Text>\n          \n          <Hr style={styles.hr} />\n          \n          <Text style={styles.footer}>\n            If you have any questions, feel free to reply to this email. \n            We're here to help!\n          </Text>\n        </Container>\n      </Body>\n    </Html>\n  )\n}\n\nexport default WelcomeEmail","// SignIn is just an alias for MagicLink with slightly different defaults\nimport React from 'react'\nimport { MagicLinkEmail, MagicLinkEmailProps } from './MagicLink'\n\nexport const SignInEmail: React.FC<MagicLinkEmailProps> = (props) => {\n  return <MagicLinkEmail {...props} />\n}\n\nexport default SignInEmail","import type { CollectionConfig, Field, CollectionAfterChangeHook, CollectionBeforeDeleteHook } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { adminOnly, adminOrSelf } from '../utils/access'\nimport { renderEmail } from '../emails/render'\n\nexport const createSubscribersCollection = (\n  pluginConfig: NewsletterPluginConfig\n): CollectionConfig => {\n  const slug = pluginConfig.subscribersSlug || 'subscribers'\n  \n  // Default fields for the subscribers collection\n  const defaultFields: Field[] = [\n    // Core fields\n    {\n      name: 'email',\n      type: 'email',\n      required: true,\n      unique: true,\n      admin: {\n        description: 'Subscriber email address',\n      },\n    },\n    {\n      name: 'name',\n      type: 'text',\n      admin: {\n        description: 'Subscriber full name',\n      },\n    },\n    {\n      name: 'locale',\n      type: 'select',\n      options: pluginConfig.i18n?.locales?.map(locale => ({\n        label: locale.toUpperCase(),\n        value: locale,\n      })) || [\n        { label: 'EN', value: 'en' },\n      ],\n      defaultValue: pluginConfig.i18n?.defaultLocale || 'en',\n      admin: {\n        description: 'Preferred language for communications',\n      },\n    },\n    \n    // Authentication fields (hidden from admin UI)\n    {\n      name: 'magicLinkToken',\n      type: 'text',\n      hidden: true,\n    },\n    {\n      name: 'magicLinkTokenExpiry',\n      type: 'date',\n      hidden: true,\n    },\n    \n    // Subscription status\n    {\n      name: 'subscriptionStatus',\n      type: 'select',\n      options: [\n        { label: 'Active', value: 'active' },\n        { label: 'Unsubscribed', value: 'unsubscribed' },\n        { label: 'Pending', value: 'pending' },\n      ],\n      defaultValue: 'pending',\n      required: true,\n      admin: {\n        description: 'Current subscription status',\n      },\n    },\n    {\n      name: 'unsubscribedAt',\n      type: 'date',\n      admin: {\n        condition: (data) => data?.subscriptionStatus === 'unsubscribed',\n        description: 'When the user unsubscribed',\n        readOnly: true,\n      },\n    },\n    \n    // Email preferences\n    {\n      name: 'emailPreferences',\n      type: 'group',\n      fields: [\n        {\n          name: 'newsletter',\n          type: 'checkbox',\n          defaultValue: true,\n          label: 'Newsletter',\n          admin: {\n            description: 'Receive regular newsletter updates',\n          },\n        },\n        {\n          name: 'announcements',\n          type: 'checkbox',\n          defaultValue: true,\n          label: 'Announcements',\n          admin: {\n            description: 'Receive important announcements',\n          },\n        },\n      ],\n      admin: {\n        description: 'Email communication preferences',\n      },\n    },\n    \n    // Source tracking\n    {\n      name: 'source',\n      type: 'text',\n      admin: {\n        description: 'Where the subscriber signed up from',\n      },\n    },\n  ]\n\n  // Add UTM tracking fields if enabled\n  if (pluginConfig.features?.utmTracking?.enabled) {\n    const utmFields = pluginConfig.features.utmTracking.fields || [\n      'source',\n      'medium',\n      'campaign',\n      'content',\n      'term',\n    ]\n    \n    defaultFields.push({\n      name: 'utmParameters',\n      type: 'group',\n      fields: utmFields.map(field => ({\n        name: field,\n        type: 'text',\n        admin: {\n          description: `UTM ${field} parameter`,\n        },\n      })),\n      admin: {\n        description: 'UTM tracking parameters',\n      },\n    })\n  }\n\n  // Add signup metadata\n  defaultFields.push({\n    name: 'signupMetadata',\n    type: 'group',\n    fields: [\n      {\n        name: 'ipAddress',\n        type: 'text',\n        admin: {\n          readOnly: true,\n        },\n      },\n      {\n        name: 'userAgent',\n        type: 'text',\n        admin: {\n          readOnly: true,\n        },\n      },\n      {\n        name: 'referrer',\n        type: 'text',\n        admin: {\n          readOnly: true,\n        },\n      },\n      {\n        name: 'signupPage',\n        type: 'text',\n        admin: {\n          readOnly: true,\n        },\n      },\n    ],\n    admin: {\n      description: 'Technical information about signup',\n    },\n  })\n\n  // Add lead magnet field if enabled\n  if (pluginConfig.features?.leadMagnets?.enabled) {\n    defaultFields.push({\n      name: 'leadMagnet',\n      type: 'relationship',\n      relationTo: pluginConfig.features.leadMagnets.collection || 'media',\n      admin: {\n        description: 'Lead magnet downloaded at signup',\n      },\n    })\n  }\n\n  // Allow field customization\n  let fields = defaultFields\n  if (pluginConfig.fields?.overrides) {\n    fields = pluginConfig.fields.overrides({ defaultFields })\n  }\n  if (pluginConfig.fields?.additional) {\n    fields = [...fields, ...pluginConfig.fields.additional]\n  }\n\n  const subscribersCollection: CollectionConfig = {\n    slug,\n    labels: {\n      singular: 'Subscriber',\n      plural: 'Subscribers',\n    },\n    admin: {\n      useAsTitle: 'email',\n      defaultColumns: ['email', 'name', 'subscriptionStatus', 'createdAt'],\n      group: 'Newsletter',\n    },\n    fields,\n    hooks: {\n      afterChange: [\n        async ({ doc, req, operation, previousDoc }) => {\n          // After create logic\n          if (operation === 'create') {\n            // Add to email service\n            const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n            if (emailService) {\n              try {\n                await emailService.addContact(doc)\n              } catch {\n                // Failed to add contact to email service\n              }\n            }\n\n            // Send welcome email if active\n            if (doc.subscriptionStatus === 'active' && emailService) {\n              try {\n                // Get settings for site name\n                const settings = await req.payload.findGlobal({\n                  slug: pluginConfig.settingsSlug || 'newsletter-settings',\n                })\n                \n                // Render welcome email\n                const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || ''\n                const html = await renderEmail('welcome', {\n                  email: doc.email,\n                  siteName: settings?.brandSettings?.siteName || 'Newsletter',\n                  preferencesUrl: `${serverURL}/account/preferences`, // This could be customized\n                })\n                \n                // Send email\n                await emailService.send({\n                  to: doc.email,\n                  subject: settings?.brandSettings?.siteName ? `Welcome to ${settings.brandSettings.siteName}!` : 'Welcome!',\n                  html,\n                })\n                \n                console.warn(`Welcome email sent to: ${doc.email}`)\n              } catch (error) {\n                console.error('Failed to send welcome email:', error)\n                // Don't fail the subscription if welcome email fails\n              }\n            }\n\n            // Custom after subscribe hook\n            if (pluginConfig.hooks?.afterSubscribe) {\n              await pluginConfig.hooks.afterSubscribe({ doc, req })\n            }\n          }\n          \n          // After update logic\n          if (operation === 'update' && previousDoc) {\n            // Update email service if status changed\n            const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n            if (\n              doc.subscriptionStatus !== previousDoc.subscriptionStatus &&\n              emailService\n            ) {\n              try {\n                await emailService.updateContact(doc)\n              } catch {\n                // Failed to update contact in email service\n              }\n            }\n\n            // Handle unsubscribe\n            if (\n              doc.subscriptionStatus === 'unsubscribed' &&\n              previousDoc.subscriptionStatus !== 'unsubscribed'\n            ) {\n              // Set unsubscribed timestamp\n              doc.unsubscribedAt = new Date().toISOString()\n              \n              // Custom after unsubscribe hook\n              if (pluginConfig.hooks?.afterUnsubscribe) {\n                await pluginConfig.hooks.afterUnsubscribe({ doc, req })\n              }\n            }\n          }\n        },\n      ] as CollectionAfterChangeHook[],\n      beforeDelete: [\n        async ({ id, req }) => {\n          // Remove from email service\n          const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n          if (emailService) {\n            try {\n              const doc = await req.payload.findByID({\n                collection: slug,\n                id,\n              })\n              await emailService.removeContact(doc.email)\n            } catch {\n              // Failed to remove contact from email service\n            }\n          }\n        },\n      ] as CollectionBeforeDeleteHook[],\n    },\n    access: {\n      create: () => true, // Public can subscribe\n      read: adminOrSelf(pluginConfig),\n      update: adminOrSelf(pluginConfig),\n      delete: adminOnly(pluginConfig),\n    },\n    timestamps: true,\n  }\n\n  return subscribersCollection\n}","import type { GlobalConfig } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { adminOnly } from '../utils/access'\n\nexport const createNewsletterSettingsGlobal = (\n  pluginConfig: NewsletterPluginConfig\n): GlobalConfig => {\n  const slug = pluginConfig.settingsSlug || 'newsletter-settings'\n  \n  return {\n    slug,\n    label: 'Newsletter Settings',\n    admin: {\n      group: 'Newsletter',\n      description: 'Configure email provider settings and templates',\n    },\n    fields: [\n      {\n        type: 'tabs',\n        tabs: [\n          {\n            label: 'Provider Settings',\n            fields: [\n              {\n                name: 'provider',\n                type: 'select',\n                label: 'Email Provider',\n                required: true,\n                options: [\n                  { label: 'Resend', value: 'resend' },\n                  { label: 'Broadcast (Self-Hosted)', value: 'broadcast' },\n                ],\n                defaultValue: pluginConfig.providers.default,\n                admin: {\n                  description: 'Choose which email service to use',\n                },\n              },\n              {\n                name: 'resendSettings',\n                type: 'group',\n                label: 'Resend Settings',\n                admin: {\n                  condition: (data) => data?.provider === 'resend',\n                },\n                fields: [\n                  {\n                    name: 'apiKey',\n                    type: 'text',\n                    label: 'API Key',\n                    required: true,\n                    admin: {\n                      description: 'Your Resend API key',\n                    },\n                  },\n                  {\n                    name: 'audienceIds',\n                    type: 'array',\n                    label: 'Audience IDs by Locale',\n                    fields: [\n                      {\n                        name: 'locale',\n                        type: 'select',\n                        label: 'Locale',\n                        required: true,\n                        options: pluginConfig.i18n?.locales?.map(locale => ({\n                          label: locale.toUpperCase(),\n                          value: locale,\n                        })) || [\n                          { label: 'EN', value: 'en' },\n                        ],\n                      },\n                      {\n                        name: 'production',\n                        type: 'text',\n                        label: 'Production Audience ID',\n                      },\n                      {\n                        name: 'development',\n                        type: 'text',\n                        label: 'Development Audience ID',\n                      },\n                    ],\n                  },\n                ],\n              },\n              {\n                name: 'broadcastSettings',\n                type: 'group',\n                label: 'Broadcast Settings',\n                admin: {\n                  condition: (data) => data?.provider === 'broadcast',\n                },\n                fields: [\n                  {\n                    name: 'apiUrl',\n                    type: 'text',\n                    label: 'API URL',\n                    required: true,\n                    admin: {\n                      description: 'Your Broadcast instance URL',\n                    },\n                  },\n                  {\n                    name: 'productionToken',\n                    type: 'text',\n                    label: 'Production Token',\n                    admin: {\n                      description: 'Token for production environment',\n                    },\n                  },\n                  {\n                    name: 'developmentToken',\n                    type: 'text',\n                    label: 'Development Token',\n                    admin: {\n                      description: 'Token for development environment',\n                    },\n                  },\n                ],\n              },\n              {\n                name: 'fromAddress',\n                type: 'email',\n                label: 'From Address',\n                required: true,\n                admin: {\n                  description: 'Default sender email address',\n                },\n              },\n              {\n                name: 'fromName',\n                type: 'text',\n                label: 'From Name',\n                required: true,\n                admin: {\n                  description: 'Default sender name',\n                },\n              },\n              {\n                name: 'replyTo',\n                type: 'email',\n                label: 'Reply-To Address',\n                admin: {\n                  description: 'Optional reply-to email address',\n                },\n              },\n            ],\n          },\n          {\n            label: 'Email Templates',\n            fields: [\n              {\n                name: 'emailTemplates',\n                type: 'group',\n                label: 'Email Templates',\n                fields: [\n                  {\n                    name: 'welcome',\n                    type: 'group',\n                    label: 'Welcome Email',\n                    fields: [\n                      {\n                        name: 'enabled',\n                        type: 'checkbox',\n                        label: 'Send Welcome Email',\n                        defaultValue: true,\n                      },\n                      {\n                        name: 'subject',\n                        type: 'text',\n                        label: 'Subject Line',\n                        defaultValue: 'Welcome to {{fromName}}!',\n                        admin: {\n                          condition: (data) => data?.emailTemplates?.welcome?.enabled,\n                        },\n                      },\n                      {\n                        name: 'preheader',\n                        type: 'text',\n                        label: 'Preheader Text',\n                        admin: {\n                          condition: (data) => data?.emailTemplates?.welcome?.enabled,\n                        },\n                      },\n                    ],\n                  },\n                  {\n                    name: 'magicLink',\n                    type: 'group',\n                    label: 'Magic Link Email',\n                    fields: [\n                      {\n                        name: 'subject',\n                        type: 'text',\n                        label: 'Subject Line',\n                        defaultValue: 'Sign in to {{fromName}}',\n                      },\n                      {\n                        name: 'preheader',\n                        type: 'text',\n                        label: 'Preheader Text',\n                        defaultValue: 'Click the link to access your preferences',\n                      },\n                      {\n                        name: 'expirationTime',\n                        type: 'select',\n                        label: 'Link Expiration',\n                        defaultValue: '7d',\n                        options: [\n                          { label: '1 hour', value: '1h' },\n                          { label: '24 hours', value: '24h' },\n                          { label: '7 days', value: '7d' },\n                          { label: '30 days', value: '30d' },\n                        ],\n                      },\n                    ],\n                  },\n                ],\n              },\n            ],\n          },\n          {\n            label: 'Subscription Settings',\n            fields: [\n              {\n                name: 'subscriptionSettings',\n                type: 'group',\n                label: 'Subscription Settings',\n                fields: [\n                  {\n                    name: 'requireDoubleOptIn',\n                    type: 'checkbox',\n                    label: 'Require Double Opt-In',\n                    defaultValue: false,\n                    admin: {\n                      description: 'Require email confirmation before activating subscriptions',\n                    },\n                  },\n                  {\n                    name: 'allowedDomains',\n                    type: 'array',\n                    label: 'Allowed Email Domains',\n                    admin: {\n                      description: 'Leave empty to allow all domains',\n                    },\n                    fields: [\n                      {\n                        name: 'domain',\n                        type: 'text',\n                        label: 'Domain',\n                        required: true,\n                        admin: {\n                          placeholder: 'example.com',\n                        },\n                      },\n                    ],\n                  },\n                  {\n                    name: 'maxSubscribersPerIP',\n                    type: 'number',\n                    label: 'Max Subscribers per IP',\n                    defaultValue: 10,\n                    min: 1,\n                    admin: {\n                      description: 'Maximum number of subscriptions allowed from a single IP address',\n                    },\n                  },\n                ],\n              },\n            ],\n          },\n        ],\n      },\n    ],\n    hooks: {\n      beforeChange: [\n        async ({ data, req }) => {\n          // Verify admin access for settings changes\n          if (!req.user || req.user.collection !== 'users') {\n            throw new Error('Only administrators can modify newsletter settings')\n          }\n          \n          return data\n        },\n      ],\n      afterChange: [\n        async ({ doc, req }) => {\n          // Reinitialize email service when settings change\n          if ((req.payload as any).newsletterEmailService) {\n            try {\n              // TODO: Implement email service reinitialization\n              console.warn('Newsletter settings updated, reinitializing service...')\n            } catch {\n              // Failed to reinitialize email service\n            }\n          }\n          \n          return doc\n        },\n      ],\n    },\n    access: {\n      read: () => true, // Settings can be read publicly for validation\n      update: adminOnly(pluginConfig),\n    },\n  }\n}","import { Resend } from 'resend'\nimport type { EmailProvider, SendEmailParams } from './types'\nimport { EmailProviderError } from './types'\nimport type { Subscriber, ResendProviderConfig } from '../types'\n\nexport class ResendProvider implements EmailProvider {\n  private client: Resend\n  private audienceIds: ResendProviderConfig['audienceIds']\n  private fromAddress: string\n  private fromName: string\n  private isDevelopment: boolean\n\n  constructor(config: ResendProviderConfig & { \n    fromAddress: string\n    fromName: string \n  }) {\n    this.client = new Resend(config.apiKey)\n    this.audienceIds = config.audienceIds || {}\n    this.fromAddress = config.fromAddress\n    this.fromName = config.fromName\n    this.isDevelopment = process.env.NODE_ENV !== 'production'\n  }\n\n  getProvider(): string {\n    return 'resend'\n  }\n\n  async send(params: SendEmailParams): Promise<void> {\n    try {\n      const from = params.from || {\n        email: this.fromAddress,\n        name: this.fromName,\n      }\n\n      if (!params.html && !params.text) {\n        throw new Error('Either html or text content is required')\n      }\n\n      await this.client.emails.send({\n        from: `${from.name} <${from.email}>`,\n        to: Array.isArray(params.to) ? params.to : [params.to],\n        subject: params.subject,\n        html: params.html || '',\n        text: params.text,\n        replyTo: params.replyTo,\n      })\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to send email via Resend: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'resend',\n        error\n      )\n    }\n  }\n\n  async addContact(contact: Subscriber): Promise<void> {\n    try {\n      const audienceId = this.getAudienceId(contact.locale)\n      if (!audienceId) {\n        console.warn(`No audience ID configured for locale: ${contact.locale}`)\n        return\n      }\n\n      await this.client.contacts.create({\n        email: contact.email,\n        firstName: contact.name?.split(' ')[0],\n        lastName: contact.name?.split(' ').slice(1).join(' '),\n        unsubscribed: contact.subscriptionStatus === 'unsubscribed',\n        audienceId,\n      })\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to add contact to Resend: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'resend',\n        error\n      )\n    }\n  }\n\n  async updateContact(contact: Subscriber): Promise<void> {\n    try {\n      const audienceId = this.getAudienceId(contact.locale)\n      if (!audienceId) {\n        console.warn(`No audience ID configured for locale: ${contact.locale}`)\n        return\n      }\n\n      // Resend requires finding the contact first\n      const contacts = await this.client.contacts.list({ audienceId })\n      const existingContact = contacts.data?.data?.find(c => c.email === contact.email)\n\n      if (existingContact) {\n        await this.client.contacts.update({\n          id: existingContact.id,\n          audienceId,\n          firstName: contact.name?.split(' ')[0],\n          lastName: contact.name?.split(' ').slice(1).join(' '),\n          unsubscribed: contact.subscriptionStatus === 'unsubscribed',\n        })\n      } else {\n        // If contact doesn't exist, add them\n        await this.addContact(contact)\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to update contact in Resend: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'resend',\n        error\n      )\n    }\n  }\n\n  async removeContact(email: string): Promise<void> {\n    try {\n      // Resend doesn't have a direct remove method, so we unsubscribe instead\n      // First, we need to find the contact across all audiences\n      for (const locale in this.audienceIds) {\n        const audienceId = this.getAudienceId(locale)\n        if (!audienceId) continue\n\n        const contacts = await this.client.contacts.list({ audienceId })\n        const contact = contacts.data?.data?.find(c => c.email === email)\n\n        if (contact) {\n          await this.client.contacts.update({\n            id: contact.id,\n            audienceId,\n            unsubscribed: true,\n          })\n          break\n        }\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to remove contact from Resend: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'resend',\n        error\n      )\n    }\n  }\n\n  private getAudienceId(locale?: string): string | undefined {\n    const localeKey = locale || 'en'\n    if (!this.audienceIds) return undefined\n    \n    const localeConfig = this.audienceIds[localeKey]\n    if (!localeConfig) return undefined\n\n    const audienceId = this.isDevelopment \n      ? (localeConfig.development || localeConfig.production)\n      : (localeConfig.production || localeConfig.development)\n    \n    return audienceId\n  }\n}","import type { Subscriber } from '../types'\n\nexport interface EmailProvider {\n  send(params: SendEmailParams): Promise<void>\n  addContact(contact: Subscriber): Promise<void>\n  updateContact(contact: Subscriber): Promise<void>\n  removeContact(email: string): Promise<void>\n  getProvider(): string\n}\n\nexport interface SendEmailParams {\n  to: string | string[]\n  subject: string\n  html?: string\n  text?: string\n  react?: React.ReactElement\n  from?: {\n    email: string\n    name?: string\n  }\n  replyTo?: string\n}\n\nexport interface EmailServiceConfig {\n  provider: 'resend' | 'broadcast' | string\n  fromAddress: string\n  fromName: string\n  replyTo?: string\n  resend?: {\n    apiKey: string\n    audienceIds?: Record<string, { production?: string; development?: string }>\n  }\n  broadcast?: {\n    apiUrl: string\n    tokens: {\n      production?: string\n      development?: string\n    }\n  }\n}\n\nexport class EmailProviderError extends Error {\n  provider: string\n  originalError?: any\n\n  constructor(message: string, provider: string, originalError?: any) {\n    super(message)\n    this.name = 'EmailProviderError'\n    this.provider = provider\n    this.originalError = originalError\n  }\n}","import type { EmailProvider, SendEmailParams } from './types'\nimport { EmailProviderError } from './types'\nimport type { Subscriber, BroadcastProviderConfig } from '../types'\n\nexport class BroadcastProvider implements EmailProvider {\n  private apiUrl: string\n  private token: string\n  private fromAddress: string\n  private fromName: string\n  private isDevelopment: boolean\n\n  constructor(config: BroadcastProviderConfig & { \n    fromAddress: string\n    fromName: string \n  }) {\n    this.apiUrl = config.apiUrl.replace(/\\/$/, '') // Remove trailing slash\n    this.isDevelopment = process.env.NODE_ENV !== 'production'\n    this.token = this.isDevelopment \n      ? config.tokens.development || config.tokens.production || ''\n      : config.tokens.production || config.tokens.development || ''\n    this.fromAddress = config.fromAddress\n    this.fromName = config.fromName\n  }\n\n  getProvider(): string {\n    return 'broadcast'\n  }\n\n  async send(params: SendEmailParams): Promise<void> {\n    try {\n      const from = params.from || {\n        email: this.fromAddress,\n        name: this.fromName,\n      }\n\n      const recipients = Array.isArray(params.to) ? params.to : [params.to]\n      \n      // Broadcast expects a specific format\n      const response = await fetch(`${this.apiUrl}/api/v1/emails`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          from_email: from.email,\n          from_name: from.name,\n          to: recipients,\n          subject: params.subject,\n          html_body: params.html,\n          text_body: params.text,\n          reply_to: params.replyTo,\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to send email via Broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'broadcast',\n        error\n      )\n    }\n  }\n\n  async addContact(contact: Subscriber): Promise<void> {\n    try {\n      const [firstName, ...lastNameParts] = (contact.name || '').split(' ')\n      const lastName = lastNameParts.join(' ')\n\n      const response = await fetch(`${this.apiUrl}/api/v1/subscribers.json`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          subscriber: {\n            email: contact.email,\n            first_name: firstName || undefined,\n            last_name: lastName || undefined,\n            tags: [`lang:${contact.locale || 'en'}`],\n            is_active: contact.subscriptionStatus === 'active',\n            source: contact.source,\n          },\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to add contact to Broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'broadcast',\n        error\n      )\n    }\n  }\n\n  async updateContact(contact: Subscriber): Promise<void> {\n    try {\n      // First, try to find the contact\n      const searchResponse = await fetch(\n        `${this.apiUrl}/api/v1/subscribers/find.json?email=${encodeURIComponent(contact.email)}`,\n        {\n          headers: {\n            'Authorization': `Bearer ${this.token}`,\n          },\n        }\n      )\n\n      if (!searchResponse.ok) {\n        // If contact doesn't exist, create it\n        await this.addContact(contact)\n        return\n      }\n\n      const existingContact = await searchResponse.json()\n\n      if (!existingContact || !existingContact.id) {\n        await this.addContact(contact)\n        return\n      }\n\n      const [firstName, ...lastNameParts] = (contact.name || '').split(' ')\n      const lastName = lastNameParts.join(' ')\n\n      // Update existing contact\n      const response = await fetch(`${this.apiUrl}/api/v1/subscribers.json`, {\n        method: 'PATCH',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          email: contact.email,\n          subscriber: {\n            first_name: firstName || undefined,\n            last_name: lastName || undefined,\n            tags: [`lang:${contact.locale || 'en'}`],\n            is_active: contact.subscriptionStatus === 'active',\n            source: contact.source,\n          },\n        }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to update contact in Broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'broadcast',\n        error\n      )\n    }\n  }\n\n  async removeContact(email: string): Promise<void> {\n    try {\n      // First, find the contact\n      const searchResponse = await fetch(\n        `${this.apiUrl}/api/v1/subscribers/find.json?email=${encodeURIComponent(email)}`,\n        {\n          headers: {\n            'Authorization': `Bearer ${this.token}`,\n          },\n        }\n      )\n\n      if (!searchResponse.ok) {\n        // Contact doesn't exist, nothing to remove\n        return\n      }\n\n      const contact = await searchResponse.json()\n\n      if (!contact || !contact.id) {\n        return\n      }\n\n      // Deactivate the contact\n      const response = await fetch(`${this.apiUrl}/api/v1/subscribers/deactivate.json`, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${this.token}`,\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({ email }),\n      })\n\n      if (!response.ok) {\n        const error = await response.text()\n        throw new Error(`Broadcast API error: ${response.status} - ${error}`)\n      }\n    } catch (error: unknown) {\n      throw new EmailProviderError(\n        `Failed to remove contact from Broadcast: ${error instanceof Error ? error.message : 'Unknown error'}`,\n        'broadcast',\n        error\n      )\n    }\n  }\n}","import type { EmailProvider, EmailServiceConfig, SendEmailParams } from './types'\nimport type { Subscriber } from '../types'\nimport { ResendProvider } from './resend'\nimport { BroadcastProvider } from './broadcast'\n\nexport * from './types'\n\nexport class EmailService {\n  private provider: EmailProvider\n\n  constructor(config: EmailServiceConfig) {\n    this.provider = this.createProvider(config)\n  }\n\n  private createProvider(config: EmailServiceConfig): EmailProvider {\n    const baseConfig = {\n      fromAddress: config.fromAddress,\n      fromName: config.fromName,\n    }\n\n    switch (config.provider) {\n      case 'resend':\n        if (!config.resend) {\n          throw new Error('Resend configuration is required when using Resend provider')\n        }\n        return new ResendProvider({\n          ...config.resend,\n          ...baseConfig,\n        })\n\n      case 'broadcast':\n        if (!config.broadcast) {\n          throw new Error('Broadcast configuration is required when using Broadcast provider')\n        }\n        return new BroadcastProvider({\n          ...config.broadcast,\n          ...baseConfig,\n        })\n\n      default:\n        throw new Error(`Unknown email provider: ${config.provider}`)\n    }\n  }\n\n  async send(params: SendEmailParams): Promise<void> {\n    return this.provider.send(params)\n  }\n\n  async addContact(contact: Subscriber): Promise<void> {\n    return this.provider.addContact(contact)\n  }\n\n  async updateContact(contact: Subscriber): Promise<void> {\n    return this.provider.updateContact(contact)\n  }\n\n  async removeContact(email: string): Promise<void> {\n    return this.provider.removeContact(email)\n  }\n\n  getProvider(): string {\n    return this.provider.getProvider()\n  }\n\n  /**\n   * Update the provider configuration\n   * Useful when settings are changed in the admin UI\n   */\n  updateConfig(config: EmailServiceConfig): void {\n    this.provider = this.createProvider(config)\n  }\n}\n\n/**\n * Create email service from plugin configuration\n */\nexport function createEmailService(config: EmailServiceConfig): EmailService {\n  return new EmailService(config)\n}","import DOMPurify from 'isomorphic-dompurify'\n\n/**\n * Validate email address format\n */\nexport function isValidEmail(email: string): boolean {\n  if (!email || typeof email !== 'string') return false\n  \n  // Trim whitespace\n  const trimmed = email.trim()\n  \n  // Length limits\n  if (trimmed.length > 255) return false\n  \n  // Check for dangerous patterns\n  if (trimmed.includes('<') || trimmed.includes('>')) return false\n  if (trimmed.includes('javascript:')) return false\n  if (trimmed.includes('data:')) return false\n  \n  // Basic format validation with stricter regex\n  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/\n  if (!emailRegex.test(trimmed)) return false\n  \n  // Additional validation rules\n  const parts = trimmed.split('@')\n  if (parts.length !== 2) return false\n  \n  const [localPart, domain] = parts\n  \n  // Check local part length\n  if (localPart.length > 64 || localPart.length === 0) return false\n  \n  // Check for invalid patterns\n  if (localPart.startsWith('.') || localPart.endsWith('.')) return false\n  if (domain.startsWith('.') || domain.endsWith('.')) return false\n  if (domain.includes('..')) return false\n  if (localPart.includes('..')) return false\n  \n  return true\n}\n\n/**\n * Normalize email for rate limiting and deduplication\n */\nexport function normalizeEmail(email: string): string {\n  if (!email || typeof email !== 'string') return ''\n  \n  const parts = email.toLowerCase().trim().split('@')\n  if (parts.length !== 2) return email.toLowerCase().trim()\n  \n  let [localPart] = parts\n  const [, domain] = parts\n  \n  // Remove dots from local part (Gmail-style)\n  localPart = localPart.replace(/\\./g, '')\n  \n  // Remove everything after + (Gmail-style aliases)\n  const plusIndex = localPart.indexOf('+')\n  if (plusIndex > -1) {\n    localPart = localPart.substring(0, plusIndex)\n  }\n  \n  return `${localPart}@${domain}`\n}\n\n/**\n * Check if email domain is allowed\n */\nexport function isDomainAllowed(\n  email: string,\n  allowedDomains?: string[]\n): boolean {\n  // Validate email format first\n  if (!isValidEmail(email)) {\n    return false\n  }\n  \n  // If no domains specified, allow all valid emails\n  if (!allowedDomains || allowedDomains.length === 0) {\n    return true\n  }\n\n  const domain = email.split('@')[1]?.toLowerCase()\n  if (!domain) return false\n\n  return allowedDomains.some(\n    allowedDomain => domain === allowedDomain.toLowerCase()\n  )\n}\n\n/**\n * Sanitize user input to prevent XSS\n */\nexport function sanitizeInput(input: string): string {\n  if (!input) return ''\n  \n  // First, remove all HTML tags and scripts\n  let cleaned = DOMPurify.sanitize(input, { \n    ALLOWED_TAGS: [],\n    ALLOWED_ATTR: [],\n    KEEP_CONTENT: true\n  })\n  \n  // Additional security: remove dangerous patterns\n  cleaned = cleaned\n    .replace(/javascript:/gi, '')\n    .replace(/data:/gi, '')\n    .replace(/vbscript:/gi, '')\n    .replace(/file:\\/\\//gi, '')\n    .replace(/onload/gi, '')\n    .replace(/onerror/gi, '')\n    .replace(/onclick/gi, '')\n    .replace(/onmouseover/gi, '')\n    .replace(/alert\\(/gi, '')\n    .replace(/prompt\\(/gi, '')\n    .replace(/confirm\\(/gi, '')\n    .replace(/\\|/g, '') // Remove pipe character (command injection)\n    .replace(/;/g, '') // Remove semicolon (command chaining)\n    .replace(/`/g, '') // Remove backticks (command substitution)\n    .replace(/&&/g, '') // Remove command chaining\n    .replace(/\\$\\(/g, '') // Remove command substitution pattern $()\n    .replace(/\\.\\./g, '') // Remove directory traversal\n    .replace(/\\/..\\//g, '') // Remove path traversal\n    .replace(/\\0/g, '') // Remove null bytes\n  \n  return cleaned.trim()\n}\n\n/**\n * Extract UTM parameters from URL search params\n */\nexport function extractUTMParams(searchParams: URLSearchParams): Record<string, string> {\n  const utmParams: Record<string, string> = {}\n  const utmKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term']\n\n  utmKeys.forEach(key => {\n    const value = searchParams.get(key)\n    if (value) {\n      // Remove 'utm_' prefix for storage\n      const shortKey = key.replace('utm_', '')\n      utmParams[shortKey] = value\n    }\n  })\n\n  return utmParams\n}\n\n/**\n * Validate source field - only allow predefined values\n */\nexport function isValidSource(source: string): boolean {\n  if (!source || typeof source !== 'string') return false\n  \n  const allowedSources = [\n    'website',\n    'api',\n    'import',\n    'admin',\n    'signup-form',\n    'magic-link',\n    'preferences',\n    'external'\n  ]\n  \n  return allowedSources.includes(source)\n}\n\n/**\n * Validate subscriber data before creation\n */\nexport interface ValidateSubscriberResult {\n  valid: boolean\n  errors: string[]\n}\n\nexport function validateSubscriberData(data: any): ValidateSubscriberResult {\n  const errors: string[] = []\n\n  // Email validation\n  if (!data.email) {\n    errors.push('Email is required')\n  } else if (!isValidEmail(data.email)) {\n    errors.push('Invalid email format')\n  }\n\n  // Name validation (optional but if provided, should be reasonable)\n  if (data.name && data.name.length > 100) {\n    errors.push('Name is too long (max 100 characters)')\n  }\n\n  // Source validation\n  if (data.source !== undefined) {\n    if (!data.source || data.source.length === 0) {\n      errors.push('Source cannot be empty')\n    } else if (data.source.length > 50) {\n      errors.push('Source is too long (max 50 characters)')\n    } else if (!isValidSource(data.source)) {\n      errors.push('Invalid source value')\n    }\n  }\n\n  return {\n    valid: errors.length === 0,\n    errors,\n  }\n}","import jwt from 'jsonwebtoken'\nimport type { NewsletterPluginConfig } from '../types'\n\nexport interface MagicLinkTokenPayload {\n  subscriberId: string\n  email: string\n  type: 'magic-link'\n}\n\nexport interface SessionTokenPayload {\n  subscriberId: string\n  email: string\n  type: 'session'\n}\n\n/**\n * Get JWT secret from environment or generate a warning\n */\nfunction getJWTSecret(): string {\n  const secret = process.env.JWT_SECRET || process.env.PAYLOAD_SECRET\n\n  if (!secret) {\n    console.warn(\n      'WARNING: No JWT_SECRET or PAYLOAD_SECRET found in environment variables. ' +\n      'Magic link authentication will not work properly. ' +\n      'Please set JWT_SECRET in your environment.'\n    )\n    // Return a placeholder to prevent crashes during development\n    return 'INSECURE_DEVELOPMENT_SECRET_PLEASE_SET_JWT_SECRET'\n  }\n\n  return secret\n}\n\n/**\n * Generate a magic link token for email authentication\n */\nexport function generateMagicLinkToken(\n  subscriberId: string,\n  email: string,\n  config: NewsletterPluginConfig\n): string {\n  const payload: MagicLinkTokenPayload = {\n    subscriberId,\n    email,\n    type: 'magic-link',\n  }\n\n  const expiresIn = config.auth?.tokenExpiration || '7d'\n\n  return jwt.sign(payload, getJWTSecret(), {\n    expiresIn: expiresIn,\n    issuer: 'payload-newsletter-plugin',\n  } as jwt.SignOptions)\n}\n\n/**\n * Verify a magic link token\n */\nexport function verifyMagicLinkToken(token: string): MagicLinkTokenPayload {\n  try {\n    const payload = jwt.verify(token, getJWTSecret(), {\n      issuer: 'payload-newsletter-plugin',\n    }) as any\n\n    if (payload.type !== 'magic-link') {\n      throw new Error('Invalid token type')\n    }\n\n    return payload as MagicLinkTokenPayload\n  } catch (error: unknown) {\n    if (error instanceof Error && error.name === 'TokenExpiredError') {\n      throw new Error('Magic link has expired. Please request a new one.')\n    }\n    if (error instanceof Error && error.name === 'JsonWebTokenError') {\n      throw new Error('Invalid magic link token')\n    }\n    throw error\n  }\n}\n\n/**\n * Generate a session token after successful magic link verification\n */\nexport function generateSessionToken(\n  subscriberId: string,\n  email: string\n): string {\n  const payload: SessionTokenPayload = {\n    subscriberId,\n    email,\n    type: 'session',\n  }\n\n  return jwt.sign(payload, getJWTSecret(), {\n    expiresIn: '30d',\n    issuer: 'payload-newsletter-plugin',\n  })\n}\n\n/**\n * Verify a session token\n */\nexport function verifySessionToken(token: string): SessionTokenPayload {\n  try {\n    const payload = jwt.verify(token, getJWTSecret(), {\n      issuer: 'payload-newsletter-plugin',\n    }) as any\n\n    if (payload.type !== 'session') {\n      throw new Error('Invalid token type')\n    }\n\n    return payload as SessionTokenPayload\n  } catch (error: unknown) {\n    if (error instanceof Error && error.name === 'TokenExpiredError') {\n      throw new Error('Session has expired. Please sign in again.')\n    }\n    if (error instanceof Error && error.name === 'JsonWebTokenError') {\n      throw new Error('Invalid session token')\n    }\n    throw error\n  }\n}\n\n/**\n * Generate a magic link URL\n */\nexport function generateMagicLinkURL(\n  token: string,\n  baseURL: string,\n  config: NewsletterPluginConfig\n): string {\n  const path = config.auth?.magicLinkPath || '/newsletter/verify'\n  const url = new URL(path, baseURL)\n  url.searchParams.set('token', token)\n  return url.toString()\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, Subscriber, SubscribeRequestData, ExtendedPayloadRequest } from '../types'\nimport { \n  isDomainAllowed, \n  sanitizeInput, \n  validateSubscriberData,\n  extractUTMParams \n} from '../utils/validation'\nimport { generateMagicLinkToken, generateMagicLinkURL } from '../utils/jwt'\nimport { renderEmail } from '../emails/render'\n\nexport const createSubscribeEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/subscribe',\n    method: 'post',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        const data = await req.json()\n        const { \n          email, \n          name, \n          source,\n          preferences,\n          leadMagnet,\n          surveyResponses,\n          metadata = {}\n        } = data as SubscribeRequestData\n\n        // Trim email before validation\n        const trimmedEmail = email?.trim()\n\n        // Validate input\n        const validation = validateSubscriberData({ email: trimmedEmail, name, source })\n        if (!validation.valid) {\n          return Response.json({\n            success: false,\n            errors: validation.errors,\n          }, { status: 400 })\n        }\n\n        // Check domain restrictions from global settings\n        // Settings are public info needed for validation, but we can still respect access control\n        const settings = await req.payload.findGlobal({\n          slug: config.settingsSlug || 'newsletter-settings',\n          overrideAccess: false,\n          // No user context for public endpoint\n        })\n\n        const allowedDomains = settings?.subscriptionSettings?.allowedDomains?.map((d: { domain: string }) => d.domain) || []\n        if (!isDomainAllowed(trimmedEmail, allowedDomains)) {\n          return Response.json({\n            success: false,\n            error: 'Email domain not allowed',\n          }, { status: 400 })\n        }\n\n        // Check if already subscribed\n        // This needs admin access to check for existing email\n        const existing = await req.payload.find({\n          collection: config.subscribersSlug || 'subscribers',\n          where: {\n            email: {\n              equals: trimmedEmail.toLowerCase(),\n            },\n          },\n          overrideAccess: true, // Need to check for duplicates in public endpoint\n        })\n\n        if (existing.docs.length > 0) {\n          const subscriber = existing.docs[0]\n          \n          // If unsubscribed, don't allow resubscription via API\n          if (subscriber.subscriptionStatus === 'unsubscribed') {\n            return Response.json({\n              success: false,\n              error: 'This email has been unsubscribed. Please contact support to resubscribe.',\n            }, { status: 400 })\n          }\n\n          return Response.json({\n            success: false,\n            error: 'Already subscribed',\n            subscriber: {\n              id: subscriber.id,\n              email: subscriber.email,\n              subscriptionStatus: subscriber.subscriptionStatus,\n            },\n          }, { status: 400 })\n        }\n\n        // Check IP rate limiting\n        const ipAddress = req.ip || req.connection?.remoteAddress\n        const maxPerIP = settings?.subscriptionSettings?.maxSubscribersPerIP || 10\n\n        const ipSubscribers = await req.payload.find({\n          collection: config.subscribersSlug || 'subscribers',\n          where: {\n            'signupMetadata.ipAddress': {\n              equals: ipAddress,\n            },\n          },\n          overrideAccess: true, // Need to check IP limits in public endpoint\n        })\n\n        if (ipSubscribers.docs.length >= maxPerIP) {\n          return Response.json({\n            success: false,\n            error: 'Too many subscriptions from this IP address',\n          }, { status: 429 })\n        }\n\n        // Extract UTM parameters\n        const referer = req.headers.get('referer') || req.headers.get('referrer') || ''\n        let utmParams = {}\n        if (referer) {\n          try {\n            utmParams = extractUTMParams(new URL(referer).searchParams)\n          } catch {\n            // Invalid URL, ignore UTM params\n          }\n        }\n\n        // Prepare subscriber data\n        const subscriberData: Partial<Subscriber> = {\n          email: trimmedEmail.toLowerCase(),\n          name: name ? sanitizeInput(name) : undefined,\n          locale: metadata.locale || config.i18n?.defaultLocale || 'en',\n          subscriptionStatus: settings?.subscriptionSettings?.requireDoubleOptIn ? 'pending' : 'active',\n          source: source || 'api',\n          emailPreferences: {\n            newsletter: true,\n            announcements: true,\n            ...(preferences || {}),\n          },\n          signupMetadata: {\n            ipAddress,\n            userAgent: req.headers.get('user-agent') || undefined,\n            referrer: referer,\n            signupPage: metadata.signupPage || referer,\n          },\n        }\n\n        // Add UTM parameters if tracking is enabled\n        if (config.features?.utmTracking?.enabled && Object.keys(utmParams).length > 0) {\n          subscriberData.utmParameters = utmParams\n        }\n\n        // Add lead magnet if provided\n        if (config.features?.leadMagnets?.enabled && leadMagnet) {\n          subscriberData.leadMagnet = leadMagnet\n        }\n\n        // Create subscriber\n        // Public endpoint needs to create subscribers\n        const subscriber = await req.payload.create({\n          collection: config.subscribersSlug || 'subscribers',\n          data: subscriberData,\n          overrideAccess: true, // Public endpoint needs to create subscribers\n        })\n\n        // Handle survey responses if provided\n        if (config.features?.surveys?.enabled && surveyResponses) {\n          // TODO: Store survey responses\n        }\n\n        // Send confirmation email if double opt-in\n        if (settings?.subscriptionSettings?.requireDoubleOptIn) {\n          try {\n            // Generate magic link token\n            const token = generateMagicLinkToken(\n              String(subscriber.id),\n              subscriber.email,\n              config\n            )\n            \n            // Generate magic link URL\n            const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || ''\n            const magicLinkURL = generateMagicLinkURL(token, serverURL, config)\n            \n            // Get email service\n            const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n            \n            if (emailService) {\n              // Render email\n              const html = await renderEmail('magic-link', {\n                magicLink: magicLinkURL,\n                email: subscriber.email,\n                siteName: settings?.brandSettings?.siteName || 'Newsletter',\n                expiresIn: config.auth?.tokenExpiration || '7d',\n              })\n              \n              // Send email\n              await emailService.send({\n                to: subscriber.email,\n                subject: settings?.brandSettings?.siteName ? `Verify your email for ${settings.brandSettings.siteName}` : 'Verify your email',\n                html,\n              })\n              \n              // Magic link email sent successfully\n            } else {\n              console.warn('Email service not initialized, cannot send magic link')\n            }\n          } catch (error) {\n            console.error('Failed to send magic link email:', error)\n            // Don't fail the subscription if email fails\n          }\n        }\n\n        return Response.json({\n          success: true,\n          subscriber: {\n            id: subscriber.id,\n            email: subscriber.email,\n            subscriptionStatus: subscriber.subscriptionStatus,\n          },\n          message: settings?.subscriptionSettings?.requireDoubleOptIn \n            ? 'Please check your email to confirm your subscription'\n            : 'Successfully subscribed',\n        })\n      } catch {\n        return Response.json({\n          success: false,\n          error: 'Failed to subscribe. Please try again.',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, VerifyMagicLinkRequestData, ExtendedPayloadRequest } from '../types'\nimport { \n  verifyMagicLinkToken, \n  generateSessionToken \n} from '../utils/jwt'\nimport { renderEmail } from '../emails/render'\n\nexport const createVerifyMagicLinkEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/verify-magic-link',\n    method: 'post',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        const data = await req.json()\n        const { token } = data as VerifyMagicLinkRequestData\n\n        if (!token) {\n          return Response.json({\n            success: false,\n            error: 'Token is required',\n          }, { status: 400 })\n        }\n\n        // Verify the magic link token\n        let payload\n        try {\n          payload = verifyMagicLinkToken(token)\n        } catch (error: unknown) {\n          return Response.json({\n            success: false,\n            error: error instanceof Error ? error.message : 'Invalid token',\n          }, { status: 401 })\n        }\n\n        // Find the subscriber - token verified so we can use admin access for initial lookup\n        const subscriber = await req.payload.findByID({\n          collection: config.subscribersSlug || 'subscribers',\n          id: payload.subscriberId,\n          // Keep overrideAccess: true for token verification\n        })\n\n        if (!subscriber) {\n          return Response.json({\n            success: false,\n            error: 'Subscriber not found',\n          }, { status: 404 })\n        }\n\n        // Check if email matches\n        if (subscriber.email !== payload.email) {\n          return Response.json({\n            success: false,\n            error: 'Invalid token',\n          }, { status: 401 })\n        }\n\n        // Check if subscriber is active\n        if (subscriber.subscriptionStatus === 'unsubscribed') {\n          return Response.json({\n            success: false,\n            error: 'This email has been unsubscribed',\n          }, { status: 403 })\n        }\n\n        // Create synthetic user for subscriber operations\n        const syntheticUser = {\n          collection: 'subscribers',\n          id: subscriber.id,\n          email: subscriber.email,\n        }\n\n        // Update subscription status if pending\n        let isNewlyActivated = false\n        if (subscriber.subscriptionStatus === 'pending') {\n          await req.payload.update({\n            collection: config.subscribersSlug || 'subscribers',\n            id: subscriber.id,\n            data: {\n              subscriptionStatus: 'active',\n            },\n            overrideAccess: false,\n            user: syntheticUser,\n          })\n          isNewlyActivated = true\n        }\n\n        // Clear the magic link token\n        await req.payload.update({\n          collection: config.subscribersSlug || 'subscribers',\n          id: subscriber.id,\n          data: {\n            magicLinkToken: null,\n            magicLinkTokenExpiry: null,\n          },\n          overrideAccess: false,\n          user: syntheticUser,\n        })\n\n        // Generate session token\n        const sessionToken = generateSessionToken(\n          String(subscriber.id),\n          subscriber.email\n        )\n\n        // Send welcome email if newly activated\n        if (isNewlyActivated) {\n          try {\n            // Get email service\n            const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n            \n            if (emailService) {\n              // Get settings for site name\n              const settings = await req.payload.findGlobal({\n                slug: config.settingsSlug || 'newsletter-settings',\n              })\n              \n              // Render welcome email\n              const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || ''\n              const html = await renderEmail('welcome', {\n                email: subscriber.email,\n                siteName: settings?.brandSettings?.siteName || 'Newsletter',\n                preferencesUrl: `${serverURL}/account/preferences`, // This could be customized\n              })\n              \n              // Send email\n              await emailService.send({\n                to: subscriber.email,\n                subject: settings?.brandSettings?.siteName ? `Welcome to ${settings.brandSettings.siteName}!` : 'Welcome!',\n                html,\n              })\n              \n              // Welcome email sent successfully\n            } else {\n              console.warn('Email service not initialized, cannot send welcome email')\n            }\n          } catch (error) {\n            console.error('Failed to send welcome email:', error)\n            // Don't fail the verification if welcome email fails\n          }\n        }\n\n        // Set the session cookie\n        const headers = new Headers()\n        headers.append('Set-Cookie', `newsletter-auth=${sessionToken}; HttpOnly; Secure=${process.env.NODE_ENV === 'production'}; SameSite=Lax; Path=/; Max-Age=${30 * 24 * 60 * 60}`)\n\n        return Response.json({\n          success: true,\n          sessionToken,\n          subscriber: {\n            id: subscriber.id,\n            email: subscriber.email,\n            name: subscriber.name,\n            locale: subscriber.locale,\n            emailPreferences: subscriber.emailPreferences,\n          },\n        }, { headers })\n      } catch (error: unknown) {\n        console.error('Verify magic link error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to verify magic link',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, Subscriber, UpdatePreferencesRequestData, ExtendedPayloadRequest } from '../types'\nimport { verifySessionToken } from '../utils/jwt'\n\nexport const createPreferencesEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/preferences',\n    method: 'get',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        // Get token from Authorization header\n        const authHeader = req.headers.get('authorization')\n        if (!authHeader || !authHeader.startsWith('Bearer ')) {\n          return Response.json({\n            success: false,\n            error: 'Authorization required',\n          }, { status: 401 })\n        }\n\n        const token = authHeader.substring(7)\n\n        // Verify session token\n        let payload\n        try {\n          payload = verifySessionToken(token)\n        } catch (error: unknown) {\n          return Response.json({\n            success: false,\n            error: error instanceof Error ? error.message : 'Invalid token',\n          }, { status: 401 })\n        }\n\n        // Get subscriber - use synthetic user to ensure access control\n        const subscriber = await req.payload.findByID({\n          collection: config.subscribersSlug || 'subscribers',\n          id: payload.subscriberId,\n          overrideAccess: false,\n          user: {\n            collection: 'subscribers',\n            id: payload.subscriberId,\n            email: payload.email,\n          },\n        })\n\n        if (!subscriber) {\n          return Response.json({\n            success: false,\n            error: 'Subscriber not found',\n          }, { status: 404 })\n        }\n\n        return Response.json({\n          success: true,\n          subscriber: {\n            id: subscriber.id,\n            email: subscriber.email,\n            name: subscriber.name,\n            locale: subscriber.locale,\n            emailPreferences: subscriber.emailPreferences,\n            subscriptionStatus: subscriber.subscriptionStatus,\n          },\n        })\n      } catch (error: unknown) {\n        console.error('Get preferences error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to get preferences',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}\n\nexport const createUpdatePreferencesEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/preferences',\n    method: 'post',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        // Get token from Authorization header\n        const authHeader = req.headers.get('authorization')\n        if (!authHeader || !authHeader.startsWith('Bearer ')) {\n          return Response.json({\n            success: false,\n            error: 'Authorization required',\n          }, { status: 401 })\n        }\n\n        const token = authHeader.substring(7)\n\n        // Verify session token\n        let payload\n        try {\n          payload = verifySessionToken(token)\n        } catch (error: unknown) {\n          return Response.json({\n            success: false,\n            error: error instanceof Error ? error.message : 'Invalid token',\n          }, { status: 401 })\n        }\n\n        const data = await req.json()\n        const { name, locale, emailPreferences } = data as UpdatePreferencesRequestData\n\n        // Prepare update data\n        const updateData: Partial<Subscriber> = {}\n        \n        if (name !== undefined) {\n          updateData.name = name\n        }\n        \n        if (locale !== undefined) {\n          updateData.locale = locale\n        }\n        \n        if (emailPreferences !== undefined) {\n          updateData.emailPreferences = emailPreferences\n        }\n\n        // Update subscriber - use synthetic user to ensure only updating own data\n        const subscriber = await req.payload.update({\n          collection: config.subscribersSlug || 'subscribers',\n          id: payload.subscriberId,\n          data: updateData,\n          overrideAccess: false,\n          user: {\n            collection: 'subscribers',\n            id: payload.subscriberId,\n            email: payload.email,\n          },\n        })\n\n        return Response.json({\n          success: true,\n          subscriber: {\n            id: subscriber.id,\n            email: subscriber.email,\n            name: subscriber.name,\n            locale: subscriber.locale,\n            emailPreferences: subscriber.emailPreferences,\n            subscriptionStatus: subscriber.subscriptionStatus,\n          },\n        })\n      } catch (error: unknown) {\n        console.error('Update preferences error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to update preferences',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, UnsubscribeRequestData, ExtendedPayloadRequest } from '../types'\nimport { isValidEmail } from '../utils/validation'\n\nexport const createUnsubscribeEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/unsubscribe',\n    method: 'post',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        const data = await req.json()\n        const { email, token } = data as UnsubscribeRequestData\n\n        // Two methods: email or token\n        if (!email && !token) {\n          return Response.json({\n            success: false,\n            error: 'Email or token is required',\n          }, { status: 400 })\n        }\n\n        let subscriber\n\n        if (token) {\n          // Token-based unsubscribe (from email link)\n          try {\n            const jwt = await import('jsonwebtoken')\n            const payload = jwt.verify(\n              token,\n              process.env.JWT_SECRET || process.env.PAYLOAD_SECRET || ''\n            ) as { type: string; subscriberId: string; email: string }\n\n            if (payload.type !== 'unsubscribe') {\n              throw new Error('Invalid token type')\n            }\n\n            // Token verified, so we can look up the subscriber\n            // Using overrideAccess: true here is OK since we verified the token\n            subscriber = await req.payload.findByID({\n              collection: config.subscribersSlug || 'subscribers',\n              id: payload.subscriberId,\n            })\n          } catch {\n            return Response.json({\n              success: false,\n              error: 'Invalid or expired unsubscribe link',\n            }, { status: 401 })\n          }\n        } else {\n          // Email-based unsubscribe\n          if (!email || !isValidEmail(email)) {\n            return Response.json({\n              success: false,\n              error: 'Invalid email format',\n            }, { status: 400 })\n          }\n\n          const result = await req.payload.find({\n            collection: config.subscribersSlug || 'subscribers',\n            where: {\n              email: {\n                equals: email!.toLowerCase(),\n              },\n            },\n          })\n\n          if (result.docs.length === 0) {\n            // Don't reveal if email exists or not\n            return Response.json({\n              success: true,\n              message: 'If this email was subscribed, it has been unsubscribed.',\n            })\n          }\n\n          subscriber = result.docs[0]\n        }\n\n        if (!subscriber) {\n          return Response.json({\n            success: true,\n            message: 'If this email was subscribed, it has been unsubscribed.',\n          })\n        }\n\n        // Check if already unsubscribed\n        if (subscriber.subscriptionStatus === 'unsubscribed') {\n          return Response.json({\n            success: true,\n            message: 'Already unsubscribed',\n          })\n        }\n\n        // Update subscription status - use synthetic user to ensure proper access\n        await req.payload.update({\n          collection: config.subscribersSlug || 'subscribers',\n          id: subscriber.id,\n          data: {\n            subscriptionStatus: 'unsubscribed',\n            unsubscribedAt: new Date().toISOString(),\n          },\n          overrideAccess: false,\n          user: {\n            collection: 'subscribers',\n            id: subscriber.id,\n            email: subscriber.email,\n          },\n        })\n\n        return Response.json({\n          success: true,\n          message: 'Successfully unsubscribed',\n        })\n      } catch (error: unknown) {\n        console.error('Unsubscribe error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to unsubscribe. Please try again.',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","export interface RateLimiterOptions {\n  maxAttempts: number\n  windowMs: number\n  prefix?: string\n}\n\nexport class RateLimiter {\n  private attempts: Map<string, { count: number; resetTime: number }> = new Map()\n  private options: RateLimiterOptions\n\n  constructor(options: RateLimiterOptions) {\n    this.options = options\n  }\n\n  async checkLimit(key: string): Promise<boolean> {\n    const now = Date.now()\n    const record = this.attempts.get(key)\n\n    if (!record || record.resetTime < now) {\n      this.attempts.set(key, {\n        count: 1,\n        resetTime: now + this.options.windowMs\n      })\n      return true\n    }\n\n    if (record.count >= this.options.maxAttempts) {\n      return false\n    }\n\n    record.count++\n    return true\n  }\n\n  async incrementAttempt(key: string): Promise<void> {\n    const now = Date.now()\n    const record = this.attempts.get(key)\n\n    if (!record || record.resetTime < now) {\n      this.attempts.set(key, {\n        count: 1,\n        resetTime: now + this.options.windowMs\n      })\n    } else {\n      record.count++\n    }\n  }\n\n  async reset(key: string): Promise<void> {\n    this.attempts.delete(key)\n  }\n\n  async resetAll(): Promise<void> {\n    this.attempts.clear()\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, SigninRequestData, ExtendedPayloadRequest } from '../types'\nimport { validateSubscriberData } from '../utils/validation'\nimport { generateMagicLinkToken, generateMagicLinkURL } from '../utils/jwt'\nimport { renderEmail } from '../emails/render'\nimport { RateLimiter } from '../utils/rate-limiter'\n\n// Create rate limiter: 5 attempts per 15 minutes\nconst signinRateLimiter = new RateLimiter({\n  maxAttempts: 5,\n  windowMs: 15 * 60 * 1000, // 15 minutes\n  prefix: 'signin',\n})\n\nexport const createSigninEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/signin',\n    method: 'post',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        const data = await req.json()\n        const { email } = data as SigninRequestData\n\n        // Validate email\n        const validation = validateSubscriberData({ email })\n        if (!validation.valid) {\n          return Response.json({\n            success: false,\n            errors: validation.errors,\n          }, { status: 400 })\n        }\n\n        // Check rate limit (per email to prevent abuse)\n        const rateLimitKey = `signin:${email.toLowerCase()}`\n        const allowed = await signinRateLimiter.checkLimit(rateLimitKey)\n        \n        if (!allowed) {\n          return Response.json({\n            success: false,\n            error: 'Too many sign-in attempts. Please try again later.',\n          }, { status: 429 })\n        }\n\n        // Find existing active subscriber\n        const result = await req.payload.find({\n          collection: config.subscribersSlug || 'subscribers',\n          where: {\n            email: { equals: email.toLowerCase() },\n            subscriptionStatus: { equals: 'active' },\n          },\n          limit: 1,\n          overrideAccess: true, // Need to check subscriber exists\n        })\n\n        if (result.docs.length === 0) {\n          return Response.json({\n            success: false,\n            error: 'Email not found. Please subscribe first.',\n          }, { status: 404 })\n        }\n\n        const subscriber = result.docs[0]\n\n        // Generate magic link token\n        const token = generateMagicLinkToken(\n          String(subscriber.id),\n          subscriber.email,\n          config\n        )\n\n        // Generate magic link URL\n        const serverURL = req.payload.config.serverURL || process.env.PAYLOAD_PUBLIC_SERVER_URL || ''\n        const magicLinkURL = generateMagicLinkURL(token, serverURL, config)\n\n        // Get email service\n        const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n\n        if (emailService) {\n          // Get settings for customization\n          const settings = await req.payload.findGlobal({\n            slug: config.settingsSlug || 'newsletter-settings',\n          })\n\n          // Render email\n          const html = await renderEmail('signin', {\n            magicLink: magicLinkURL,\n            email: subscriber.email,\n            siteName: settings?.brandSettings?.siteName || 'Newsletter',\n            expiresIn: config.auth?.tokenExpiration || '7d',\n          })\n\n          // Send email\n          await emailService.send({\n            to: subscriber.email,\n            subject: settings?.brandSettings?.siteName \n              ? `Sign in to ${settings.brandSettings.siteName}` \n              : 'Sign in to your account',\n            html,\n          })\n\n          // Sign-in email sent successfully\n        } else {\n          console.warn('Email service not initialized, cannot send sign-in link')\n        }\n\n        return Response.json({\n          success: true,\n          message: 'Check your email for the sign-in link',\n        })\n      } catch (error) {\n        console.error('Sign-in error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to process sign-in request',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, ExtendedPayloadRequest } from '../types'\nimport { verifySessionToken } from '../utils/jwt'\n\nexport const createMeEndpoint = (\n  config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/me',\n    method: 'get',\n    handler: (async (req: ExtendedPayloadRequest) => {\n      try {\n        // Get token from cookie header\n        const cookieHeader = req.headers.get('cookie') || ''\n        const cookies = Object.fromEntries(\n          cookieHeader.split('; ').map(c => {\n            const [key, ...value] = c.split('=')\n            return [key, value.join('=')]\n          })\n        )\n        const token = cookies['newsletter-auth']\n        \n        if (!token) {\n          return Response.json({\n            success: false,\n            error: 'Not authenticated',\n          }, { status: 401 })\n        }\n\n        // Verify the session token\n        let payload\n        try {\n          payload = verifySessionToken(token)\n        } catch {\n          return Response.json({\n            success: false,\n            error: 'Invalid or expired session',\n          }, { status: 401 })\n        }\n\n        // Get fresh subscriber data\n        const subscriber = await req.payload.findByID({\n          collection: config.subscribersSlug || 'subscribers',\n          id: payload.subscriberId,\n          overrideAccess: true, // Need to get subscriber data\n        })\n\n        if (!subscriber || subscriber.subscriptionStatus !== 'active') {\n          return Response.json({\n            success: false,\n            error: 'Not authenticated',\n          }, { status: 401 })\n        }\n\n        return Response.json({\n          success: true,\n          subscriber: {\n            id: subscriber.id,\n            email: subscriber.email,\n            name: subscriber.name,\n            status: subscriber.subscriptionStatus,\n            preferences: {\n              frequency: subscriber.emailPreferences?.frequency,\n              categories: subscriber.emailPreferences?.categories,\n            },\n            createdAt: subscriber.createdAt,\n            updatedAt: subscriber.updatedAt,\n          },\n        })\n      } catch (error) {\n        console.error('Me endpoint error:', error)\n        return Response.json({\n          success: false,\n          error: 'Internal server error',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler } from 'payload'\nimport type { NewsletterPluginConfig, ExtendedPayloadRequest } from '../types'\n\nexport const createSignoutEndpoint = (\n  _config: NewsletterPluginConfig\n): Endpoint => {\n  return {\n    path: '/newsletter/signout',\n    method: 'post',\n    handler: ((_req: ExtendedPayloadRequest) => {\n      try {\n        // In Payload v3, cookies are handled differently\n        // The Response object doesn't have a clearCookie method\n        // We'll need to set the cookie with an expired date\n        const headers = new Headers()\n        headers.append('Set-Cookie', `newsletter-auth=; HttpOnly; Secure=${process.env.NODE_ENV === 'production'}; SameSite=Lax; Path=/; Max-Age=0`)\n        \n        return Response.json({ \n          success: true, \n          message: 'Signed out successfully' \n        }, { headers })\n      } catch (error) {\n        console.error('Signout error:', error)\n        return Response.json({\n          success: false,\n          error: 'Failed to sign out',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint, PayloadHandler, PayloadRequest } from 'payload'\nimport type { NewsletterPluginConfig, SendBroadcastOptions } from '../../types'\nimport { NewsletterProviderError, NewsletterStatus } from '../../types'\nimport { requireAdmin } from '../../utils/auth'\n\nexport const createSendBroadcastEndpoint = (\n  config: NewsletterPluginConfig,\n  collectionSlug: string\n): Endpoint => {\n  return {\n    path: `/${collectionSlug}/:id/send`,\n    method: 'post',\n    handler: (async (req: PayloadRequest) => {\n      try {\n        // Check authentication\n        const auth = await requireAdmin(req, config)\n        if (!auth.authorized) {\n          return Response.json({\n            success: false,\n            error: auth.error,\n          }, { status: 401 })\n        }\n\n        // Get broadcast provider\n        const broadcastProvider = (req.payload as any).newsletterProvider\n        if (!broadcastProvider) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast management is not enabled',\n          }, { status: 400 })\n        }\n\n        // Get ID from URL\n        const url = new URL(req.url || '', `http://localhost`)\n        const pathParts = url.pathname.split('/')\n        const id = pathParts[pathParts.length - 2] // -2 because last part is 'send'\n\n        if (!id) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast ID is required',\n          }, { status: 400 })\n        }\n\n        // Parse request body\n        const data = await (req.json?.() || Promise.resolve({})) as SendBroadcastOptions\n\n        // Get the broadcast document to get the provider ID\n        const broadcastDoc = await req.payload.findByID({\n          collection: collectionSlug,\n          id,\n          user: auth.user,\n        })\n\n        if (!broadcastDoc || !broadcastDoc.providerId) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast not found or not synced with provider',\n          }, { status: 404 })\n        }\n\n        // Send broadcast using provider ID\n        const broadcast = await broadcastProvider.send(broadcastDoc.providerId, data)\n\n        // Update status in Payload collection\n        await req.payload.update({\n          collection: collectionSlug,\n          id,\n          data: {\n            status: NewsletterStatus.SENDING,\n            sentAt: new Date().toISOString(),\n          },\n          user: auth.user,\n        })\n\n        return Response.json({\n          success: true,\n          message: 'Broadcast sent successfully',\n          broadcast,\n        })\n      } catch (error) {\n        console.error('Failed to send broadcast:', error)\n        \n        if (error instanceof NewsletterProviderError) {\n          return Response.json({\n            success: false,\n            error: error.message,\n            code: error.code,\n          }, { status: error.code === 'NOT_SUPPORTED' ? 501 : 500 })\n        }\n\n        return Response.json({\n          success: false,\n          error: 'Failed to send broadcast',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { PayloadRequest } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { isAdmin } from './access'\n\n/**\n * Get authenticated user from request\n * In Payload v3, authentication is handled differently than v2\n */\nexport async function getAuthenticatedUser(req: PayloadRequest): Promise<any | null> {\n  try {\n    // Try to get the current user using Payload's auth\n    // This requires the request to have proper authentication headers/cookies\n    const me = await req.payload.find({\n      collection: 'users',\n      where: {\n        id: {\n          equals: 'me', // Special value in Payload to get current user\n        },\n      },\n      limit: 1,\n      depth: 0,\n    })\n    \n    return me.docs[0] || null\n  } catch {\n    return null\n  }\n}\n\n/**\n * Check if request has admin access\n */\nexport async function requireAdmin(\n  req: PayloadRequest,\n  config: NewsletterPluginConfig\n): Promise<{ authorized: true; user: any } | { authorized: false; error: string }> {\n  const user = await getAuthenticatedUser(req)\n  \n  if (!user) {\n    return {\n      authorized: false,\n      error: 'Authentication required',\n    }\n  }\n  \n  if (!isAdmin(user, config)) {\n    return {\n      authorized: false,\n      error: 'Admin access required',\n    }\n  }\n  \n  return {\n    authorized: true,\n    user,\n  }\n}","import type { Endpoint, PayloadHandler, PayloadRequest } from 'payload'\nimport type { NewsletterPluginConfig } from '../../types'\nimport { NewsletterProviderError, NewsletterStatus } from '../../types'\nimport { requireAdmin } from '../../utils/auth'\n\nexport const createScheduleBroadcastEndpoint = (\n  config: NewsletterPluginConfig,\n  collectionSlug: string\n): Endpoint => {\n  return {\n    path: `/${collectionSlug}/:id/schedule`,\n    method: 'post',\n    handler: (async (req: PayloadRequest) => {\n      try {\n        // Check authentication\n        const auth = await requireAdmin(req, config)\n        if (!auth.authorized) {\n          return Response.json({\n            success: false,\n            error: auth.error,\n          }, { status: 401 })\n        }\n\n        // Get broadcast provider\n        const broadcastProvider = (req.payload as any).newsletterProvider\n        if (!broadcastProvider) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast management is not enabled',\n          }, { status: 400 })\n        }\n\n        // Get ID from URL\n        const url = new URL(req.url || '', `http://localhost`)\n        const pathParts = url.pathname.split('/')\n        const id = pathParts[pathParts.length - 2] // -2 because last part is 'schedule'\n\n        if (!id) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast ID is required',\n          }, { status: 400 })\n        }\n\n        // Parse request body\n        const data = await (req.json?.() || Promise.resolve({}))\n        const { scheduledAt } = data\n\n        if (!scheduledAt) {\n          return Response.json({\n            success: false,\n            error: 'scheduledAt is required',\n          }, { status: 400 })\n        }\n\n        // Parse and validate date\n        const scheduledDate = new Date(scheduledAt)\n        if (isNaN(scheduledDate.getTime())) {\n          return Response.json({\n            success: false,\n            error: 'Invalid scheduledAt date',\n          }, { status: 400 })\n        }\n\n        // Ensure scheduled date is in the future\n        if (scheduledDate <= new Date()) {\n          return Response.json({\n            success: false,\n            error: 'scheduledAt must be in the future',\n          }, { status: 400 })\n        }\n\n        // Get the broadcast document to get the provider ID\n        const broadcastDoc = await req.payload.findByID({\n          collection: collectionSlug,\n          id,\n          user: auth.user,\n        })\n\n        if (!broadcastDoc || !broadcastDoc.providerId) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast not found or not synced with provider',\n          }, { status: 404 })\n        }\n\n        // Schedule broadcast using provider ID\n        const broadcast = await broadcastProvider.schedule(broadcastDoc.providerId, scheduledDate)\n\n        // Update status in Payload collection\n        await req.payload.update({\n          collection: collectionSlug,\n          id,\n          data: {\n            status: NewsletterStatus.SCHEDULED,\n            scheduledAt: scheduledDate.toISOString(),\n          },\n          user: auth.user,\n        })\n\n        return Response.json({\n          success: true,\n          message: `Broadcast scheduled for ${scheduledDate.toISOString()}`,\n          broadcast,\n        })\n      } catch (error) {\n        console.error('Failed to schedule broadcast:', error)\n        \n        if (error instanceof NewsletterProviderError) {\n          return Response.json({\n            success: false,\n            error: error.message,\n            code: error.code,\n          }, { status: error.code === 'NOT_SUPPORTED' ? 501 : 500 })\n        }\n\n        return Response.json({\n          success: false,\n          error: 'Failed to schedule broadcast',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import DOMPurify from 'isomorphic-dompurify'\nimport type { SerializedEditorState } from 'lexical'\n\n/**\n * DOMPurify configuration for email-safe HTML\n */\nexport const EMAIL_SAFE_CONFIG = {\n  ALLOWED_TAGS: [\n    'p', 'br', 'strong', 'b', 'em', 'i', 'u', 'strike', 's', 'span',\n    'a', 'h1', 'h2', 'h3', 'ul', 'ol', 'li', 'blockquote', 'hr'\n  ],\n  ALLOWED_ATTR: ['href', 'style', 'target', 'rel', 'align'],\n  ALLOWED_STYLES: {\n    '*': [\n      'color', 'background-color', 'font-size', 'font-weight',\n      'font-style', 'text-decoration', 'text-align', 'margin',\n      'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n      'padding', 'padding-top', 'padding-right', 'padding-bottom', \n      'padding-left', 'line-height', 'border-left', 'border-left-width',\n      'border-left-style', 'border-left-color'\n    ],\n  },\n  FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'form', 'input'],\n  FORBID_ATTR: ['class', 'id', 'onclick', 'onload', 'onerror'],\n}\n\n/**\n * Converts Lexical editor state to email-safe HTML\n */\nexport async function convertToEmailSafeHtml(\n  editorState: SerializedEditorState,\n  options?: {\n    wrapInTemplate?: boolean\n    preheader?: string\n  }\n): Promise<string> {\n  // First, convert Lexical state to HTML using custom converters\n  const rawHtml = await lexicalToEmailHtml(editorState)\n  \n  // Sanitize the HTML\n  const sanitizedHtml = DOMPurify.sanitize(rawHtml, EMAIL_SAFE_CONFIG)\n  \n  // Optionally wrap in email template\n  if (options?.wrapInTemplate) {\n    return wrapInEmailTemplate(sanitizedHtml, options.preheader)\n  }\n  \n  return sanitizedHtml\n}\n\n/**\n * Custom Lexical to HTML converter for email\n */\nasync function lexicalToEmailHtml(editorState: SerializedEditorState): Promise<string> {\n  const { root } = editorState\n  \n  if (!root || !root.children) {\n    return ''\n  }\n  \n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const html = root.children.map((node: any) => convertNode(node)).join('')\n  return html\n}\n\n/**\n * Convert individual Lexical nodes to email-safe HTML\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertNode(node: any): string {\n  switch (node.type) {\n    case 'paragraph':\n      return convertParagraph(node)\n    case 'heading':\n      return convertHeading(node)\n    case 'list':\n      return convertList(node)\n    case 'listitem':\n      return convertListItem(node)\n    case 'blockquote':\n      return convertBlockquote(node)\n    case 'text':\n      return convertText(node)\n    case 'link':\n      return convertLink(node)\n    case 'linebreak':\n      return '<br>'\n    default:\n      // Unknown node type - convert children if any\n      if (node.children) {\n        return node.children.map(convertNode).join('')\n      }\n      return ''\n  }\n}\n\n/**\n * Convert paragraph node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertParagraph(node: any): string {\n  const align = getAlignment(node.format)\n  const children = node.children?.map(convertNode).join('') || ''\n  \n  if (!children.trim()) {\n    return '<p style=\"margin: 0 0 16px 0; min-height: 1em;\">&nbsp;</p>'\n  }\n  \n  return `<p style=\"margin: 0 0 16px 0; text-align: ${align};\">${children}</p>`\n}\n\n/**\n * Convert heading node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertHeading(node: any): string {\n  const tag = node.tag || 'h1'\n  const align = getAlignment(node.format)\n  const children = node.children?.map(convertNode).join('') || ''\n  \n  const styles: Record<string, string> = {\n    h1: 'font-size: 32px; font-weight: 700; margin: 0 0 24px 0; line-height: 1.2;',\n    h2: 'font-size: 24px; font-weight: 600; margin: 0 0 16px 0; line-height: 1.3;',\n    h3: 'font-size: 20px; font-weight: 600; margin: 0 0 12px 0; line-height: 1.4;',\n  }\n  \n  const style = `${styles[tag] || styles.h3} text-align: ${align};`\n  \n  return `<${tag} style=\"${style}\">${children}</${tag}>`\n}\n\n/**\n * Convert list node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertList(node: any): string {\n  const tag = node.listType === 'number' ? 'ol' : 'ul'\n  const children = node.children?.map(convertNode).join('') || ''\n  \n  const style = tag === 'ul' \n    ? 'margin: 0 0 16px 0; padding-left: 24px; list-style-type: disc;'\n    : 'margin: 0 0 16px 0; padding-left: 24px; list-style-type: decimal;'\n  \n  return `<${tag} style=\"${style}\">${children}</${tag}>`\n}\n\n/**\n * Convert list item node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertListItem(node: any): string {\n  const children = node.children?.map(convertNode).join('') || ''\n  return `<li style=\"margin: 0 0 8px 0;\">${children}</li>`\n}\n\n/**\n * Convert blockquote node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertBlockquote(node: any): string {\n  const children = node.children?.map(convertNode).join('') || ''\n  const style = 'margin: 0 0 16px 0; padding-left: 16px; border-left: 4px solid #e5e7eb; color: #6b7280;'\n  \n  return `<blockquote style=\"${style}\">${children}</blockquote>`\n}\n\n/**\n * Convert text node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertText(node: any): string {\n  let text = escapeHtml(node.text || '')\n  \n  // Apply formatting\n  if (node.format & 1) { // Bold\n    text = `<strong>${text}</strong>`\n  }\n  if (node.format & 2) { // Italic\n    text = `<em>${text}</em>`\n  }\n  if (node.format & 8) { // Underline\n    text = `<u>${text}</u>`\n  }\n  if (node.format & 4) { // Strikethrough\n    text = `<strike>${text}</strike>`\n  }\n  \n  return text\n}\n\n/**\n * Convert link node\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertLink(node: any): string {\n  const children = node.children?.map(convertNode).join('') || ''\n  const url = node.fields?.url || '#'\n  \n  // Ensure links open in new tab and have security attributes\n  return `<a href=\"${escapeHtml(url)}\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"color: #2563eb; text-decoration: underline;\">${children}</a>`\n}\n\n/**\n * Get text alignment from format number\n */\nfunction getAlignment(format?: number): string {\n  if (!format) return 'left'\n  \n  // Lexical alignment format values\n  if (format & 2) return 'center'\n  if (format & 3) return 'right'\n  if (format & 4) return 'justify'\n  \n  return 'left'\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n  const map: Record<string, string> = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#039;'\n  }\n  \n  return text.replace(/[&<>\"']/g, m => map[m])\n}\n\n/**\n * Wrap content in a basic email template\n */\nfunction wrapInEmailTemplate(content: string, preheader?: string): string {\n  return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Email</title>\n  <!--[if mso]>\n  <noscript>\n    <xml>\n      <o:OfficeDocumentSettings>\n        <o:PixelsPerInch>96</o:PixelsPerInch>\n      </o:OfficeDocumentSettings>\n    </xml>\n  </noscript>\n  <![endif]-->\n</head>\n<body style=\"margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 16px; line-height: 1.5; color: #333333; background-color: #f3f4f6;\">\n  ${preheader ? `<div style=\"display: none; max-height: 0; overflow: hidden;\">${escapeHtml(preheader)}</div>` : ''}\n  <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"margin: 0; padding: 0;\">\n    <tr>\n      <td align=\"center\" style=\"padding: 20px 0;\">\n        <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden;\">\n          <tr>\n            <td style=\"padding: 40px 30px;\">\n              ${content}\n            </td>\n          </tr>\n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>`\n}\n\n/**\n * Extract personalization tags from content\n */\nexport function extractPersonalizationTags(html: string): string[] {\n  const regex = /\\{\\{([^}]+)\\}\\}/g\n  const tags: string[] = []\n  let match\n  \n  while ((match = regex.exec(html)) !== null) {\n    tags.push(match[1].trim())\n  }\n  \n  return [...new Set(tags)]\n}\n\n/**\n * Replace personalization tags with sample data\n */\nexport function replacePersonalizationTags(\n  html: string, \n  sampleData: Record<string, string>\n): string {\n  return html.replace(/\\{\\{([^}]+)\\}\\}/g, (match, tag) => {\n    const trimmedTag = tag.trim()\n    return sampleData[trimmedTag] || match\n  })\n}","import type { Endpoint, PayloadHandler, PayloadRequest } from 'payload'\nimport type { NewsletterPluginConfig } from '../../types'\nimport { requireAdmin } from '../../utils/auth'\nimport { convertToEmailSafeHtml } from '../../utils/emailSafeHtml'\n\nexport const createTestBroadcastEndpoint = (\n  config: NewsletterPluginConfig,\n  collectionSlug: string\n): Endpoint => {\n  return {\n    path: `/${collectionSlug}/:id/test`,\n    method: 'post',\n    handler: (async (req: PayloadRequest) => {\n      try {\n        // Check authentication\n        const auth = await requireAdmin(req, config)\n        if (!auth.authorized) {\n          return Response.json({\n            success: false,\n            error: auth.error,\n          }, { status: 401 })\n        }\n\n        // Get ID from URL\n        const url = new URL(req.url || '', `http://localhost`)\n        const pathParts = url.pathname.split('/')\n        const id = pathParts[pathParts.length - 2] // -2 because last part is 'test'\n\n        if (!id) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast ID is required',\n          }, { status: 400 })\n        }\n\n        // Parse request body for optional test email\n        const data = await (req.json?.() || Promise.resolve({}))\n        const testEmail = data.email || auth.user.email\n\n        if (!testEmail) {\n          return Response.json({\n            success: false,\n            error: 'No email address available for test send',\n          }, { status: 400 })\n        }\n\n        // Get the broadcast document\n        const broadcast = await req.payload.findByID({\n          collection: collectionSlug,\n          id,\n          user: auth.user,\n        })\n\n        if (!broadcast) {\n          return Response.json({\n            success: false,\n            error: 'Broadcast not found',\n          }, { status: 404 })\n        }\n\n        // Get the channel for sender info\n        const channel = await req.payload.findByID({\n          collection: 'channels',\n          id: typeof broadcast.channel === 'string' ? broadcast.channel : broadcast.channel.id,\n          user: auth.user,\n        })\n\n        // Convert content to email-safe HTML\n        const htmlContent = await convertToEmailSafeHtml(broadcast.content, {\n          wrapInTemplate: true,\n          preheader: broadcast.preheader,\n        })\n\n        // Get email service\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        const emailService = (req.payload as any).newsletterEmailService\n        if (!emailService) {\n          return Response.json({\n            success: false,\n            error: 'Email service is not configured',\n          }, { status: 500 })\n        }\n\n        // Send test email\n        await emailService.send({\n          to: testEmail,\n          from: channel?.fromEmail || config.providers.resend?.fromAddress || 'noreply@example.com',\n          fromName: channel?.fromName || config.providers.resend?.fromName || 'Newsletter',\n          replyTo: broadcast.settings?.replyTo || channel?.replyTo,\n          subject: `[TEST] ${broadcast.subject}`,\n          html: htmlContent,\n          trackOpens: false,\n          trackClicks: false,\n        })\n\n        return Response.json({\n          success: true,\n          message: `Test email sent to ${testEmail}`,\n        })\n      } catch (error) {\n        console.error('Failed to send test broadcast:', error)\n        \n        return Response.json({\n          success: false,\n          error: 'Failed to send test email',\n        }, { status: 500 })\n      }\n    }) as PayloadHandler,\n  }\n}","import type { Endpoint } from 'payload'\nimport type { NewsletterPluginConfig } from '../../types'\nimport { createSendBroadcastEndpoint } from './send'\nimport { createScheduleBroadcastEndpoint } from './schedule'\nimport { createTestBroadcastEndpoint } from './test'\n\nexport const createBroadcastManagementEndpoints = (\n  config: NewsletterPluginConfig\n): Endpoint[] => {\n  // Only create endpoints if broadcast management is enabled\n  if (!config.features?.newsletterManagement?.enabled) {\n    return []\n  }\n\n  // Only create custom action endpoints\n  // CRUD operations are handled by Payload's automatic REST API\n  const collectionSlug = config.features.newsletterManagement.collections?.broadcasts || 'broadcasts'\n  \n  return [\n    createSendBroadcastEndpoint(config, collectionSlug),\n    createScheduleBroadcastEndpoint(config, collectionSlug),\n    createTestBroadcastEndpoint(config, collectionSlug),\n  ]\n}","import type { Endpoint } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { createSubscribeEndpoint } from './subscribe'\nimport { createVerifyMagicLinkEndpoint } from './verify-magic-link'\nimport { createPreferencesEndpoint, createUpdatePreferencesEndpoint } from './preferences'\nimport { createUnsubscribeEndpoint } from './unsubscribe'\nimport { createSigninEndpoint } from './signin'\nimport { createMeEndpoint } from './me'\nimport { createSignoutEndpoint } from './signout'\nimport { createBroadcastManagementEndpoints } from './broadcasts'\n\nexport function createNewsletterEndpoints(\n  config: NewsletterPluginConfig\n): Endpoint[] {\n  const endpoints: Endpoint[] = [\n    createSubscribeEndpoint(config),\n    createUnsubscribeEndpoint(config),\n  ]\n\n  // Add auth endpoints if enabled\n  if (config.auth?.enabled !== false) {\n    endpoints.push(\n      createVerifyMagicLinkEndpoint(config),\n      createPreferencesEndpoint(config),\n      createUpdatePreferencesEndpoint(config),\n      createSigninEndpoint(config),\n      createMeEndpoint(config),\n      createSignoutEndpoint(config)\n    )\n  }\n\n  // Add broadcast management endpoints if enabled\n  endpoints.push(...createBroadcastManagementEndpoints(config))\n\n  return endpoints\n}","import type { Field } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\n\nexport function createNewsletterSchedulingFields(\n  config: NewsletterPluginConfig\n): Field[] {\n  const groupName = config.features?.newsletterScheduling?.fields?.groupName || 'newsletterScheduling'\n  const contentField = config.features?.newsletterScheduling?.fields?.contentField || 'content'\n  const createMarkdownField = config.features?.newsletterScheduling?.fields?.createMarkdownField !== false\n\n  const fields: Field[] = [\n    {\n      name: groupName,\n      type: 'group',\n      label: 'Newsletter Scheduling',\n      admin: {\n        condition: (data, { user }) => user?.collection === 'users', // Only show for admin users\n      },\n      fields: [\n        {\n          name: 'scheduled',\n          type: 'checkbox',\n          label: 'Schedule for Newsletter',\n          defaultValue: false,\n          admin: {\n            description: 'Schedule this content to be sent as a newsletter',\n          },\n        },\n        {\n          name: 'scheduledDate',\n          type: 'date',\n          label: 'Send Date',\n          required: true,\n          admin: {\n            date: {\n              pickerAppearance: 'dayAndTime',\n            },\n            condition: (data) => data?.[groupName]?.scheduled,\n            description: 'When to send this newsletter',\n          },\n        },\n        {\n          name: 'sentDate',\n          type: 'date',\n          label: 'Sent Date',\n          admin: {\n            readOnly: true,\n            condition: (data) => data?.[groupName]?.sendStatus === 'sent',\n            description: 'When this newsletter was sent',\n          },\n        },\n        {\n          name: 'sendStatus',\n          type: 'select',\n          label: 'Status',\n          options: [\n            { label: 'Draft', value: 'draft' },\n            { label: 'Scheduled', value: 'scheduled' },\n            { label: 'Sending', value: 'sending' },\n            { label: 'Sent', value: 'sent' },\n            { label: 'Failed', value: 'failed' },\n          ],\n          defaultValue: 'draft',\n          admin: {\n            readOnly: true,\n            description: 'Current send status',\n          },\n        },\n        {\n          name: 'emailSubject',\n          type: 'text',\n          label: 'Email Subject',\n          required: true,\n          admin: {\n            condition: (data) => data?.[groupName]?.scheduled,\n            description: 'Subject line for the newsletter email',\n          },\n        },\n        {\n          name: 'preheader',\n          type: 'text',\n          label: 'Email Preheader',\n          admin: {\n            condition: (data) => data?.[groupName]?.scheduled,\n            description: 'Preview text that appears after the subject line',\n          },\n        },\n        {\n          name: 'segments',\n          type: 'select',\n          label: 'Target Segments',\n          hasMany: true,\n          options: [\n            { label: 'All Subscribers', value: 'all' },\n            ...(config.i18n?.locales?.map(locale => ({\n              label: `${locale.toUpperCase()} Subscribers`,\n              value: locale,\n            })) || []),\n          ],\n          defaultValue: ['all'],\n          admin: {\n            condition: (data) => data?.[groupName]?.scheduled,\n            description: 'Which subscriber segments to send to',\n          },\n        },\n        {\n          name: 'testEmails',\n          type: 'array',\n          label: 'Test Email Recipients',\n          admin: {\n            condition: (data) => data?.[groupName]?.scheduled && data?.[groupName]?.sendStatus === 'draft',\n            description: 'Send test emails before scheduling',\n          },\n          fields: [\n            {\n              name: 'email',\n              type: 'email',\n              required: true,\n            },\n          ],\n        },\n      ],\n    },\n  ]\n\n  // Add markdown companion field if requested\n  if (createMarkdownField) {\n    fields.push(createMarkdownFieldInternal({\n      name: `${contentField}Markdown`,\n      richTextField: contentField,\n      label: 'Email Content (Markdown)',\n      admin: {\n        position: 'sidebar',\n        condition: (data: any) => Boolean(data?.[contentField] && data?.[groupName]?.scheduled),\n        description: 'Markdown version for email rendering',\n        readOnly: true,\n      },\n    }))\n  }\n\n  return fields\n}\n\n/**\n * Create a markdown companion field for rich text\n * This creates a virtual field that converts rich text to markdown\n */\nfunction createMarkdownFieldInternal(config: {\n  name: string\n  richTextField: string\n  label?: string\n  admin?: any\n}): Field {\n  return {\n    name: config.name,\n    type: 'textarea',\n    label: config.label || 'Markdown',\n    admin: {\n      ...config.admin,\n      description: config.admin?.description || 'Auto-generated from rich text content',\n    },\n    hooks: {\n      afterRead: [\n        async ({ data }) => {\n          // Convert rich text to markdown on read\n          if (data?.[config.richTextField]) {\n            try {\n              const { convertLexicalToMarkdown } = await import('@payloadcms/richtext-lexical')\n              return convertLexicalToMarkdown({\n                data: data[config.richTextField],\n              } as any)\n            } catch {\n              return ''\n            }\n          }\n          return ''\n        },\n      ],\n      beforeChange: [\n        () => {\n          // Don't save markdown to database\n          return null\n        },\n      ],\n    },\n  }\n}","import type { TaskConfig, PayloadRequest } from 'payload'\nimport type { NewsletterPluginConfig } from '../types/index'\n\nexport const createUnsubscribeSyncJob = (\n  pluginConfig: NewsletterPluginConfig\n): TaskConfig => {\n  return {\n    slug: 'sync-unsubscribes',\n    label: 'Sync Unsubscribes from Email Service',\n    handler: async ({ req }: { req: PayloadRequest }) => {\n      const subscribersSlug = pluginConfig.subscribersSlug || 'subscribers'\n      const emailService = (req.payload as any).newsletterEmailService // TODO: Add proper type for newsletter email service\n      \n      if (!emailService) {\n        console.error('Email service not configured')\n        return {\n          output: {\n            syncedCount: 0\n          }\n        }\n      }\n\n      let syncedCount = 0\n      \n      try {\n        // For Broadcast: Poll all subscribers\n        if (emailService.getProvider() === 'broadcast') {\n          console.warn('Starting Broadcast unsubscribe sync...')\n          \n          // Get Broadcast configuration\n          const broadcastConfig = pluginConfig.providers?.broadcast\n          if (!broadcastConfig) {\n            throw new Error('Broadcast configuration not found')\n          }\n\n          const apiUrl = broadcastConfig.apiUrl.replace(/\\/$/, '')\n          const token = process.env.NODE_ENV === 'production' \n            ? broadcastConfig.tokens.production \n            : broadcastConfig.tokens.development\n\n          let page = 1\n          let hasMore = true\n\n          while (hasMore) {\n            // Fetch subscribers from Broadcast\n            const response = await fetch(\n              `${apiUrl}/api/v1/subscribers.json?page=${page}`,\n              {\n                headers: {\n                  'Authorization': `Bearer ${token}`,\n                },\n              }\n            )\n\n            if (!response.ok) {\n              throw new Error(`Broadcast API error: ${response.status}`)\n            }\n\n            const data = await response.json()\n            const broadcastSubscribers = data.subscribers || []\n            \n            // Process each subscriber\n            for (const broadcastSub of broadcastSubscribers) {\n              // Find corresponding subscriber in Payload\n              const payloadSubscribers = await req.payload.find({\n                collection: subscribersSlug,\n                where: {\n                  email: {\n                    equals: broadcastSub.email,\n                  },\n                },\n                limit: 1,\n              })\n\n              if (payloadSubscribers.docs.length > 0) {\n                const payloadSub = payloadSubscribers.docs[0]\n                \n                // Check if unsubscribe status differs\n                const broadcastUnsubscribed = !broadcastSub.is_active || broadcastSub.unsubscribed_at\n                const payloadUnsubscribed = payloadSub.subscriptionStatus === 'unsubscribed'\n                \n                if (broadcastUnsubscribed && !payloadUnsubscribed) {\n                  // Update Payload subscriber to unsubscribed\n                  await req.payload.update({\n                    collection: subscribersSlug,\n                    id: payloadSub.id,\n                    data: {\n                      subscriptionStatus: 'unsubscribed',\n                      unsubscribedAt: broadcastSub.unsubscribed_at || new Date().toISOString(),\n                    },\n                  })\n                  syncedCount++\n                  console.warn(`Unsubscribed: ${broadcastSub.email}`)\n                }\n              }\n            }\n\n            // Check pagination\n            if (data.pagination && data.pagination.current < data.pagination.total_pages) {\n              page++\n            } else {\n              hasMore = false\n            }\n          }\n\n          console.warn(`Broadcast sync complete. Unsubscribed ${syncedCount} contacts.`)\n        }\n\n        // For Resend: Use Audiences API\n        if (emailService.getProvider() === 'resend') {\n          console.warn('Starting Resend unsubscribe sync...')\n          \n          // Note: Resend webhooks are preferred over polling\n          // This is a fallback polling implementation\n          \n          // First, get all audiences\n          const resendConfig = pluginConfig.providers?.resend\n          if (!resendConfig) {\n            throw new Error('Resend configuration not found')\n          }\n\n          // You would need to implement audience/contact polling here\n          // Resend's API structure would require:\n          // 1. List audiences\n          // 2. For each audience, list contacts\n          // 3. Check unsubscribed status\n          \n          console.warn('Resend polling implementation needed - webhooks recommended')\n        }\n\n        // Custom after sync hook\n        if (pluginConfig.hooks?.afterUnsubscribeSync) {\n          await pluginConfig.hooks.afterUnsubscribeSync({ \n            req, \n            syncedCount: syncedCount\n          })\n        }\n\n      } catch (error) {\n        console.error('Unsubscribe sync error:', error)\n        throw error\n      }\n      \n      return {\n        output: {\n          syncedCount\n        }\n      }\n    },\n  }\n}","import type { CollectionConfig } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\n\nexport const createChannelsCollection = (pluginConfig: NewsletterPluginConfig): CollectionConfig => {\n  const hasProviders = !!(pluginConfig.providers?.broadcast || pluginConfig.providers?.resend)\n\n  return {\n    slug: 'channels',\n    labels: {\n      singular: 'Channel',\n      plural: 'Channels',\n    },\n    admin: {\n      useAsTitle: 'name',\n      description: 'Newsletter channels/publications that can send broadcasts',\n      defaultColumns: ['name', 'fromEmail', 'subscriberCount', 'active'],\n    },\n    fields: [\n      {\n        name: 'name',\n        type: 'text',\n        required: true,\n        admin: {\n          description: 'The name of this newsletter channel'\n        },\n      },\n      {\n        name: 'description',\n        type: 'textarea',\n        admin: {\n          description: 'A brief description of what this channel is about'\n        },\n      },\n      {\n        name: 'fromName',\n        type: 'text',\n        required: true,\n        admin: {\n          description: 'The sender name that appears in emails'\n        },\n      },\n      {\n        name: 'fromEmail',\n        type: 'email',\n        required: true,\n        admin: {\n          description: 'The sender email address'\n        },\n      },\n      {\n        name: 'replyTo',\n        type: 'email',\n        admin: {\n          description: 'Reply-to email address (optional)'\n        },\n      },\n      {\n        name: 'providerType',\n        type: 'select',\n        required: true,\n        options: [\n          ...(pluginConfig.providers?.broadcast ? [{ label: 'Broadcast', value: 'broadcast' }] : []),\n          ...(pluginConfig.providers?.resend ? [{ label: 'Resend', value: 'resend' }] : []),\n        ],\n        admin: {\n          description: 'Which email provider manages this channel'\n        },\n      },\n      {\n        name: 'providerId',\n        type: 'text',\n        admin: {\n          readOnly: true,\n          description: 'ID from the email provider',\n          condition: (data) => hasProviders && data?.providerId,\n        },\n      },\n      {\n        name: 'subscriberCount',\n        type: 'number',\n        admin: {\n          readOnly: true,\n          description: 'Number of active subscribers',\n        },\n        defaultValue: 0,\n      },\n      {\n        name: 'active',\n        type: 'checkbox',\n        defaultValue: true,\n        admin: {\n          description: 'Whether this channel is currently active'\n        },\n      },\n      {\n        name: 'settings',\n        type: 'group',\n        fields: [\n          {\n            name: 'defaultTrackOpens',\n            type: 'checkbox',\n            defaultValue: true,\n            admin: {\n              description: 'Track email opens by default for broadcasts in this channel'\n            },\n          },\n          {\n            name: 'defaultTrackClicks',\n            type: 'checkbox',\n            defaultValue: true,\n            admin: {\n              description: 'Track link clicks by default for broadcasts in this channel'\n            },\n          },\n          {\n            name: 'requireDoubleOptIn',\n            type: 'checkbox',\n            defaultValue: false,\n            admin: {\n              description: 'Require double opt-in for new subscribers'\n            },\n          },\n        ],\n      },\n    ],\n    hooks: {\n      // Sync with provider on create\n      afterChange: [\n        async ({ doc, operation, req }) => {\n          if (!hasProviders || operation !== 'create') return doc\n\n          try {\n            const provider = await getProvider(doc.providerType, pluginConfig)\n            if (!provider) return doc\n\n            // Create channel in provider\n            const providerChannel = await provider.createChannel({\n              name: doc.name,\n              description: doc.description,\n              fromName: doc.fromName,\n              fromEmail: doc.fromEmail,\n              replyTo: doc.replyTo,\n            })\n\n            // Update with provider ID\n            await req.payload.update({\n              collection: 'channels',\n              id: doc.id,\n              data: {\n                providerId: providerChannel.id,\n                subscriberCount: providerChannel.subscriberCount || 0,\n              },\n              req,\n            })\n\n            return {\n              ...doc,\n              providerId: providerChannel.id,\n              subscriberCount: providerChannel.subscriberCount || 0,\n            }\n          } catch (error) {\n            req.payload.logger.error('Failed to create channel in provider:', error)\n            return doc\n          }\n        },\n      ],\n      // Sync updates with provider\n      beforeChange: [\n        async ({ data, originalDoc, operation, req }) => {\n          if (!hasProviders || !originalDoc?.providerId || operation !== 'update') return data\n\n          try {\n            const provider = await getProvider(originalDoc.providerType, pluginConfig)\n            if (!provider) return data\n\n            // Check what fields changed\n            const updates: any = {}\n            if (data.name !== originalDoc.name) updates.name = data.name\n            if (data.description !== originalDoc.description) updates.description = data.description\n            if (data.fromName !== originalDoc.fromName) updates.fromName = data.fromName\n            if (data.fromEmail !== originalDoc.fromEmail) updates.fromEmail = data.fromEmail\n            if (data.replyTo !== originalDoc.replyTo) updates.replyTo = data.replyTo\n\n            if (Object.keys(updates).length > 0) {\n              await provider.updateChannel(originalDoc.providerId, updates)\n            }\n          } catch (error) {\n            req.payload.logger.error('Failed to update channel in provider:', error)\n            // Continue with local update even if provider fails\n          }\n\n          return data\n        },\n      ],\n      // Handle deletion\n      afterDelete: [\n        async ({ doc, req }) => {\n          if (!hasProviders || !doc?.providerId) return doc\n\n          try {\n            const provider = await getProvider(doc.providerType, pluginConfig)\n            if (!provider) return doc\n\n            await provider.deleteChannel(doc.providerId)\n          } catch (error) {\n            req.payload.logger.error('Failed to delete channel from provider:', error)\n          }\n\n          return doc\n        },\n      ],\n    },\n  }\n}\n\n// Helper to get provider instance\nasync function getProvider(providerType: string, config: NewsletterPluginConfig): Promise<any> {\n  if (providerType === 'broadcast') {\n    const { BroadcastApiProvider } = await import('../providers/broadcast/broadcast')\n    const providerConfig = config.providers?.broadcast\n    return providerConfig ? new BroadcastApiProvider(providerConfig) : null\n  }\n  \n  if (providerType === 'resend') {\n    const { ResendBroadcastProvider } = await import('../providers/resend/broadcast')\n    const providerConfig = config.providers?.resend\n    return providerConfig ? new ResendBroadcastProvider(providerConfig) : null\n  }\n\n  return null\n}","import type { CollectionConfig } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { BroadcastStatus } from '../types'\nimport { createEmailContentField } from '../fields/emailContent'\nimport { convertToEmailSafeHtml } from '../utils/emailSafeHtml'\n\nexport const createBroadcastsCollection = (pluginConfig: NewsletterPluginConfig): CollectionConfig => {\n  const hasProviders = !!(pluginConfig.providers?.broadcast || pluginConfig.providers?.resend)\n\n  return {\n    slug: 'broadcasts',\n    labels: {\n      singular: 'Broadcast',\n      plural: 'Broadcasts',\n    },\n    admin: {\n      useAsTitle: 'name',\n      description: 'Individual email campaigns sent to subscribers',\n      defaultColumns: ['name', 'subject', 'status', 'channel', 'sentAt', 'actions'],\n    },\n    fields: [\n      {\n        name: 'channel',\n        type: 'relationship',\n        relationTo: 'channels',\n        required: true,\n        admin: {\n          description: 'The channel this broadcast belongs to'\n        },\n      },\n      {\n        name: 'name',\n        type: 'text',\n        required: true,\n        admin: {\n          description: 'Internal name for this broadcast'\n        },\n      },\n      {\n        name: 'subject',\n        type: 'text',\n        required: true,\n        admin: {\n          description: 'Email subject line'\n        },\n      },\n      {\n        name: 'preheader',\n        type: 'text',\n        admin: {\n          description: 'Preview text shown in email clients'\n        },\n      },\n      createEmailContentField({\n        admin: {\n          description: 'Email content',\n        },\n      }),\n      {\n        name: 'emailPreview',\n        type: 'ui',\n        admin: {\n          components: {\n            Field: '/src/components/Broadcasts/EmailPreviewField',\n          },\n        },\n      },\n      {\n        name: 'status',\n        type: 'select',\n        required: true,\n        defaultValue: BroadcastStatus.DRAFT,\n        options: [\n          { label: 'Draft', value: BroadcastStatus.DRAFT },\n          { label: 'Scheduled', value: BroadcastStatus.SCHEDULED },\n          { label: 'Sending', value: BroadcastStatus.SENDING },\n          { label: 'Sent', value: BroadcastStatus.SENT },\n          { label: 'Failed', value: BroadcastStatus.FAILED },\n          { label: 'Paused', value: BroadcastStatus.PAUSED },\n          { label: 'Canceled', value: BroadcastStatus.CANCELED },\n        ],\n        admin: {\n          readOnly: true,\n          components: {\n            Cell: '/src/components/Broadcasts/StatusBadge',\n          },\n        },\n      },\n      {\n        name: 'settings',\n        type: 'group',\n        fields: [\n          {\n            name: 'trackOpens',\n            type: 'checkbox',\n            defaultValue: true,\n            admin: {\n              description: 'Track when recipients open this email'\n            },\n          },\n          {\n            name: 'trackClicks',\n            type: 'checkbox',\n            defaultValue: true,\n            admin: {\n              description: 'Track when recipients click links'\n            },\n          },\n          {\n            name: 'replyTo',\n            type: 'email',\n            admin: {\n              description: 'Override the channel reply-to address for this broadcast'\n            },\n          },\n        ],\n      },\n      {\n        name: 'audienceIds',\n        type: 'array',\n        fields: [\n          {\n            name: 'audienceId',\n            type: 'text',\n            required: true,\n          },\n        ],\n        admin: {\n          description: 'Target specific audience segments',\n          condition: () => {\n            // Only show if the provider supports segmentation\n            return hasProviders\n          },\n        },\n      },\n      {\n        name: 'analytics',\n        type: 'group',\n        admin: {\n          readOnly: true,\n          condition: (data) => data?.status === BroadcastStatus.SENT,\n        },\n        fields: [\n          {\n            name: 'recipientCount',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'sent',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'delivered',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'opened',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'clicked',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'bounced',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'complained',\n            type: 'number',\n            defaultValue: 0,\n          },\n          {\n            name: 'unsubscribed',\n            type: 'number',\n            defaultValue: 0,\n          },\n        ],\n      },\n      {\n        name: 'sentAt',\n        type: 'date',\n        admin: {\n          readOnly: true,\n          date: {\n            displayFormat: 'MMM d, yyyy h:mm a',\n          },\n        },\n      },\n      {\n        name: 'scheduledAt',\n        type: 'date',\n        admin: {\n          condition: (data) => data?.status === BroadcastStatus.SCHEDULED,\n          date: {\n            displayFormat: 'MMM d, yyyy h:mm a',\n          },\n        },\n      },\n      {\n        name: 'providerId',\n        type: 'text',\n        admin: {\n          readOnly: true,\n          description: 'ID from the email provider',\n          condition: (data) => hasProviders && data?.providerId,\n        },\n      },\n      {\n        name: 'providerData',\n        type: 'json',\n        admin: {\n          readOnly: true,\n          condition: () => false, // Hidden by default\n        },\n      },\n      // UI Field for custom actions in list view\n      {\n        name: 'actions',\n        type: 'ui',\n        admin: {\n          components: {\n            Cell: '/src/components/Broadcasts/ActionsCell',\n            Field: '/src/components/Broadcasts/EmptyField',\n          },\n          disableListColumn: false,\n        },\n      },\n    ],\n    hooks: {\n      // Sync with provider on create\n      afterChange: [\n        async ({ doc, operation, req }) => {\n          if (!hasProviders || operation !== 'create') return doc\n\n          try {\n            // Get the channel to determine provider\n            const channel = await req.payload.findByID({\n              collection: 'channels',\n              id: typeof doc.channel === 'string' ? doc.channel : doc.channel.id,\n              req,\n            })\n\n            const provider = await getProvider(channel.providerType, pluginConfig)\n            if (!provider) return doc\n\n            // Convert rich text to HTML\n            const htmlContent = await convertToEmailSafeHtml(doc.content)\n\n            // Create broadcast in provider\n            const providerBroadcast = await provider.create({\n              channelId: channel.providerId || channel.id,\n              name: doc.name,\n              subject: doc.subject,\n              preheader: doc.preheader,\n              content: htmlContent,\n              trackOpens: doc.settings?.trackOpens,\n              trackClicks: doc.settings?.trackClicks,\n              replyTo: doc.settings?.replyTo,\n              audienceIds: doc.audienceIds?.map((a: any) => a.audienceId),\n            })\n\n            // Update with provider ID\n            await req.payload.update({\n              collection: 'broadcasts',\n              id: doc.id,\n              data: {\n                providerId: providerBroadcast.id,\n                providerData: providerBroadcast.providerData,\n              },\n              req,\n            })\n\n            return {\n              ...doc,\n              providerId: providerBroadcast.id,\n              providerData: providerBroadcast.providerData,\n            }\n          } catch (error) {\n            req.payload.logger.error('Failed to create broadcast in provider:', error)\n            return doc\n          }\n        },\n      ],\n      // Sync updates with provider\n      beforeChange: [\n        async ({ data, originalDoc, operation, req }) => {\n          if (!hasProviders || !originalDoc?.providerId || operation !== 'update') return data\n\n          try {\n            // Get the channel to determine provider\n            const channelId = data.channel || originalDoc.channel\n            const channel = await req.payload.findByID({\n              collection: 'channels',\n              id: typeof channelId === 'string' ? channelId : channelId.id,\n              req,\n            })\n\n            const provider = await getProvider(channel.providerType, pluginConfig)\n            if (!provider) return data\n\n            // Only sync if broadcast is still editable\n            const capabilities = provider.getCapabilities()\n            if (!capabilities.editableStatuses.includes(originalDoc.status)) {\n              return data\n            }\n\n            // Build update data\n            const updates: any = {}\n            if (data.name !== originalDoc.name) updates.name = data.name\n            if (data.subject !== originalDoc.subject) updates.subject = data.subject\n            if (data.preheader !== originalDoc.preheader) updates.preheader = data.preheader\n            if (data.content !== originalDoc.content) {\n              updates.content = await convertToEmailSafeHtml(data.content)\n            }\n            if (data.settings?.trackOpens !== originalDoc.settings?.trackOpens) {\n              updates.trackOpens = data.settings.trackOpens\n            }\n            if (data.settings?.trackClicks !== originalDoc.settings?.trackClicks) {\n              updates.trackClicks = data.settings.trackClicks\n            }\n            if (data.settings?.replyTo !== originalDoc.settings?.replyTo) {\n              updates.replyTo = data.settings.replyTo\n            }\n            if (JSON.stringify(data.audienceIds) !== JSON.stringify(originalDoc.audienceIds)) {\n              updates.audienceIds = data.audienceIds?.map((a: any) => a.audienceId)\n            }\n\n            if (Object.keys(updates).length > 0) {\n              await provider.update(originalDoc.providerId, updates)\n            }\n          } catch (error) {\n            req.payload.logger.error('Failed to update broadcast in provider:', error)\n            // Continue with local update even if provider fails\n          }\n\n          return data\n        },\n      ],\n      // Handle deletion\n      afterDelete: [\n        async ({ doc, req }) => {\n          if (!hasProviders || !doc?.providerId) return doc\n\n          try {\n            // Get the channel to determine provider\n            const channel = await req.payload.findByID({\n              collection: 'channels',\n              id: typeof doc.channel === 'string' ? doc.channel : doc.channel.id,\n              req,\n            })\n\n            const provider = await getProvider(channel.providerType, pluginConfig)\n            if (!provider) return doc\n\n            // Only delete if broadcast is still editable\n            const capabilities = provider.getCapabilities()\n            if (capabilities.editableStatuses.includes(doc.status)) {\n              await provider.delete(doc.providerId)\n            }\n          } catch (error) {\n            req.payload.logger.error('Failed to delete broadcast from provider:', error)\n          }\n\n          return doc\n        },\n      ],\n    },\n  }\n}\n\n// Helper to get provider instance\nasync function getProvider(providerType: string, config: NewsletterPluginConfig): Promise<any> {\n  if (providerType === 'broadcast') {\n    const { BroadcastApiProvider } = await import('../providers/broadcast/broadcast')\n    const providerConfig = config.providers?.broadcast\n    return providerConfig ? new BroadcastApiProvider(providerConfig) : null\n  }\n  \n  if (providerType === 'resend') {\n    const { ResendBroadcastProvider } = await import('../providers/resend/broadcast')\n    const providerConfig = config.providers?.resend\n    return providerConfig ? new ResendBroadcastProvider(providerConfig) : null\n  }\n\n  return null\n}\n\n","import { \n  BoldFeature,\n  ItalicFeature,\n  UnderlineFeature,\n  StrikethroughFeature,\n  LinkFeature,\n  OrderedListFeature,\n  UnorderedListFeature,\n  HeadingFeature,\n  ParagraphFeature,\n  AlignFeature,\n  BlockquoteFeature,\n  lexicalEditor,\n} from '@payloadcms/richtext-lexical'\nimport type { RichTextField } from 'payload'\n\n/**\n * Email-safe features for Lexical editor\n * Only includes features that render consistently across email clients\n */\n// Using any[] here because Payload's FeatureProviderServer type is complex\n// and varies between versions. The features are properly typed by Payload internally.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const emailSafeFeatures: any[] = [\n  // Basic text formatting\n  BoldFeature(),\n  ItalicFeature(),\n  UnderlineFeature(),\n  StrikethroughFeature(),\n  \n  // Links with simple configuration\n  LinkFeature({\n    fields: [{\n      name: 'url',\n      type: 'text',\n      required: true,\n      admin: {\n        description: 'Enter the full URL (including https://)',\n      },\n    }],\n  }),\n  \n  // Lists\n  OrderedListFeature(),\n  UnorderedListFeature(),\n  \n  // Headings - limited to h1, h2, h3 for email compatibility\n  HeadingFeature({\n    enabledHeadingSizes: ['h1', 'h2', 'h3'],\n  }),\n  \n  // Basic paragraph and alignment\n  ParagraphFeature(),\n  AlignFeature(),\n  \n  // Blockquotes\n  BlockquoteFeature(),\n]\n\n/**\n * Creates an email-safe rich text field configuration\n */\nexport const createEmailContentField = (overrides?: Partial<RichTextField>): RichTextField => {\n  return {\n    name: 'content',\n    type: 'richText',\n    required: true,\n    editor: lexicalEditor({\n      features: emailSafeFeatures,\n    }),\n    admin: {\n      description: 'Email content with limited formatting for compatibility',\n      ...overrides?.admin,\n    },\n    ...overrides,\n  }\n}","import type { PayloadRequest } from 'payload'\nimport jwt from 'jsonwebtoken'\n\n// Next.js types - these are optional and only used when Next.js is available\ninterface NextApiRequest {\n  cookies?: { [key: string]: string }\n  headers?: { [key: string]: string | string[] | undefined }\n  [key: string]: any\n}\n\ninterface GetServerSidePropsContext {\n  req: {\n    cookies?: { [key: string]: string }\n    headers?: { [key: string]: string | string[] | undefined }\n    [key: string]: any\n  }\n  [key: string]: any\n}\n\ninterface TokenPayload {\n  id: string\n  email: string\n  type?: string\n  iat?: number\n  exp?: number\n}\n\n/**\n * Extract token from request cookies\n */\nexport const getTokenFromRequest = (\n  req: NextApiRequest | GetServerSidePropsContext['req'] | PayloadRequest\n): string | null => {\n  // Handle different request types\n  const cookies = (req as any).cookies || (req as any).headers?.cookie\n  \n  if (!cookies) return null\n  \n  // Parse cookies if it's a string\n  if (typeof cookies === 'string') {\n    const parsed = cookies.split(';').reduce((acc, cookie) => {\n      const [key, value] = cookie.trim().split('=')\n      acc[key] = value\n      return acc\n    }, {} as Record<string, string>)\n    return parsed['newsletter-auth'] || null\n  }\n  \n  // Direct cookie object\n  return cookies['newsletter-auth'] || null\n}\n\n/**\n * Verify JWT token\n */\nexport const verifyToken = (\n  token: string, \n  secret: string\n): TokenPayload | null => {\n  try {\n    const decoded = jwt.verify(token, secret) as TokenPayload\n    return decoded\n  } catch {\n    return null\n  }\n}\n\n/**\n * Get authentication state for server-side rendering\n */\nexport const getServerSideAuth = async (\n  context: GetServerSidePropsContext,\n  secret?: string\n): Promise<{ subscriber: TokenPayload | null; isAuthenticated: boolean }> => {\n  const token = getTokenFromRequest(context.req)\n  \n  if (!token) {\n    return { subscriber: null, isAuthenticated: false }\n  }\n  \n  const payloadSecret = secret || process.env.PAYLOAD_SECRET\n  if (!payloadSecret) {\n    console.error('No secret provided for token verification')\n    return { subscriber: null, isAuthenticated: false }\n  }\n  \n  const decoded = verifyToken(token, payloadSecret)\n  \n  if (!decoded) {\n    return { subscriber: null, isAuthenticated: false }\n  }\n  \n  return {\n    subscriber: decoded,\n    isAuthenticated: true,\n  }\n}\n\n/**\n * Higher-order function for protecting pages\n */\nexport const requireAuth = <P extends { [key: string]: any }>(\n  gssp?: (context: GetServerSidePropsContext) => Promise<{ props: P }>\n) => {\n  return async (context: GetServerSidePropsContext) => {\n    const { isAuthenticated, subscriber } = await getServerSideAuth(context)\n    \n    if (!isAuthenticated) {\n      return {\n        redirect: {\n          destination: '/auth/signin',\n          permanent: false,\n        },\n      }\n    }\n    \n    // If there's a custom getServerSideProps, run it\n    if (gssp) {\n      const result = await gssp(context)\n      return {\n        ...result,\n        props: {\n          ...result.props,\n          subscriber,\n        },\n      }\n    }\n    \n    // Otherwise just return the subscriber\n    return {\n      props: {\n        subscriber,\n      } as any as P,\n    }\n  }\n}\n\n/**\n * Check if request has valid authentication\n */\nexport const isAuthenticated = (\n  req: PayloadRequest | NextApiRequest,\n  secret: string\n): boolean => {\n  const token = getTokenFromRequest(req)\n  if (!token) return false\n  \n  const decoded = verifyToken(token, secret)\n  return !!decoded\n}"],"mappings":"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","names":["init_broadcast","broadcast_exports","import_resend","init_broadcast","import_components","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","DOMPurify","jwt","subscriber","jwt","import_isomorphic_dompurify","DOMPurify","styles","BroadcastApiProvider","ResendBroadcastProvider","getProvider","BroadcastApiProvider","ResendBroadcastProvider","init_broadcast","import_jsonwebtoken","jwt","isAuthenticated"]}