@burdenoff/be-sdk 2026.618.1 → 2026.623.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/auth/index.d.ts +3 -2
  2. package/dist/auth/index.js +2 -2
  3. package/dist/{chunk-XNQUN3AE.js → chunk-4OQRBSHM.js} +3 -3
  4. package/dist/{chunk-XNQUN3AE.js.map → chunk-4OQRBSHM.js.map} +1 -1
  5. package/dist/{chunk-FTDQ6NY5.js → chunk-6NB7P6SR.js} +3 -3
  6. package/dist/{chunk-FTDQ6NY5.js.map → chunk-6NB7P6SR.js.map} +1 -1
  7. package/dist/{chunk-L2P4CJUR.js → chunk-B527JLOB.js} +6 -2
  8. package/dist/chunk-B527JLOB.js.map +1 -0
  9. package/dist/{chunk-SMGTXYFR.js → chunk-EZ4PKRUK.js} +2 -2
  10. package/dist/chunk-EZ4PKRUK.js.map +1 -0
  11. package/dist/{chunk-5FEOFBQ4.js → chunk-F5BPKP75.js} +3 -3
  12. package/dist/{chunk-5FEOFBQ4.js.map → chunk-F5BPKP75.js.map} +1 -1
  13. package/dist/{chunk-ZHQUXD6S.js → chunk-IUL5TEKE.js} +3 -3
  14. package/dist/{chunk-ZHQUXD6S.js.map → chunk-IUL5TEKE.js.map} +1 -1
  15. package/dist/{chunk-N7UJFZQH.js → chunk-OWUVYM2S.js} +6 -47
  16. package/dist/chunk-OWUVYM2S.js.map +1 -0
  17. package/dist/{chunk-FKSMQLIV.js → chunk-SS4XWRYR.js} +3 -3
  18. package/dist/{chunk-FKSMQLIV.js.map → chunk-SS4XWRYR.js.map} +1 -1
  19. package/dist/{chunk-ZPEDC5V3.js → chunk-TYXGWVRL.js} +5 -5
  20. package/dist/{chunk-ZPEDC5V3.js.map → chunk-TYXGWVRL.js.map} +1 -1
  21. package/dist/{chunk-X7QMT2P6.js → chunk-UJI2S556.js} +3 -3
  22. package/dist/{chunk-X7QMT2P6.js.map → chunk-UJI2S556.js.map} +1 -1
  23. package/dist/chunk-VFCMR5GX.js +49 -0
  24. package/dist/chunk-VFCMR5GX.js.map +1 -0
  25. package/dist/{chunk-HRCWJLCZ.js → chunk-YEA4BZOL.js} +8 -4
  26. package/dist/chunk-YEA4BZOL.js.map +1 -0
  27. package/dist/{chunk-XR3KUHJ5.js → chunk-Z2423JIB.js} +3 -3
  28. package/dist/{chunk-XR3KUHJ5.js.map → chunk-Z2423JIB.js.map} +1 -1
  29. package/dist/database/index.js +2 -2
  30. package/dist/event-queue/index.d.ts +3 -3
  31. package/dist/export/index.js +4 -3
  32. package/dist/feature-flags/index.d.ts +1 -1
  33. package/dist/feature-flags/index.js +2 -1
  34. package/dist/gateway/index.d.ts +1 -1
  35. package/dist/gateway/index.js +3 -2
  36. package/dist/gateway/security/index.js +1 -1
  37. package/dist/graph/index.d.ts +4 -3
  38. package/dist/graph/index.js +2 -2
  39. package/dist/{graphql-CNhiZ89U.d.ts → graphql-BRj5KPOL.d.ts} +3 -2
  40. package/dist/{index-DraeealK.d.ts → index-1qCbBvKE.d.ts} +2 -2
  41. package/dist/{index-D7BJuXP3.d.ts → index-B3ECnOLp.d.ts} +2 -2
  42. package/dist/{index-CVFEyBvK.d.ts → index-BIhZJ1w7.d.ts} +1 -1
  43. package/dist/{index-DYQF_AIz.d.ts → index-BN_-AWdb.d.ts} +2 -2
  44. package/dist/{index-jOuh_TKn.d.ts → index-BdPnlJ8_.d.ts} +2 -0
  45. package/dist/{index-BKjt3X8L.d.ts → index-Bm6MYdqS.d.ts} +5 -2
  46. package/dist/{index-B-w7NWpD.d.ts → index-CNy4MwKc.d.ts} +1 -1
  47. package/dist/{index-D9RN6jp1.d.ts → index-DDCOGyYh.d.ts} +4 -0
  48. package/dist/{index-DohlGQGw.d.ts → index-DsBZRR82.d.ts} +3 -3
  49. package/dist/index.d.ts +15 -15
  50. package/dist/index.js +113 -32
  51. package/dist/index.js.map +1 -1
  52. package/dist/init/index.js +4 -3
  53. package/dist/instrumentation/index.d.ts +4 -3
  54. package/dist/logger/index.d.ts +3 -2
  55. package/dist/notifications/index.d.ts +4 -3
  56. package/dist/notifications/index.js +2 -2
  57. package/dist/rbac/index.d.ts +2 -2
  58. package/dist/rbac/index.js +2 -2
  59. package/dist/resource-caps/index.d.ts +3 -2
  60. package/dist/telemetry/index.d.ts +5 -4
  61. package/dist/telemetry/index.js.map +1 -1
  62. package/dist/tracker/index.d.ts +5 -4
  63. package/dist/tracker/index.js +4 -4
  64. package/package.json +1 -1
  65. package/dist/chunk-HRCWJLCZ.js.map +0 -1
  66. package/dist/chunk-L2P4CJUR.js.map +0 -1
  67. package/dist/chunk-N7UJFZQH.js.map +0 -1
  68. package/dist/chunk-SMGTXYFR.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/notifications/tenant-notifications.ts","../src/notifications/index.ts"],"names":["NotificationChannel","NotificationPriority","NotificationType","TenantNotificationsModule","client","context","send","input","validateSendInput","logger","info","channel","type","priority","mutation","variables","recipient","subject","body","htmlBody","data","metadata","scheduledFor","toISOString","expiresAt","trackOpens","trackClicks","response","tenantQuery","notificationId","sendNotification","sendWithTemplate","templateSlug","trim","length","ValidationError","Object","keys","email","userId","channelId","platform","timezone","result","triggerNotificationWithTemplate","firstNotification","notifications","totalTriggered","totalRequested","totalFailed","id","status","sendBatch","count","batchSize","map","n","delayBetweenBatches","batchId","sendBatchNotifications","queued","totalQueued","failed","getNotification","query","notification","getNotifications","filter","startDate","endDate","undefined","limit","offset","getTemplate","slug","locale","notificationTemplate","getTemplates","notificationTemplates","getStats","notificationStats","markAsRead","notificationIds","markAllAsRead","deleteNotifications","deleteAllReadNotifications","phoneNumber","pushToken","NotificationsModule","options","title","message","userIds","userCount","redirectUrl","appName","sms","successCount","createNotification","failureCount","errors","sendToUser","debug","search","markMultipleAsRead","markNotificationsAsRead","markAllMyNotificationsAsRead","deleteNotification","deleteMultiple","getUnreadCount","unreadCount","sendChannelNotification","recipients","includeInApp","recipientCount","inAppUserCount","results","Promise","allSettled","forEach","index","value","push","triggerNotification","reason","Error","error","sendTemplateNotification"],"mappings":"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","file":"chunk-ZHQUXD6S.js","sourcesContent":["/**\n * Tenant-Backend Notifications Module\n * Comprehensive notification system supporting 10+ channels via tenant-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\n// ========================================\n// Enums\n// ========================================\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n PUSH = 'PUSH',\n IN_APP = 'IN_APP',\n WEBHOOK = 'WEBHOOK',\n WHATSAPP = 'WHATSAPP',\n TEAMS = 'TEAMS',\n SLACK = 'SLACK',\n TELEGRAM = 'TELEGRAM',\n DISCORD = 'DISCORD',\n}\n\nexport enum NotificationPriority {\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n URGENT = 'URGENT',\n}\n\nexport enum NotificationType {\n TRANSACTIONAL = 'TRANSACTIONAL',\n MARKETING = 'MARKETING',\n SYSTEM = 'SYSTEM',\n ALERT = 'ALERT',\n}\n\n// ========================================\n// Types & Interfaces\n// ========================================\n\nexport interface RecipientInput {\n userId?: string;\n email?: string;\n phoneNumber?: string;\n pushToken?: string;\n whatsappNumber?: string;\n teamsUserId?: string;\n slackUserId?: string;\n webhookUrl?: string;\n name?: string;\n locale?: string;\n timezone?: string;\n}\n\nexport interface SendNotificationInput {\n recipient: RecipientInput;\n channel: NotificationChannel;\n type?: NotificationType;\n priority?: NotificationPriority;\n subject?: string;\n body: string;\n htmlBody?: string;\n data?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n}\n\nexport interface SendWithTemplateInput {\n templateSlug: string;\n variables: Record<string, unknown>;\n recipient: RecipientInput;\n priority?: NotificationPriority;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n /** Specific channel instance ID from channel service (takes precedence) */\n channelId?: string;\n /** Platform type for auto-failover (EMAIL, SMS, etc.) - used if channelId not provided */\n platform?: NotificationChannel;\n /** Timezone for scheduling */\n timezone?: string;\n}\n\nexport interface BatchNotificationInput {\n notifications: SendNotificationInput[];\n batchSize?: number;\n delayBetweenBatches?: number;\n priority?: NotificationPriority;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n channel: NotificationChannel;\n type: NotificationType;\n priority: NotificationPriority;\n status: string;\n deliveryStatus?: string;\n title: string;\n message: string;\n htmlMessage?: string;\n subject?: string;\n recipientEmail?: string;\n recipientPhone?: string;\n trackOpens: boolean;\n trackClicks: boolean;\n openedAt?: string;\n clickedAt?: string;\n sentAt?: string;\n deliveredAt?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationTemplate {\n id: string;\n name: string;\n slug: string;\n description?: string;\n channel: NotificationChannel;\n type: NotificationType;\n locale: string;\n subject?: string;\n bodyTemplate: string;\n htmlTemplate?: string;\n variables: Array<{\n name: string;\n type: string;\n required: boolean;\n defaultValue?: unknown;\n description?: string;\n example?: unknown;\n }>;\n enabled: boolean;\n version: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationStats {\n total: number;\n pending: number;\n queued: number;\n processing: number;\n sent: number;\n delivered: number;\n failed: number;\n byChannel: Record<string, number>;\n byType: Record<string, number>;\n}\n\n// ========================================\n// Tenant Notifications Module\n// ========================================\n\n/**\n * Tenant-Backend Notifications Module\n * Provides access to the centralized notification system\n */\nexport class TenantNotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send a single notification\n */\n public async send(input: SendNotificationInput): Promise<string> {\n // Validate inputs\n this.validateSendInput(input);\n\n logger.info('[TenantNotifications] Sending notification', {\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation SendNotification($input: SendNotificationInput!) {\n sendNotification(input: $input)\n }\n `;\n\n const variables = {\n input: {\n recipient: input.recipient,\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n subject: input.subject,\n body: input.body,\n htmlBody: input.htmlBody,\n data: input.data,\n metadata: input.metadata,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendNotification: string;\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Notification sent', {\n notificationId: response.sendNotification,\n });\n\n return response.sendNotification;\n }\n\n /**\n * Send notification using a template\n */\n public async sendWithTemplate(input: SendWithTemplateInput): Promise<string> {\n // Validate inputs\n if (!input.templateSlug || input.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!input.variables || Object.keys(input.variables).length === 0) {\n throw new ValidationError('Template variables are required');\n }\n\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId)) {\n throw new ValidationError('Recipient email or userId is required');\n }\n\n logger.info('[TenantNotifications] Sending notification with template', {\n templateSlug: input.templateSlug,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n templateSlug: input.templateSlug,\n variables: input.variables,\n recipient: input.recipient,\n priority: input.priority || NotificationPriority.MEDIUM,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n // Platform is required for notification delivery routing\n // If channelId is specified, it takes precedence; otherwise platform determines delivery\n channelId: input.channelId,\n platform: input.platform || NotificationChannel.EMAIL,\n timezone: input.timezone,\n },\n };\n\n const response = await this.client.tenantQuery<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const result = response.triggerNotificationWithTemplate;\n const firstNotification = result.notifications[0];\n\n if (result.totalTriggered === 0 || !firstNotification) {\n throw new ValidationError(\n `Notification trigger failed: requested=${result.totalRequested}, triggered=${result.totalTriggered}, failed=${result.totalFailed}`\n );\n }\n\n logger.info('[TenantNotifications] Notification sent with template', {\n notificationId: firstNotification.id,\n status: firstNotification.status,\n totalTriggered: result.totalTriggered,\n totalFailed: result.totalFailed,\n });\n\n return firstNotification.id;\n }\n\n /**\n * Send batch notifications\n */\n public async sendBatch(input: BatchNotificationInput): Promise<{\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n }> {\n if (!input.notifications || input.notifications.length === 0) {\n throw new ValidationError('At least one notification is required');\n }\n\n logger.info('[TenantNotifications] Sending batch notifications', {\n count: input.notifications.length,\n batchSize: input.batchSize,\n });\n\n const mutation = `\n mutation SendBatchNotifications($input: BatchNotificationInput!) {\n sendBatchNotifications(input: $input) {\n totalRequested\n totalQueued\n totalFailed\n batchId\n }\n }\n `;\n\n const variables = {\n input: {\n notifications: input.notifications.map((n) => ({\n recipient: n.recipient,\n channel: n.channel,\n type: n.type || NotificationType.TRANSACTIONAL,\n priority: n.priority || NotificationPriority.MEDIUM,\n subject: n.subject,\n body: n.body,\n htmlBody: n.htmlBody,\n data: n.data,\n metadata: n.metadata,\n scheduledFor: n.scheduledFor?.toISOString(),\n expiresAt: n.expiresAt?.toISOString(),\n trackOpens: n.trackOpens,\n trackClicks: n.trackClicks,\n })),\n batchSize: input.batchSize,\n delayBetweenBatches: input.delayBetweenBatches,\n priority: input.priority,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendBatchNotifications: {\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n };\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Batch notifications sent', {\n batchId: response.sendBatchNotifications.batchId,\n queued: response.sendBatchNotifications.totalQueued,\n failed: response.sendBatchNotifications.totalFailed,\n });\n\n return response.sendBatchNotifications;\n }\n\n /**\n * Get a notification by ID\n */\n public async getNotification(id: string): Promise<Notification | null> {\n const query = `\n query GetNotification($id: ID!) {\n notification(id: $id) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n htmlMessage\n subject\n recipientEmail\n recipientPhone\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notification: Notification | null;\n }>(query, { id }, this.context);\n\n return response.notification;\n }\n\n /**\n * Get notifications with filters\n */\n public async getNotifications(filter?: {\n userId?: string;\n channel?: NotificationChannel;\n type?: NotificationType;\n status?: string;\n priority?: NotificationPriority;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n }): Promise<Notification[]> {\n const query = `\n query GetNotifications($filter: NotificationFilterInput, $limit: Int, $offset: Int) {\n notifications(filter: $filter, limit: $limit, offset: $offset) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n subject\n recipientEmail\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n channel: filter.channel,\n type: filter.type,\n status: filter.status,\n priority: filter.priority,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n limit: filter?.limit || 50,\n offset: filter?.offset || 0,\n };\n\n const response = await this.client.tenantQuery<{\n notifications: Notification[];\n }>(query, variables, this.context);\n\n return response.notifications;\n }\n\n /**\n * Get notification template\n */\n public async getTemplate(slug: string, locale?: string): Promise<NotificationTemplate | null> {\n const query = `\n query GetNotificationTemplate($slug: String!, $locale: String) {\n notificationTemplate(slug: $slug, locale: $locale) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplate: NotificationTemplate | null;\n }>(query, { slug, locale }, this.context);\n\n return response.notificationTemplate;\n }\n\n /**\n * Get all notification templates\n */\n public async getTemplates(filter?: {\n channel?: NotificationChannel;\n type?: NotificationType;\n enabled?: boolean;\n }): Promise<NotificationTemplate[]> {\n const query = `\n query GetNotificationTemplates($filter: TemplateFilterInput) {\n notificationTemplates(filter: $filter) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplates: NotificationTemplate[];\n }>(query, { filter }, this.context);\n\n return response.notificationTemplates;\n }\n\n /**\n * Get notification statistics\n */\n public async getStats(filter?: { userId?: string; startDate?: Date; endDate?: Date }): Promise<NotificationStats> {\n const query = `\n query GetNotificationStats($filter: NotificationFilterInput) {\n notificationStats(filter: $filter) {\n total\n pending\n queued\n processing\n sent\n delivered\n failed\n byChannel\n byType\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n };\n\n const response = await this.client.tenantQuery<{\n notificationStats: NotificationStats;\n }>(query, variables, this.context);\n\n return response.notificationStats;\n }\n\n /**\n * Mark notifications as read\n */\n public async markAsRead(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications marked as read', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<boolean> {\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All notifications marked as read');\n\n return true;\n }\n\n /**\n * Delete notifications\n */\n public async deleteNotifications(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications deleted', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Delete all read notifications for the current user\n */\n public async deleteAllReadNotifications(): Promise<boolean> {\n const mutation = `\n mutation DeleteMyReadNotifications {\n deleteMyReadNotifications\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All read notifications deleted');\n\n return true;\n }\n\n /**\n * Validate send notification input\n */\n private validateSendInput(input: SendNotificationInput): void {\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId && !input.recipient.phoneNumber)) {\n throw new ValidationError('Recipient email, userId, or phoneNumber is required');\n }\n\n if (!input.channel) {\n throw new ValidationError('Notification channel is required');\n }\n\n if (!input.body || input.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n // Channel-specific validation\n if (input.channel === NotificationChannel.EMAIL && !input.recipient.email) {\n throw new ValidationError('Recipient email is required for EMAIL channel');\n }\n\n if (input.channel === NotificationChannel.SMS && !input.recipient.phoneNumber) {\n throw new ValidationError('Recipient phone number is required for SMS channel');\n }\n\n if (input.channel === NotificationChannel.PUSH && !input.recipient.pushToken && !input.recipient.userId) {\n throw new ValidationError('Recipient push token or userId is required for PUSH channel');\n }\n }\n}\n","/**\n * Notifications Module\n * Send in-app, email, SMS, and push notifications via workspaces-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\nexport enum NotificationType {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n WHATSAPP = 'WHATSAPP',\n PUSH = 'PUSH',\n SLACK = 'SLACK',\n TEAMS = 'TEAMS',\n WEBHOOK = 'WEBHOOK',\n}\n\n// Re-export from tenant-notifications\nexport { NotificationPriority, TenantNotificationsModule } from './tenant-notifications.js';\n\nexport interface SendNotificationOptions {\n /** Notification title */\n title: string;\n /** Notification message */\n message: string;\n /** Notification type */\n type?: NotificationType;\n /** Target user IDs */\n userIds: string[];\n /** Optional redirect URL */\n redirectUrl?: string;\n /** Application name */\n appName?: string;\n /** Send email notification */\n email?: boolean;\n /** Send SMS notification */\n sms?: boolean;\n}\n\nexport interface NotificationResponse {\n /** Number of successful notifications */\n successCount: number;\n /** Number of failed notifications */\n failureCount: number;\n /** Error messages if any */\n errors: string[];\n /** Created notification IDs */\n notificationIds?: string[];\n}\n\nexport interface GetNotificationsOptions {\n /** User ID to get notifications for */\n userId: string;\n /** Filter by status */\n status?: 'unread' | 'read' | 'all';\n /** Filter by type */\n type?: NotificationType;\n /** Filter by app name */\n appName?: string;\n /** Search term */\n search?: string;\n /** Limit number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n status: 'unread' | 'read';\n redirectUrl?: string;\n appName?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RecipientInput {\n email?: string;\n locale?: string;\n name?: string;\n phoneNumber?: string;\n pushToken?: string;\n slackUserId?: string;\n teamsUserId?: string;\n timezone?: string;\n userId?: string;\n webhookUrl?: string;\n whatsappNumber?: string;\n}\n\nexport interface SendChannelNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Recipient information for primary channel */\n recipient: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Notification subject (for EMAIL) */\n subject?: string;\n /** Notification body/message */\n body: string;\n /** HTML body (for EMAIL) */\n htmlBody?: string;\n /** Notification type */\n type?: NotificationType;\n /** Application name */\n appName?: string;\n /** Redirect URL */\n redirectUrl?: string;\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\nexport interface SendTemplateNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Template slug to use */\n templateSlug: string;\n /** Template variables */\n variables: Record<string, unknown>;\n /** Recipient information for primary channel */\n recipient?: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Application name */\n appName?: string;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Scheduled delivery time */\n scheduledFor?: Date;\n /** Timezone for scheduling */\n timezone?: string;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\n/**\n * Notifications Module\n */\nexport class NotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send notification to users\n */\n public async send(options: SendNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.title || options.title.trim().length === 0) {\n throw new ValidationError('Notification title is required');\n }\n\n if (!options.message || options.message.trim().length === 0) {\n throw new ValidationError('Notification message is required');\n }\n\n if (!options.userIds || options.userIds.length === 0) {\n throw new ValidationError('At least one user ID is required');\n }\n\n logger.info('[Notifications] Sending notification', {\n title: options.title,\n userCount: options.userIds.length,\n type: options.type || NotificationType.INFO,\n });\n\n const mutation = `\n mutation CreateNotification($input: CreateNotificationInput!) {\n createNotification(input: $input) {\n successCount\n failureCount\n errors\n notifications {\n id\n }\n }\n }\n `;\n\n const variables = {\n input: {\n title: options.title,\n message: options.message,\n type: options.type || NotificationType.INFO,\n userIds: options.userIds,\n redirectUrl: options.redirectUrl || '',\n appName: options.appName,\n email: options.email || false,\n sms: options.sms || false,\n },\n };\n\n const response = await this.client.query<{\n createNotification: NotificationResponse & { notifications: Array<{ id: string }> };\n }>(mutation, variables, this.context);\n\n const result = {\n successCount: response.createNotification.successCount,\n failureCount: response.createNotification.failureCount,\n errors: response.createNotification.errors,\n notificationIds: response.createNotification.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Notification sent', {\n successCount: result.successCount,\n failureCount: result.failureCount,\n });\n\n return result;\n }\n\n /**\n * Send notification to a single user (convenience method)\n */\n public async sendToUser(\n userId: string,\n title: string,\n message: string,\n options?: Omit<SendNotificationOptions, 'userIds' | 'title' | 'message'>\n ): Promise<NotificationResponse> {\n return this.send({\n title,\n message,\n userIds: [userId],\n ...options,\n });\n }\n\n /**\n * Get notifications for a user\n */\n public async getNotifications(options: GetNotificationsOptions): Promise<{\n notifications: Notification[];\n total: number;\n unreadCount: number;\n }> {\n logger.debug('[Notifications] Getting notifications', { userId: options.userId });\n\n const query = `\n query GetNotifications(\n $userId: ID!\n $status: NotificationStatus\n $type: NotificationType\n $appName: String\n $search: String\n $limit: Int\n $offset: Int\n ) {\n getNotifications(\n userId: $userId\n status: $status\n type: $type\n appName: $appName\n search: $search\n limit: $limit\n offset: $offset\n ) {\n notifications {\n id\n userId\n title\n message\n type\n status\n redirectUrl\n appName\n createdAt\n updatedAt\n }\n total\n unreadCount\n }\n }\n `;\n\n const variables = {\n userId: options.userId,\n status: options.status,\n type: options.type,\n appName: options.appName,\n search: options.search,\n limit: options.limit || 20,\n offset: options.offset || 0,\n };\n\n const response = await this.client.query<{\n getNotifications: {\n notifications: Notification[];\n total: number;\n unreadCount: number;\n };\n }>(query, variables, this.context);\n\n return response.getNotifications;\n }\n\n /**\n * Mark notification as read\n */\n public async markAsRead(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Marking notification as read', { notificationId });\n\n const mutation = `\n mutation MarkNotificationAsRead($notificationId: ID!) {\n markNotificationAsRead(notificationId: $notificationId) {\n id\n status\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification marked as read', { notificationId });\n\n return true;\n }\n\n /**\n * Mark multiple notifications as read\n */\n public async markMultipleAsRead(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Marking multiple notifications as read', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markNotificationsAsRead: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications marked as read', {\n count: response.markNotificationsAsRead.count,\n });\n\n return response.markNotificationsAsRead.count;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<number> {\n logger.debug('[Notifications] Marking all notifications as read');\n\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markAllMyNotificationsAsRead: { count: number };\n }>(mutation, {}, this.context);\n\n logger.info('[Notifications] All notifications marked as read', {\n count: response.markAllMyNotificationsAsRead.count,\n });\n\n return response.markAllMyNotificationsAsRead.count;\n }\n\n /**\n * Delete notification\n */\n public async deleteNotification(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Deleting notification', { notificationId });\n\n const mutation = `\n mutation DeleteNotification($notificationId: ID!) {\n deleteNotification(notificationId: $notificationId) {\n success\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification deleted', { notificationId });\n\n return true;\n }\n\n /**\n * Delete multiple notifications\n */\n public async deleteMultiple(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Deleting multiple notifications', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n deleteNotifications: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications deleted', {\n count: response.deleteNotifications.count,\n });\n\n return response.deleteNotifications.count;\n }\n\n /**\n * Get unread notification count for a user\n */\n public async getUnreadCount(userId: string): Promise<number> {\n const result = await this.getNotifications({\n userId,\n status: 'unread',\n limit: 0,\n });\n\n return result.unreadCount;\n }\n\n /**\n * Send notification via specific channel (EMAIL, SMS, WHATSAPP, etc.)\n * with optional in-app notification\n */\n public async sendChannelNotification(options: SendChannelNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.body || options.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending channel notification', {\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotification($input: TriggerNotificationInput!) {\n triggerNotification(input: $input) {\n id\n status\n deliveryStatus\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n notification: {\n subject: options.subject || '',\n body: options.body,\n htmlBody: options.htmlBody || '',\n channel: options.platform,\n type: options.type || NotificationType.INFO,\n recipient: options.recipient,\n appName: options.appName,\n redirectUrl: options.redirectUrl || '',\n metadata: options.metadata || {},\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n },\n },\n };\n\n // Handle bulk recipients\n if (options.recipients && options.recipients.length > 1) {\n const results = await Promise.allSettled(\n options.recipients.map((recipient) =>\n this.client.query(\n mutation,\n {\n input: {\n ...variables.input,\n notification: {\n ...variables.input.notification,\n recipient,\n },\n },\n },\n this.context\n )\n )\n );\n\n let successCount = 0;\n let failureCount = 0;\n const errors: string[] = [];\n const notificationIds: string[] = [];\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled') {\n successCount++;\n const response = result.value as { triggerNotification: { id: string } };\n notificationIds.push(response.triggerNotification.id);\n } else {\n failureCount++;\n errors.push(\n `Recipient ${index + 1}: ${result.reason instanceof Error ? result.reason.message : 'Unknown error'}`\n );\n }\n });\n\n const response: NotificationResponse = {\n successCount,\n failureCount,\n errors,\n notificationIds,\n };\n\n logger.info('[Notifications] Channel notification sent (bulk)', {\n successCount,\n failureCount,\n });\n\n return response;\n } else {\n // Single recipient\n try {\n const response = await this.client.query<{\n triggerNotification: { id: string; status: string; deliveryStatus: string };\n }>(mutation, variables, this.context);\n\n const result: NotificationResponse = {\n successCount: 1,\n failureCount: 0,\n errors: [],\n notificationIds: [response.triggerNotification.id],\n };\n\n logger.info('[Notifications] Channel notification sent', {\n notificationId: response.triggerNotification.id,\n status: response.triggerNotification.status,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send channel notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n }\n\n /**\n * Send notification using a template with optional in-app notification\n */\n public async sendTemplateNotification(options: SendTemplateNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.templateSlug || options.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!options.variables || typeof options.variables !== 'object') {\n throw new ValidationError('Template variables are required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending template notification', {\n templateSlug: options.templateSlug,\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n templateSlug: options.templateSlug,\n variables: options.variables,\n recipient: options.recipient,\n recipients: options.recipients,\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n scheduledFor: options.scheduledFor?.toISOString(),\n timezone: options.timezone,\n },\n };\n\n try {\n const response = await this.client.query<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const data = response.triggerNotificationWithTemplate;\n\n const result: NotificationResponse = {\n successCount: data.totalTriggered,\n failureCount: data.totalFailed,\n errors: [],\n notificationIds: data.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Template notification sent', {\n templateSlug: options.templateSlug,\n totalTriggered: data.totalTriggered,\n totalFailed: data.totalFailed,\n notificationIds: result.notificationIds,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send template notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/notifications/tenant-notifications.ts","../src/notifications/index.ts"],"names":["NotificationChannel","NotificationPriority","NotificationType","TenantNotificationsModule","client","context","send","input","validateSendInput","logger","info","channel","type","priority","mutation","variables","recipient","subject","body","htmlBody","data","metadata","scheduledFor","toISOString","expiresAt","trackOpens","trackClicks","response","tenantQuery","notificationId","sendNotification","sendWithTemplate","templateSlug","trim","length","ValidationError","Object","keys","email","userId","channelId","platform","timezone","result","triggerNotificationWithTemplate","firstNotification","notifications","totalTriggered","totalRequested","totalFailed","id","status","sendBatch","count","batchSize","map","n","delayBetweenBatches","batchId","sendBatchNotifications","queued","totalQueued","failed","getNotification","query","notification","getNotifications","filter","startDate","endDate","undefined","limit","offset","getTemplate","slug","locale","notificationTemplate","getTemplates","notificationTemplates","getStats","notificationStats","markAsRead","notificationIds","markAllAsRead","deleteNotifications","deleteAllReadNotifications","phoneNumber","pushToken","NotificationsModule","options","title","message","userIds","userCount","redirectUrl","appName","sms","successCount","createNotification","failureCount","errors","sendToUser","debug","search","markMultipleAsRead","markNotificationsAsRead","markAllMyNotificationsAsRead","deleteNotification","deleteMultiple","getUnreadCount","unreadCount","sendChannelNotification","recipients","includeInApp","recipientCount","inAppUserCount","results","Promise","allSettled","forEach","index","value","push","triggerNotification","reason","Error","error","sendTemplateNotification"],"mappings":";;;;;AAAA,IAAA,4BAAA,GAAA;;;;;;;AAcO,IAAKA,mBAAAA,6BAAAA,oBAAAA,EAAAA;;;;;;;;;;;AAAAA,EAAAA,OAAAA,oBAAAA;;AAaL,IAAKC,oBAAAA,6BAAAA,qBAAAA,EAAAA;;;;;AAAAA,EAAAA,OAAAA,qBAAAA;;AAOL,IAAKC,gBAAAA,6BAAAA,iBAAAA,EAAAA;;;;;AAAAA,EAAAA,OAAAA,iBAAAA;;AAsIL,IAAMC,4BAAN,MAAMA;EAxKb;;;;;AAyKE,EAAA,WAAA,CACUC,QACAC,OAAAA,EACR;SAFQD,MAAAA,GAAAA,MAAAA;SACAC,OAAAA,GAAAA,OAAAA;AACP,EAAA;;;;AAKH,EAAA,MAAaC,KAAKC,KAAAA,EAA+C;AAE/D,IAAA,IAAA,CAAKC,kBAAkBD,KAAAA,CAAAA;AAEvBE,IAAAA,MAAAA,CAAOC,KAAK,4CAAA,EAA8C;AACxDC,MAAAA,OAAAA,EAASJ,KAAAA,CAAMI,OAAAA;AACfC,MAAAA,IAAAA,EAAML,MAAMK,IAAAA,IAAI,eAAA;AAChBC,MAAAA,QAAAA,EAAUN,MAAMM,QAAAA,IAAQ;KAC1B,CAAA;AAEA,IAAA,MAAMC,QAAAA,GAAW;;;;;AAMjB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLS,QAAAA,SAAAA,EAAWT,KAAAA,CAAMS,SAAAA;AACjBL,QAAAA,OAAAA,EAASJ,KAAAA,CAAMI,OAAAA;AACfC,QAAAA,IAAAA,EAAML,MAAMK,IAAAA,IAAI,eAAA;AAChBC,QAAAA,QAAAA,EAAUN,MAAMM,QAAAA,IAAQ,QAAA;AACxBI,QAAAA,OAAAA,EAASV,KAAAA,CAAMU,OAAAA;AACfC,QAAAA,IAAAA,EAAMX,KAAAA,CAAMW,IAAAA;AACZC,QAAAA,QAAAA,EAAUZ,KAAAA,CAAMY,QAAAA;AAChBC,QAAAA,IAAAA,EAAMb,KAAAA,CAAMa,IAAAA;AACZC,QAAAA,QAAAA,EAAUd,KAAAA,CAAMc,QAAAA;QAChBC,YAAAA,EAAcf,KAAAA,CAAMe,cAAcC,WAAAA,EAAAA;QAClCC,SAAAA,EAAWjB,KAAAA,CAAMiB,WAAWD,WAAAA,EAAAA;AAC5BE,QAAAA,UAAAA,EAAYlB,KAAAA,CAAMkB,UAAAA;AAClBC,QAAAA,WAAAA,EAAanB,KAAAA,CAAMmB;AACrB;AACF,KAAA;AAEA,IAAA,MAAMC,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCd,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpCI,IAAAA,MAAAA,CAAOC,KAAK,yCAAA,EAA2C;AACrDmB,MAAAA,cAAAA,EAAgBF,QAAAA,CAASG;KAC3B,CAAA;AAEA,IAAA,OAAOH,QAAAA,CAASG,gBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaC,iBAAiBxB,KAAAA,EAA+C;AAE3E,IAAA,IAAI,CAACA,MAAMyB,YAAAA,IAAgBzB,KAAAA,CAAMyB,aAAaC,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AACjE,MAAA,MAAM,IAAIC,gBAAgB,2BAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAAC5B,MAAMQ,SAAAA,IAAaqB,MAAAA,CAAOC,KAAK9B,KAAAA,CAAMQ,SAAS,CAAA,CAAEmB,MAAAA,KAAW,CAAA,EAAG;AACjE,MAAA,MAAM,IAAIC,gBAAgB,iCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAAC5B,KAAAA,CAAMS,SAAAA,IAAc,CAACT,KAAAA,CAAMS,UAAUsB,KAAAA,IAAS,CAAC/B,KAAAA,CAAMS,SAAAA,CAAUuB,MAAAA,EAAS;AAC3E,MAAA,MAAM,IAAIJ,gBAAgB,uCAAA,CAAA;AAC5B,IAAA;AAEA1B,IAAAA,MAAAA,CAAOC,KAAK,0DAAA,EAA4D;AACtEsB,MAAAA,YAAAA,EAAczB,KAAAA,CAAMyB,YAAAA;AACpBnB,MAAAA,QAAAA,EAAUN,MAAMM,QAAAA,IAAQ;KAC1B,CAAA;AAEA,IAAA,MAAMC,QAAAA,GAAW;;;;;;;;;;;;;;AAejB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLyB,QAAAA,YAAAA,EAAczB,KAAAA,CAAMyB,YAAAA;AACpBjB,QAAAA,SAAAA,EAAWR,KAAAA,CAAMQ,SAAAA;AACjBC,QAAAA,SAAAA,EAAWT,KAAAA,CAAMS,SAAAA;AACjBH,QAAAA,QAAAA,EAAUN,MAAMM,QAAAA,IAAQ,QAAA;QACxBS,YAAAA,EAAcf,KAAAA,CAAMe,cAAcC,WAAAA,EAAAA;QAClCC,SAAAA,EAAWjB,KAAAA,CAAMiB,WAAWD,WAAAA,EAAAA;AAC5BE,QAAAA,UAAAA,EAAYlB,KAAAA,CAAMkB,UAAAA;AAClBC,QAAAA,WAAAA,EAAanB,KAAAA,CAAMmB,WAAAA;;;AAGnBc,QAAAA,SAAAA,EAAWjC,KAAAA,CAAMiC,SAAAA;AACjBC,QAAAA,QAAAA,EAAUlC,MAAMkC,QAAAA,IAAQ,OAAA;AACxBC,QAAAA,QAAAA,EAAUnC,KAAAA,CAAMmC;AAClB;AACF,KAAA;AAEA,IAAA,MAAMf,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAOhCd,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpC,IAAA,MAAMsC,SAAShB,QAAAA,CAASiB,+BAAAA;AACxB,IAAA,MAAMC,iBAAAA,GAAoBF,MAAAA,CAAOG,aAAAA,CAAc,CAAA,CAAA;AAE/C,IAAA,IAAIH,MAAAA,CAAOI,cAAAA,KAAmB,CAAA,IAAK,CAACF,iBAAAA,EAAmB;AACrD,MAAA,MAAM,IAAIV,eAAAA,CACR,CAAA,uCAAA,EAA0CQ,MAAAA,CAAOK,cAAc,CAAA,YAAA,EAAeL,MAAAA,CAAOI,cAAc,CAAA,SAAA,EAAYJ,MAAAA,CAAOM,WAAW,CAAA,CAAE,CAAA;AAEvI,IAAA;AAEAxC,IAAAA,MAAAA,CAAOC,KAAK,uDAAA,EAAyD;AACnEmB,MAAAA,cAAAA,EAAgBgB,iBAAAA,CAAkBK,EAAAA;AAClCC,MAAAA,MAAAA,EAAQN,iBAAAA,CAAkBM,MAAAA;AAC1BJ,MAAAA,cAAAA,EAAgBJ,MAAAA,CAAOI,cAAAA;AACvBE,MAAAA,WAAAA,EAAaN,MAAAA,CAAOM;KACtB,CAAA;AAEA,IAAA,OAAOJ,iBAAAA,CAAkBK,EAAAA;AAC3B,EAAA;;;;AAKA,EAAA,MAAaE,UAAU7C,KAAAA,EAKpB;AACD,IAAA,IAAI,CAACA,KAAAA,CAAMuC,aAAAA,IAAiBvC,KAAAA,CAAMuC,aAAAA,CAAcZ,WAAW,CAAA,EAAG;AAC5D,MAAA,MAAM,IAAIC,gBAAgB,uCAAA,CAAA;AAC5B,IAAA;AAEA1B,IAAAA,MAAAA,CAAOC,KAAK,mDAAA,EAAqD;AAC/D2C,MAAAA,KAAAA,EAAO9C,MAAMuC,aAAAA,CAAcZ,MAAAA;AAC3BoB,MAAAA,SAAAA,EAAW/C,KAAAA,CAAM+C;KACnB,CAAA;AAEA,IAAA,MAAMxC,QAAAA,GAAW;;;;;;;;;;AAWjB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLuC,QAAAA,aAAAA,EAAevC,KAAAA,CAAMuC,aAAAA,CAAcS,GAAAA,CAAI,CAACC,CAAAA,MAAO;AAC7CxC,UAAAA,SAAAA,EAAWwC,CAAAA,CAAExC,SAAAA;AACbL,UAAAA,OAAAA,EAAS6C,CAAAA,CAAE7C,OAAAA;AACXC,UAAAA,IAAAA,EAAM4C,EAAE5C,IAAAA,IAAI,eAAA;AACZC,UAAAA,QAAAA,EAAU2C,EAAE3C,QAAAA,IAAQ,QAAA;AACpBI,UAAAA,OAAAA,EAASuC,CAAAA,CAAEvC,OAAAA;AACXC,UAAAA,IAAAA,EAAMsC,CAAAA,CAAEtC,IAAAA;AACRC,UAAAA,QAAAA,EAAUqC,CAAAA,CAAErC,QAAAA;AACZC,UAAAA,IAAAA,EAAMoC,CAAAA,CAAEpC,IAAAA;AACRC,UAAAA,QAAAA,EAAUmC,CAAAA,CAAEnC,QAAAA;UACZC,YAAAA,EAAckC,CAAAA,CAAElC,cAAcC,WAAAA,EAAAA;UAC9BC,SAAAA,EAAWgC,CAAAA,CAAEhC,WAAWD,WAAAA,EAAAA;AACxBE,UAAAA,UAAAA,EAAY+B,CAAAA,CAAE/B,UAAAA;AACdC,UAAAA,WAAAA,EAAa8B,CAAAA,CAAE9B;SACjB,CAAA,CAAA;AACA4B,QAAAA,SAAAA,EAAW/C,KAAAA,CAAM+C,SAAAA;AACjBG,QAAAA,mBAAAA,EAAqBlD,KAAAA,CAAMkD,mBAAAA;AAC3B5C,QAAAA,QAAAA,EAAUN,KAAAA,CAAMM;AAClB;AACF,KAAA;AAEA,IAAA,MAAMc,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAOhCd,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpCI,IAAAA,MAAAA,CAAOC,KAAK,gDAAA,EAAkD;AAC5DgD,MAAAA,OAAAA,EAAS/B,SAASgC,sBAAAA,CAAuBD,OAAAA;AACzCE,MAAAA,MAAAA,EAAQjC,SAASgC,sBAAAA,CAAuBE,WAAAA;AACxCC,MAAAA,MAAAA,EAAQnC,SAASgC,sBAAAA,CAAuBV;KAC1C,CAAA;AAEA,IAAA,OAAOtB,QAAAA,CAASgC,sBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaI,gBAAgBb,EAAAA,EAA0C;AACrE,IAAA,MAAMc,KAAAA,GAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4Bd,IAAA,MAAMrC,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCoC,KAAAA,EAAO;AAAEd,MAAAA;AAAG,KAAA,EAAG,KAAK7C,OAAO,CAAA;AAE9B,IAAA,OAAOsB,QAAAA,CAASsC,YAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaC,iBAAiBC,MAAAA,EAUF;AAC1B,IAAA,MAAMH,KAAAA,GAAQ;;;;;;;;;;;;;;;;;;;;;;;;;AA0Bd,IAAA,MAAMjD,SAAAA,GAAY;AAChBoD,MAAAA,MAAAA,EAAQA,MAAAA,GACJ;AACE5B,QAAAA,MAAAA,EAAQ4B,MAAAA,CAAO5B,MAAAA;AACf5B,QAAAA,OAAAA,EAASwD,MAAAA,CAAOxD,OAAAA;AAChBC,QAAAA,IAAAA,EAAMuD,MAAAA,CAAOvD,IAAAA;AACbuC,QAAAA,MAAAA,EAAQgB,MAAAA,CAAOhB,MAAAA;AACftC,QAAAA,QAAAA,EAAUsD,MAAAA,CAAOtD,QAAAA;QACjBuD,SAAAA,EAAWD,MAAAA,CAAOC,WAAW7C,WAAAA,EAAAA;QAC7B8C,OAAAA,EAASF,MAAAA,CAAOE,SAAS9C,WAAAA;OAC3B,GACA+C,MAAAA;AACJC,MAAAA,KAAAA,EAAOJ,QAAQI,KAAAA,IAAS,EAAA;AACxBC,MAAAA,MAAAA,EAAQL,QAAQK,MAAAA,IAAU;AAC5B,KAAA;AAEA,IAAA,MAAM7C,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCoC,KAAAA,EAAOjD,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEjC,IAAA,OAAOsB,QAAAA,CAASmB,aAAAA;AAClB,EAAA;;;;EAKA,MAAa2B,WAAAA,CAAYC,MAAcC,MAAAA,EAAuD;AAC5F,IAAA,MAAMX,KAAAA,GAAQ;;;;;;;;;;;;;;;;;;;;;AAsBd,IAAA,MAAMrC,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCoC,KAAAA,EAAO;AAAEU,MAAAA,IAAAA;AAAMC,MAAAA;AAAO,KAAA,EAAG,KAAKtE,OAAO,CAAA;AAExC,IAAA,OAAOsB,QAAAA,CAASiD,oBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaC,aAAaV,MAAAA,EAIU;AAClC,IAAA,MAAMH,KAAAA,GAAQ;;;;;;;;;;;;;;;;;;;;;AAsBd,IAAA,MAAMrC,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCoC,KAAAA,EAAO;AAAEG,MAAAA;AAAO,KAAA,EAAG,KAAK9D,OAAO,CAAA;AAElC,IAAA,OAAOsB,QAAAA,CAASmD,qBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaC,SAASZ,MAAAA,EAA4F;AAChH,IAAA,MAAMH,KAAAA,GAAQ;;;;;;;;;;;;;;;AAgBd,IAAA,MAAMjD,SAAAA,GAAY;AAChBoD,MAAAA,MAAAA,EAAQA,MAAAA,GACJ;AACE5B,QAAAA,MAAAA,EAAQ4B,MAAAA,CAAO5B,MAAAA;QACf6B,SAAAA,EAAWD,MAAAA,CAAOC,WAAW7C,WAAAA,EAAAA;QAC7B8C,OAAAA,EAASF,MAAAA,CAAOE,SAAS9C,WAAAA;OAC3B,GACA+C;AACN,KAAA;AAEA,IAAA,MAAM3C,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAOwB,YAEhCoC,KAAAA,EAAOjD,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEjC,IAAA,OAAOsB,QAAAA,CAASqD,iBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAaC,WAAWC,eAAAA,EAA6C;AACnE,IAAA,MAAMpE,QAAAA,GAAW;;;;;AAMjB,IAAA,MAAM,IAAA,CAAKV,MAAAA,CAAOwB,WAAAA,CAAYd,QAAAA,EAAU;AAAEoE,MAAAA;AAAgB,KAAA,EAAG,KAAK7E,OAAO,CAAA;AAEzEI,IAAAA,MAAAA,CAAOC,KAAK,oDAAA,EAAsD;AAChE2C,MAAAA,KAAAA,EAAO6B,eAAAA,CAAgBhD;KACzB,CAAA;AAEA,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKA,EAAA,MAAaiD,aAAAA,GAAkC;AAC7C,IAAA,MAAMrE,QAAAA,GAAW;;;;;AAMjB,IAAA,MAAM,KAAKV,MAAAA,CAAOwB,WAAAA,CAAYd,UAAU,EAAC,EAAG,KAAKT,OAAO,CAAA;AAExDI,IAAAA,MAAAA,CAAOC,KAAK,wDAAA,CAAA;AAEZ,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKA,EAAA,MAAa0E,oBAAoBF,eAAAA,EAA6C;AAC5E,IAAA,MAAMpE,QAAAA,GAAW;;;;;AAMjB,IAAA,MAAM,IAAA,CAAKV,MAAAA,CAAOwB,WAAAA,CAAYd,QAAAA,EAAU;AAAEoE,MAAAA;AAAgB,KAAA,EAAG,KAAK7E,OAAO,CAAA;AAEzEI,IAAAA,MAAAA,CAAOC,KAAK,6CAAA,EAA+C;AACzD2C,MAAAA,KAAAA,EAAO6B,eAAAA,CAAgBhD;KACzB,CAAA;AAEA,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKA,EAAA,MAAamD,0BAAAA,GAA+C;AAC1D,IAAA,MAAMvE,QAAAA,GAAW;;;;;AAMjB,IAAA,MAAM,KAAKV,MAAAA,CAAOwB,WAAAA,CAAYd,UAAU,EAAC,EAAG,KAAKT,OAAO,CAAA;AAExDI,IAAAA,MAAAA,CAAOC,KAAK,sDAAA,CAAA;AAEZ,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKQF,EAAAA,iBAAAA,CAAkBD,KAAAA,EAAoC;AAC5D,IAAA,IAAI,CAACA,KAAAA,CAAMS,SAAAA,IAAc,CAACT,MAAMS,SAAAA,CAAUsB,KAAAA,IAAS,CAAC/B,KAAAA,CAAMS,SAAAA,CAAUuB,MAAAA,IAAU,CAAChC,KAAAA,CAAMS,UAAUsE,WAAAA,EAAc;AAC3G,MAAA,MAAM,IAAInD,gBAAgB,qDAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAAC5B,MAAMI,OAAAA,EAAS;AAClB,MAAA,MAAM,IAAIwB,gBAAgB,kCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAAC5B,MAAMW,IAAAA,IAAQX,KAAAA,CAAMW,KAAKe,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AACjD,MAAA,MAAM,IAAIC,gBAAgB,+BAAA,CAAA;AAC5B,IAAA;AAGA,IAAA,IAAI5B,MAAMI,OAAAA,KAAO,OAAA,IAAkC,CAACJ,KAAAA,CAAMS,UAAUsB,KAAAA,EAAO;AACzE,MAAA,MAAM,IAAIH,gBAAgB,+CAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI5B,MAAMI,OAAAA,KAAO,KAAA,IAAgC,CAACJ,KAAAA,CAAMS,UAAUsE,WAAAA,EAAa;AAC7E,MAAA,MAAM,IAAInD,gBAAgB,oDAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI5B,KAAAA,CAAMI,OAAAA,KAAO,MAAA,IAAiC,CAACJ,KAAAA,CAAMS,UAAUuE,SAAAA,IAAa,CAAChF,KAAAA,CAAMS,SAAAA,CAAUuB,MAAAA,EAAQ;AACvG,MAAA,MAAM,IAAIJ,gBAAgB,6DAAA,CAAA;AAC5B,IAAA;AACF,EAAA;AACF;;;ACnqBO,IAAKjC,iBAAAA,6BAAAA,iBAAAA,EAAAA;;;;;AAAAA,EAAAA,OAAAA,iBAAAA;;AAOL,IAAKF,oBAAAA,6BAAAA,oBAAAA,EAAAA;;;;;;;;AAAAA,EAAAA,OAAAA,oBAAAA;;AA4JL,IAAMwF,sBAAN,MAAMA;EA7Kb;;;;;AA8KE,EAAA,WAAA,CACUpF,QACAC,OAAAA,EACR;SAFQD,MAAAA,GAAAA,MAAAA;SACAC,OAAAA,GAAAA,OAAAA;AACP,EAAA;;;;AAKH,EAAA,MAAaC,KAAKmF,OAAAA,EAAiE;AAEjF,IAAA,IAAI,CAACA,QAAQC,KAAAA,IAASD,OAAAA,CAAQC,MAAMzD,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AACvD,MAAA,MAAM,IAAIC,gBAAgB,gCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAACsD,QAAQE,OAAAA,IAAWF,OAAAA,CAAQE,QAAQ1D,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AAC3D,MAAA,MAAM,IAAIC,gBAAgB,kCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAACsD,OAAAA,CAAQG,OAAAA,IAAWH,OAAAA,CAAQG,OAAAA,CAAQ1D,WAAW,CAAA,EAAG;AACpD,MAAA,MAAM,IAAIC,gBAAgB,kCAAA,CAAA;AAC5B,IAAA;AAEA1B,IAAAA,MAAAA,CAAOC,KAAK,sCAAA,EAAwC;AAClDgF,MAAAA,KAAAA,EAAOD,OAAAA,CAAQC,KAAAA;AACfG,MAAAA,SAAAA,EAAWJ,QAAQG,OAAAA,CAAQ1D,MAAAA;AAC3BtB,MAAAA,IAAAA,EAAM6E,QAAQ7E,IAAAA,IAAI;KACpB,CAAA;AAEA,IAAA,MAAME,QAAAA,GAAW;;;;;;;;;;;;AAajB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLmF,QAAAA,KAAAA,EAAOD,OAAAA,CAAQC,KAAAA;AACfC,QAAAA,OAAAA,EAASF,OAAAA,CAAQE,OAAAA;AACjB/E,QAAAA,IAAAA,EAAM6E,QAAQ7E,IAAAA,IAAI,MAAA;AAClBgF,QAAAA,OAAAA,EAASH,OAAAA,CAAQG,OAAAA;AACjBE,QAAAA,WAAAA,EAAaL,QAAQK,WAAAA,IAAe,EAAA;AACpCC,QAAAA,OAAAA,EAASN,OAAAA,CAAQM,OAAAA;AACjBzD,QAAAA,KAAAA,EAAOmD,QAAQnD,KAAAA,IAAS,KAAA;AACxB0D,QAAAA,GAAAA,EAAKP,QAAQO,GAAAA,IAAO;AACtB;AACF,KAAA;AAEA,IAAA,MAAMrE,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAEhClD,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpC,IAAA,MAAMsC,MAAAA,GAAS;AACbsD,MAAAA,YAAAA,EAActE,SAASuE,kBAAAA,CAAmBD,YAAAA;AAC1CE,MAAAA,YAAAA,EAAcxE,SAASuE,kBAAAA,CAAmBC,YAAAA;AAC1CC,MAAAA,MAAAA,EAAQzE,SAASuE,kBAAAA,CAAmBE,MAAAA;AACpClB,MAAAA,eAAAA,EAAiBvD,SAASuE,kBAAAA,CAAmBpD,aAAAA,CAAcS,IAAI,CAACC,CAAAA,KAAMA,EAAEN,EAAE;AAC5E,KAAA;AAEAzC,IAAAA,MAAAA,CAAOC,KAAK,mCAAA,EAAqC;AAC/CuF,MAAAA,YAAAA,EAActD,MAAAA,CAAOsD,YAAAA;AACrBE,MAAAA,YAAAA,EAAcxD,MAAAA,CAAOwD;KACvB,CAAA;AAEA,IAAA,OAAOxD,MAAAA;AACT,EAAA;;;;AAKA,EAAA,MAAa0D,UAAAA,CACX9D,MAAAA,EACAmD,KAAAA,EACAC,OAAAA,EACAF,OAAAA,EAC+B;AAC/B,IAAA,OAAO,KAAKnF,IAAAA,CAAK;AACfoF,MAAAA,KAAAA;AACAC,MAAAA,OAAAA;MACAC,OAAAA,EAAS;AAACrD,QAAAA;;MACV,GAAGkD;KACL,CAAA;AACF,EAAA;;;;AAKA,EAAA,MAAavB,iBAAiBuB,OAAAA,EAI3B;AACDhF,IAAAA,MAAAA,CAAO6F,MAAM,uCAAA,EAAyC;AAAE/D,MAAAA,MAAAA,EAAQkD,OAAAA,CAAQlD;KAAO,CAAA;AAE/E,IAAA,MAAMyB,KAAAA,GAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCd,IAAA,MAAMjD,SAAAA,GAAY;AAChBwB,MAAAA,MAAAA,EAAQkD,OAAAA,CAAQlD,MAAAA;AAChBY,MAAAA,MAAAA,EAAQsC,OAAAA,CAAQtC,MAAAA;AAChBvC,MAAAA,IAAAA,EAAM6E,OAAAA,CAAQ7E,IAAAA;AACdmF,MAAAA,OAAAA,EAASN,OAAAA,CAAQM,OAAAA;AACjBQ,MAAAA,MAAAA,EAAQd,OAAAA,CAAQc,MAAAA;AAChBhC,MAAAA,KAAAA,EAAOkB,QAAQlB,KAAAA,IAAS,EAAA;AACxBC,MAAAA,MAAAA,EAAQiB,QAAQjB,MAAAA,IAAU;AAC5B,KAAA;AAEA,IAAA,MAAM7C,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAMhCA,KAAAA,EAAOjD,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEjC,IAAA,OAAOsB,QAAAA,CAASuC,gBAAAA;AAClB,EAAA;;;;AAKA,EAAA,MAAae,WAAWpD,cAAAA,EAA0C;AAChEpB,IAAAA,MAAAA,CAAO6F,MAAM,8CAAA,EAAgD;AAAEzE,MAAAA;KAAe,CAAA;AAE9E,IAAA,MAAMf,QAAAA,GAAW;;;;;;;;AASjB,IAAA,MAAM,IAAA,CAAKV,MAAAA,CAAO4D,KAAAA,CAAMlD,QAAAA,EAAU;AAAEe,MAAAA;AAAe,KAAA,EAAG,KAAKxB,OAAO,CAAA;AAElEI,IAAAA,MAAAA,CAAOC,KAAK,6CAAA,EAA+C;AAAEmB,MAAAA;KAAe,CAAA;AAE5E,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKA,EAAA,MAAa2E,mBAAmBtB,eAAAA,EAA4C;AAC1EzE,IAAAA,MAAAA,CAAO6F,MAAM,wDAAA,EAA0D;AACrEjD,MAAAA,KAAAA,EAAO6B,eAAAA,CAAgBhD;KACzB,CAAA;AAEA,IAAA,MAAMpB,QAAAA,GAAW;;;;;;;AAQjB,IAAA,MAAMa,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAEhClD,QAAAA,EAAU;AAAEoE,MAAAA;AAAgB,KAAA,EAAG,KAAK7E,OAAO,CAAA;AAE9CI,IAAAA,MAAAA,CAAOC,KAAK,8CAAA,EAAgD;AAC1D2C,MAAAA,KAAAA,EAAO1B,SAAS8E,uBAAAA,CAAwBpD;KAC1C,CAAA;AAEA,IAAA,OAAO1B,SAAS8E,uBAAAA,CAAwBpD,KAAAA;AAC1C,EAAA;;;;AAKA,EAAA,MAAa8B,aAAAA,GAAiC;AAC5C1E,IAAAA,MAAAA,CAAO6F,MAAM,mDAAA,CAAA;AAEb,IAAA,MAAMxF,QAAAA,GAAW;;;;;;;AAQjB,IAAA,MAAMa,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAEhClD,QAAAA,EAAU,EAAC,EAAG,IAAA,CAAKT,OAAO,CAAA;AAE7BI,IAAAA,MAAAA,CAAOC,KAAK,kDAAA,EAAoD;AAC9D2C,MAAAA,KAAAA,EAAO1B,SAAS+E,4BAAAA,CAA6BrD;KAC/C,CAAA;AAEA,IAAA,OAAO1B,SAAS+E,4BAAAA,CAA6BrD,KAAAA;AAC/C,EAAA;;;;AAKA,EAAA,MAAasD,mBAAmB9E,cAAAA,EAA0C;AACxEpB,IAAAA,MAAAA,CAAO6F,MAAM,uCAAA,EAAyC;AAAEzE,MAAAA;KAAe,CAAA;AAEvE,IAAA,MAAMf,QAAAA,GAAW;;;;;;;AAQjB,IAAA,MAAM,IAAA,CAAKV,MAAAA,CAAO4D,KAAAA,CAAMlD,QAAAA,EAAU;AAAEe,MAAAA;AAAe,KAAA,EAAG,KAAKxB,OAAO,CAAA;AAElEI,IAAAA,MAAAA,CAAOC,KAAK,sCAAA,EAAwC;AAAEmB,MAAAA;KAAe,CAAA;AAErE,IAAA,OAAO,IAAA;AACT,EAAA;;;;AAKA,EAAA,MAAa+E,eAAe1B,eAAAA,EAA4C;AACtEzE,IAAAA,MAAAA,CAAO6F,MAAM,iDAAA,EAAmD;AAC9DjD,MAAAA,KAAAA,EAAO6B,eAAAA,CAAgBhD;KACzB,CAAA;AAEA,IAAA,MAAMpB,QAAAA,GAAW;;;;;;;AAQjB,IAAA,MAAMa,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAEhClD,QAAAA,EAAU;AAAEoE,MAAAA;AAAgB,KAAA,EAAG,KAAK7E,OAAO,CAAA;AAE9CI,IAAAA,MAAAA,CAAOC,KAAK,uCAAA,EAAyC;AACnD2C,MAAAA,KAAAA,EAAO1B,SAASyD,mBAAAA,CAAoB/B;KACtC,CAAA;AAEA,IAAA,OAAO1B,SAASyD,mBAAAA,CAAoB/B,KAAAA;AACtC,EAAA;;;;AAKA,EAAA,MAAawD,eAAetE,MAAAA,EAAiC;AAC3D,IAAA,MAAMI,MAAAA,GAAS,MAAM,IAAA,CAAKuB,gBAAAA,CAAiB;AACzC3B,MAAAA,MAAAA;MACAY,MAAAA,EAAQ,QAAA;MACRoB,KAAAA,EAAO;KACT,CAAA;AAEA,IAAA,OAAO5B,MAAAA,CAAOmE,WAAAA;AAChB,EAAA;;;;;AAMA,EAAA,MAAaC,wBAAwBtB,OAAAA,EAAwE;AAE3G,IAAA,IAAI,CAACA,QAAQvE,IAAAA,IAAQuE,OAAAA,CAAQvE,KAAKe,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AACrD,MAAA,MAAM,IAAIC,gBAAgB,+BAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAACsD,OAAAA,CAAQzE,SAAAA,IAAa,CAACyE,QAAQuB,UAAAA,EAAY;AAC7C,MAAA,MAAM,IAAI7E,gBAAgB,oCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAIsD,OAAAA,CAAQwB,iBAAiB,CAACxB,OAAAA,CAAQG,WAAWH,OAAAA,CAAQG,OAAAA,CAAQ1D,WAAW,CAAA,CAAA,EAAI;AAC9E,MAAA,MAAM,IAAIC,gBAAgB,iDAAA,CAAA;AAC5B,IAAA;AAEA1B,IAAAA,MAAAA,CAAOC,KAAK,8CAAA,EAAgD;AAC1D+B,MAAAA,QAAAA,EAAUgD,OAAAA,CAAQhD,QAAAA;AAClByE,MAAAA,cAAAA,EAAgBzB,OAAAA,CAAQuB,UAAAA,GAAavB,OAAAA,CAAQuB,UAAAA,CAAW9E,MAAAA,GAAS,CAAA;AACjE+E,MAAAA,YAAAA,EAAcxB,OAAAA,CAAQwB,YAAAA;AACtBE,MAAAA,cAAAA,EAAgB1B,OAAAA,CAAQG,OAAAA,GAAUH,OAAAA,CAAQG,OAAAA,CAAQ1D,MAAAA,GAAS;KAC7D,CAAA;AAEA,IAAA,MAAMpB,QAAAA,GAAW;;;;;;;;;AAUjB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLkC,QAAAA,QAAAA,EAAUgD,OAAAA,CAAQhD,QAAAA;AAClBD,QAAAA,SAAAA,EAAWiD,OAAAA,CAAQjD,SAAAA;AACnByE,QAAAA,YAAAA,EAAcxB,QAAQwB,YAAAA,IAAgB,KAAA;QACtCrB,OAAAA,EAASH,OAAAA,CAAQG,WAAW,EAAA;QAC5B3B,YAAAA,EAAc;AACZhD,UAAAA,OAAAA,EAASwE,QAAQxE,OAAAA,IAAW,EAAA;AAC5BC,UAAAA,IAAAA,EAAMuE,OAAAA,CAAQvE,IAAAA;AACdC,UAAAA,QAAAA,EAAUsE,QAAQtE,QAAAA,IAAY,EAAA;AAC9BR,UAAAA,OAAAA,EAAS8E,OAAAA,CAAQhD,QAAAA;AACjB7B,UAAAA,IAAAA,EAAM6E,QAAQ7E,IAAAA,IAAI,MAAA;AAClBI,UAAAA,SAAAA,EAAWyE,OAAAA,CAAQzE,SAAAA;AACnB+E,UAAAA,OAAAA,EAASN,OAAAA,CAAQM,OAAAA;AACjBD,UAAAA,WAAAA,EAAaL,QAAQK,WAAAA,IAAe,EAAA;UACpCzE,QAAAA,EAAUoE,OAAAA,CAAQpE,YAAY,EAAC;AAC/BI,UAAAA,UAAAA,EAAYgE,QAAQhE,UAAAA,IAAc,KAAA;AAClCC,UAAAA,WAAAA,EAAa+D,QAAQ/D,WAAAA,IAAe,KAAA;UACpCF,SAAAA,EAAWiE,OAAAA,CAAQjE,WAAWD,WAAAA;AAChC;AACF;AACF,KAAA;AAGA,IAAA,IAAIkE,OAAAA,CAAQuB,UAAAA,IAAcvB,OAAAA,CAAQuB,UAAAA,CAAW9E,SAAS,CAAA,EAAG;AACvD,MAAA,MAAMkF,OAAAA,GAAU,MAAMC,OAAAA,CAAQC,UAAAA,CAC5B7B,OAAAA,CAAQuB,UAAAA,CAAWzD,GAAAA,CAAI,CAACvC,SAAAA,KACtB,IAAA,CAAKZ,MAAAA,CAAO4D,KAAAA,CACVlD,QAAAA,EACA;QACEP,KAAAA,EAAO;AACL,UAAA,GAAGQ,SAAAA,CAAUR,KAAAA;UACb0D,YAAAA,EAAc;AACZ,YAAA,GAAGlD,UAAUR,KAAAA,CAAM0D,YAAAA;AACnBjD,YAAAA;AACF;AACF;OACF,EACA,IAAA,CAAKX,OAAO,CAAA,CAAA,CAAA;AAKlB,MAAA,IAAI4F,YAAAA,GAAe,CAAA;AACnB,MAAA,IAAIE,YAAAA,GAAe,CAAA;AACnB,MAAA,MAAMC,SAAmB,EAAA;AACzB,MAAA,MAAMlB,kBAA4B,EAAA;AAElCkC,MAAAA,OAAAA,CAAQG,OAAAA,CAAQ,CAAC5E,MAAAA,EAAQ6E,KAAAA,KAAAA;AACvB,QAAA,IAAI7E,MAAAA,CAAOQ,WAAW,WAAA,EAAa;AACjC8C,UAAAA,YAAAA,EAAAA;AACA,UAAA,MAAMtE,YAAWgB,MAAAA,CAAO8E,KAAAA;AACxBvC,UAAAA,eAAAA,CAAgBwC,IAAAA,CAAK/F,SAAAA,CAASgG,mBAAAA,CAAoBzE,EAAE,CAAA;QACtD,CAAA,MAAO;AACLiD,UAAAA,YAAAA,EAAAA;AACAC,UAAAA,MAAAA,CAAOsB,IAAAA,CACL,CAAA,UAAA,EAAaF,KAAAA,GAAQ,CAAA,CAAA,EAAA,EAAM7E,MAAAA,CAAOiF,MAAAA,YAAkBC,KAAAA,GAAQlF,MAAAA,CAAOiF,MAAAA,CAAOjC,OAAAA,GAAU,eAAA,CAAA,CAAiB,CAAA;AAEzG,QAAA;MACF,CAAA,CAAA;AAEA,MAAA,MAAMhE,QAAAA,GAAiC;AACrCsE,QAAAA,YAAAA;AACAE,QAAAA,YAAAA;AACAC,QAAAA,MAAAA;AACAlB,QAAAA;AACF,OAAA;AAEAzE,MAAAA,MAAAA,CAAOC,KAAK,kDAAA,EAAoD;AAC9DuF,QAAAA,YAAAA;AACAE,QAAAA;OACF,CAAA;AAEA,MAAA,OAAOxE,QAAAA;IACT,CAAA,MAAO;AAEL,MAAA,IAAI;AACF,QAAA,MAAMA,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAEhClD,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpC,QAAA,MAAMsC,MAAAA,GAA+B;UACnCsD,YAAAA,EAAc,CAAA;UACdE,YAAAA,EAAc,CAAA;AACdC,UAAAA,MAAAA,EAAQ,EAAA;UACRlB,eAAAA,EAAiB;AAACvD,YAAAA,QAAAA,CAASgG,mBAAAA,CAAoBzE;;AACjD,SAAA;AAEAzC,QAAAA,MAAAA,CAAOC,KAAK,2CAAA,EAA6C;AACvDmB,UAAAA,cAAAA,EAAgBF,SAASgG,mBAAAA,CAAoBzE,EAAAA;AAC7CC,UAAAA,MAAAA,EAAQxB,SAASgG,mBAAAA,CAAoBxE;SACvC,CAAA;AAEA,QAAA,OAAOR,MAAAA;AACT,MAAA,CAAA,CAAA,OAASmF,KAAAA,EAAO;AACdrH,QAAAA,MAAAA,CAAOqH,MAAM,qDAAA,EAAuD;AAAEA,UAAAA;SAAM,CAAA;AAE5E,QAAA,OAAO;UACL7B,YAAAA,EAAc,CAAA;UACdE,YAAAA,EAAc,CAAA;UACdC,MAAAA,EAAQ;YAAC0B,KAAAA,YAAiBD,KAAAA,GAAQC,MAAMnC,OAAAA,GAAU;;AAClDT,UAAAA,eAAAA,EAAiB;AACnB,SAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;;;;AAKA,EAAA,MAAa6C,yBAAyBtC,OAAAA,EAAyE;AAE7G,IAAA,IAAI,CAACA,QAAQzD,YAAAA,IAAgByD,OAAAA,CAAQzD,aAAaC,IAAAA,EAAI,CAAGC,WAAW,CAAA,EAAG;AACrE,MAAA,MAAM,IAAIC,gBAAgB,2BAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAACsD,OAAAA,CAAQ1E,SAAAA,IAAa,OAAO0E,OAAAA,CAAQ1E,cAAc,QAAA,EAAU;AAC/D,MAAA,MAAM,IAAIoB,gBAAgB,iCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAI,CAACsD,OAAAA,CAAQzE,SAAAA,IAAa,CAACyE,QAAQuB,UAAAA,EAAY;AAC7C,MAAA,MAAM,IAAI7E,gBAAgB,oCAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,IAAIsD,OAAAA,CAAQwB,iBAAiB,CAACxB,OAAAA,CAAQG,WAAWH,OAAAA,CAAQG,OAAAA,CAAQ1D,WAAW,CAAA,CAAA,EAAI;AAC9E,MAAA,MAAM,IAAIC,gBAAgB,iDAAA,CAAA;AAC5B,IAAA;AAEA1B,IAAAA,MAAAA,CAAOC,KAAK,+CAAA,EAAiD;AAC3DsB,MAAAA,YAAAA,EAAcyD,OAAAA,CAAQzD,YAAAA;AACtBS,MAAAA,QAAAA,EAAUgD,OAAAA,CAAQhD,QAAAA;AAClByE,MAAAA,cAAAA,EAAgBzB,OAAAA,CAAQuB,UAAAA,GAAavB,OAAAA,CAAQuB,UAAAA,CAAW9E,MAAAA,GAAS,CAAA;AACjE+E,MAAAA,YAAAA,EAAcxB,OAAAA,CAAQwB,YAAAA;AACtBE,MAAAA,cAAAA,EAAgB1B,OAAAA,CAAQG,OAAAA,GAAUH,OAAAA,CAAQG,OAAAA,CAAQ1D,MAAAA,GAAS;KAC7D,CAAA;AAEA,IAAA,MAAMpB,QAAAA,GAAW;;;;;;;;;;;;;;AAejB,IAAA,MAAMC,SAAAA,GAAY;MAChBR,KAAAA,EAAO;AACLkC,QAAAA,QAAAA,EAAUgD,OAAAA,CAAQhD,QAAAA;AAClBD,QAAAA,SAAAA,EAAWiD,OAAAA,CAAQjD,SAAAA;AACnByE,QAAAA,YAAAA,EAAcxB,QAAQwB,YAAAA,IAAgB,KAAA;QACtCrB,OAAAA,EAASH,OAAAA,CAAQG,WAAW,EAAA;AAC5B5D,QAAAA,YAAAA,EAAcyD,OAAAA,CAAQzD,YAAAA;AACtBjB,QAAAA,SAAAA,EAAW0E,OAAAA,CAAQ1E,SAAAA;AACnBC,QAAAA,SAAAA,EAAWyE,OAAAA,CAAQzE,SAAAA;AACnBgG,QAAAA,UAAAA,EAAYvB,OAAAA,CAAQuB,UAAAA;AACpBvF,QAAAA,UAAAA,EAAYgE,QAAQhE,UAAAA,IAAc,KAAA;AAClCC,QAAAA,WAAAA,EAAa+D,QAAQ/D,WAAAA,IAAe,KAAA;QACpCF,SAAAA,EAAWiE,OAAAA,CAAQjE,WAAWD,WAAAA,EAAAA;QAC9BD,YAAAA,EAAcmE,OAAAA,CAAQnE,cAAcC,WAAAA,EAAAA;AACpCmB,QAAAA,QAAAA,EAAU+C,OAAAA,CAAQ/C;AACpB;AACF,KAAA;AAEA,IAAA,IAAI;AACF,MAAA,MAAMf,QAAAA,GAAW,MAAM,IAAA,CAAKvB,MAAAA,CAAO4D,MAOhClD,QAAAA,EAAUC,SAAAA,EAAW,KAAKV,OAAO,CAAA;AAEpC,MAAA,MAAMe,OAAOO,QAAAA,CAASiB,+BAAAA;AAEtB,MAAA,MAAMD,MAAAA,GAA+B;AACnCsD,QAAAA,YAAAA,EAAc7E,IAAAA,CAAK2B,cAAAA;AACnBoD,QAAAA,YAAAA,EAAc/E,IAAAA,CAAK6B,WAAAA;AACnBmD,QAAAA,MAAAA,EAAQ,EAAA;AACRlB,QAAAA,eAAAA,EAAiB9D,KAAK0B,aAAAA,CAAcS,GAAAA,CAAI,CAACC,CAAAA,KAAMA,EAAEN,EAAE;AACrD,OAAA;AAEAzC,MAAAA,MAAAA,CAAOC,KAAK,4CAAA,EAA8C;AACxDsB,QAAAA,YAAAA,EAAcyD,OAAAA,CAAQzD,YAAAA;AACtBe,QAAAA,cAAAA,EAAgB3B,IAAAA,CAAK2B,cAAAA;AACrBE,QAAAA,WAAAA,EAAa7B,IAAAA,CAAK6B,WAAAA;AAClBiC,QAAAA,eAAAA,EAAiBvC,MAAAA,CAAOuC;OAC1B,CAAA;AAEA,MAAA,OAAOvC,MAAAA;AACT,IAAA,CAAA,CAAA,OAASmF,KAAAA,EAAO;AACdrH,MAAAA,MAAAA,CAAOqH,MAAM,sDAAA,EAAwD;AAAEA,QAAAA;OAAM,CAAA;AAE7E,MAAA,OAAO;QACL7B,YAAAA,EAAc,CAAA;QACdE,YAAAA,EAAc,CAAA;QACdC,MAAAA,EAAQ;UAAC0B,KAAAA,YAAiBD,KAAAA,GAAQC,MAAMnC,OAAAA,GAAU;;AAClDT,QAAAA,eAAAA,EAAiB;AACnB,OAAA;AACF,IAAA;AACF,EAAA;AACF","file":"chunk-IUL5TEKE.js","sourcesContent":["/**\n * Tenant-Backend Notifications Module\n * Comprehensive notification system supporting 10+ channels via tenant-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\n// ========================================\n// Enums\n// ========================================\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n PUSH = 'PUSH',\n IN_APP = 'IN_APP',\n WEBHOOK = 'WEBHOOK',\n WHATSAPP = 'WHATSAPP',\n TEAMS = 'TEAMS',\n SLACK = 'SLACK',\n TELEGRAM = 'TELEGRAM',\n DISCORD = 'DISCORD',\n}\n\nexport enum NotificationPriority {\n LOW = 'LOW',\n MEDIUM = 'MEDIUM',\n HIGH = 'HIGH',\n URGENT = 'URGENT',\n}\n\nexport enum NotificationType {\n TRANSACTIONAL = 'TRANSACTIONAL',\n MARKETING = 'MARKETING',\n SYSTEM = 'SYSTEM',\n ALERT = 'ALERT',\n}\n\n// ========================================\n// Types & Interfaces\n// ========================================\n\nexport interface RecipientInput {\n userId?: string;\n email?: string;\n phoneNumber?: string;\n pushToken?: string;\n whatsappNumber?: string;\n teamsUserId?: string;\n slackUserId?: string;\n webhookUrl?: string;\n name?: string;\n locale?: string;\n timezone?: string;\n}\n\nexport interface SendNotificationInput {\n recipient: RecipientInput;\n channel: NotificationChannel;\n type?: NotificationType;\n priority?: NotificationPriority;\n subject?: string;\n body: string;\n htmlBody?: string;\n data?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n}\n\nexport interface SendWithTemplateInput {\n templateSlug: string;\n variables: Record<string, unknown>;\n recipient: RecipientInput;\n priority?: NotificationPriority;\n scheduledFor?: Date;\n expiresAt?: Date;\n trackOpens?: boolean;\n trackClicks?: boolean;\n /** Specific channel instance ID from channel service (takes precedence) */\n channelId?: string;\n /** Platform type for auto-failover (EMAIL, SMS, etc.) - used if channelId not provided */\n platform?: NotificationChannel;\n /** Timezone for scheduling */\n timezone?: string;\n}\n\nexport interface BatchNotificationInput {\n notifications: SendNotificationInput[];\n batchSize?: number;\n delayBetweenBatches?: number;\n priority?: NotificationPriority;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n channel: NotificationChannel;\n type: NotificationType;\n priority: NotificationPriority;\n status: string;\n deliveryStatus?: string;\n title: string;\n message: string;\n htmlMessage?: string;\n subject?: string;\n recipientEmail?: string;\n recipientPhone?: string;\n trackOpens: boolean;\n trackClicks: boolean;\n openedAt?: string;\n clickedAt?: string;\n sentAt?: string;\n deliveredAt?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationTemplate {\n id: string;\n name: string;\n slug: string;\n description?: string;\n channel: NotificationChannel;\n type: NotificationType;\n locale: string;\n subject?: string;\n bodyTemplate: string;\n htmlTemplate?: string;\n variables: Array<{\n name: string;\n type: string;\n required: boolean;\n defaultValue?: unknown;\n description?: string;\n example?: unknown;\n }>;\n enabled: boolean;\n version: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface NotificationStats {\n total: number;\n pending: number;\n queued: number;\n processing: number;\n sent: number;\n delivered: number;\n failed: number;\n byChannel: Record<string, number>;\n byType: Record<string, number>;\n}\n\n// ========================================\n// Tenant Notifications Module\n// ========================================\n\n/**\n * Tenant-Backend Notifications Module\n * Provides access to the centralized notification system\n */\nexport class TenantNotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send a single notification\n */\n public async send(input: SendNotificationInput): Promise<string> {\n // Validate inputs\n this.validateSendInput(input);\n\n logger.info('[TenantNotifications] Sending notification', {\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation SendNotification($input: SendNotificationInput!) {\n sendNotification(input: $input)\n }\n `;\n\n const variables = {\n input: {\n recipient: input.recipient,\n channel: input.channel,\n type: input.type || NotificationType.TRANSACTIONAL,\n priority: input.priority || NotificationPriority.MEDIUM,\n subject: input.subject,\n body: input.body,\n htmlBody: input.htmlBody,\n data: input.data,\n metadata: input.metadata,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendNotification: string;\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Notification sent', {\n notificationId: response.sendNotification,\n });\n\n return response.sendNotification;\n }\n\n /**\n * Send notification using a template\n */\n public async sendWithTemplate(input: SendWithTemplateInput): Promise<string> {\n // Validate inputs\n if (!input.templateSlug || input.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!input.variables || Object.keys(input.variables).length === 0) {\n throw new ValidationError('Template variables are required');\n }\n\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId)) {\n throw new ValidationError('Recipient email or userId is required');\n }\n\n logger.info('[TenantNotifications] Sending notification with template', {\n templateSlug: input.templateSlug,\n priority: input.priority || NotificationPriority.MEDIUM,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n templateSlug: input.templateSlug,\n variables: input.variables,\n recipient: input.recipient,\n priority: input.priority || NotificationPriority.MEDIUM,\n scheduledFor: input.scheduledFor?.toISOString(),\n expiresAt: input.expiresAt?.toISOString(),\n trackOpens: input.trackOpens,\n trackClicks: input.trackClicks,\n // Platform is required for notification delivery routing\n // If channelId is specified, it takes precedence; otherwise platform determines delivery\n channelId: input.channelId,\n platform: input.platform || NotificationChannel.EMAIL,\n timezone: input.timezone,\n },\n };\n\n const response = await this.client.tenantQuery<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const result = response.triggerNotificationWithTemplate;\n const firstNotification = result.notifications[0];\n\n if (result.totalTriggered === 0 || !firstNotification) {\n throw new ValidationError(\n `Notification trigger failed: requested=${result.totalRequested}, triggered=${result.totalTriggered}, failed=${result.totalFailed}`\n );\n }\n\n logger.info('[TenantNotifications] Notification sent with template', {\n notificationId: firstNotification.id,\n status: firstNotification.status,\n totalTriggered: result.totalTriggered,\n totalFailed: result.totalFailed,\n });\n\n return firstNotification.id;\n }\n\n /**\n * Send batch notifications\n */\n public async sendBatch(input: BatchNotificationInput): Promise<{\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n }> {\n if (!input.notifications || input.notifications.length === 0) {\n throw new ValidationError('At least one notification is required');\n }\n\n logger.info('[TenantNotifications] Sending batch notifications', {\n count: input.notifications.length,\n batchSize: input.batchSize,\n });\n\n const mutation = `\n mutation SendBatchNotifications($input: BatchNotificationInput!) {\n sendBatchNotifications(input: $input) {\n totalRequested\n totalQueued\n totalFailed\n batchId\n }\n }\n `;\n\n const variables = {\n input: {\n notifications: input.notifications.map((n) => ({\n recipient: n.recipient,\n channel: n.channel,\n type: n.type || NotificationType.TRANSACTIONAL,\n priority: n.priority || NotificationPriority.MEDIUM,\n subject: n.subject,\n body: n.body,\n htmlBody: n.htmlBody,\n data: n.data,\n metadata: n.metadata,\n scheduledFor: n.scheduledFor?.toISOString(),\n expiresAt: n.expiresAt?.toISOString(),\n trackOpens: n.trackOpens,\n trackClicks: n.trackClicks,\n })),\n batchSize: input.batchSize,\n delayBetweenBatches: input.delayBetweenBatches,\n priority: input.priority,\n },\n };\n\n const response = await this.client.tenantQuery<{\n sendBatchNotifications: {\n totalRequested: number;\n totalQueued: number;\n totalFailed: number;\n batchId: string;\n };\n }>(mutation, variables, this.context);\n\n logger.info('[TenantNotifications] Batch notifications sent', {\n batchId: response.sendBatchNotifications.batchId,\n queued: response.sendBatchNotifications.totalQueued,\n failed: response.sendBatchNotifications.totalFailed,\n });\n\n return response.sendBatchNotifications;\n }\n\n /**\n * Get a notification by ID\n */\n public async getNotification(id: string): Promise<Notification | null> {\n const query = `\n query GetNotification($id: ID!) {\n notification(id: $id) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n htmlMessage\n subject\n recipientEmail\n recipientPhone\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notification: Notification | null;\n }>(query, { id }, this.context);\n\n return response.notification;\n }\n\n /**\n * Get notifications with filters\n */\n public async getNotifications(filter?: {\n userId?: string;\n channel?: NotificationChannel;\n type?: NotificationType;\n status?: string;\n priority?: NotificationPriority;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n }): Promise<Notification[]> {\n const query = `\n query GetNotifications($filter: NotificationFilterInput, $limit: Int, $offset: Int) {\n notifications(filter: $filter, limit: $limit, offset: $offset) {\n id\n userId\n channel\n type\n priority\n status\n deliveryStatus\n title\n message\n subject\n recipientEmail\n trackOpens\n trackClicks\n openedAt\n clickedAt\n sentAt\n deliveredAt\n createdAt\n updatedAt\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n channel: filter.channel,\n type: filter.type,\n status: filter.status,\n priority: filter.priority,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n limit: filter?.limit || 50,\n offset: filter?.offset || 0,\n };\n\n const response = await this.client.tenantQuery<{\n notifications: Notification[];\n }>(query, variables, this.context);\n\n return response.notifications;\n }\n\n /**\n * Get notification template\n */\n public async getTemplate(slug: string, locale?: string): Promise<NotificationTemplate | null> {\n const query = `\n query GetNotificationTemplate($slug: String!, $locale: String) {\n notificationTemplate(slug: $slug, locale: $locale) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplate: NotificationTemplate | null;\n }>(query, { slug, locale }, this.context);\n\n return response.notificationTemplate;\n }\n\n /**\n * Get all notification templates\n */\n public async getTemplates(filter?: {\n channel?: NotificationChannel;\n type?: NotificationType;\n enabled?: boolean;\n }): Promise<NotificationTemplate[]> {\n const query = `\n query GetNotificationTemplates($filter: TemplateFilterInput) {\n notificationTemplates(filter: $filter) {\n id\n name\n slug\n description\n channel\n type\n locale\n subject\n bodyTemplate\n htmlTemplate\n variables\n enabled\n version\n createdAt\n updatedAt\n }\n }\n `;\n\n const response = await this.client.tenantQuery<{\n notificationTemplates: NotificationTemplate[];\n }>(query, { filter }, this.context);\n\n return response.notificationTemplates;\n }\n\n /**\n * Get notification statistics\n */\n public async getStats(filter?: { userId?: string; startDate?: Date; endDate?: Date }): Promise<NotificationStats> {\n const query = `\n query GetNotificationStats($filter: NotificationFilterInput) {\n notificationStats(filter: $filter) {\n total\n pending\n queued\n processing\n sent\n delivered\n failed\n byChannel\n byType\n }\n }\n `;\n\n const variables = {\n filter: filter\n ? {\n userId: filter.userId,\n startDate: filter.startDate?.toISOString(),\n endDate: filter.endDate?.toISOString(),\n }\n : undefined,\n };\n\n const response = await this.client.tenantQuery<{\n notificationStats: NotificationStats;\n }>(query, variables, this.context);\n\n return response.notificationStats;\n }\n\n /**\n * Mark notifications as read\n */\n public async markAsRead(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications marked as read', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<boolean> {\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All notifications marked as read');\n\n return true;\n }\n\n /**\n * Delete notifications\n */\n public async deleteNotifications(notificationIds: string[]): Promise<boolean> {\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds)\n }\n `;\n\n await this.client.tenantQuery(mutation, { notificationIds }, this.context);\n\n logger.info('[TenantNotifications] Notifications deleted', {\n count: notificationIds.length,\n });\n\n return true;\n }\n\n /**\n * Delete all read notifications for the current user\n */\n public async deleteAllReadNotifications(): Promise<boolean> {\n const mutation = `\n mutation DeleteMyReadNotifications {\n deleteMyReadNotifications\n }\n `;\n\n await this.client.tenantQuery(mutation, {}, this.context);\n\n logger.info('[TenantNotifications] All read notifications deleted');\n\n return true;\n }\n\n /**\n * Validate send notification input\n */\n private validateSendInput(input: SendNotificationInput): void {\n if (!input.recipient || (!input.recipient.email && !input.recipient.userId && !input.recipient.phoneNumber)) {\n throw new ValidationError('Recipient email, userId, or phoneNumber is required');\n }\n\n if (!input.channel) {\n throw new ValidationError('Notification channel is required');\n }\n\n if (!input.body || input.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n // Channel-specific validation\n if (input.channel === NotificationChannel.EMAIL && !input.recipient.email) {\n throw new ValidationError('Recipient email is required for EMAIL channel');\n }\n\n if (input.channel === NotificationChannel.SMS && !input.recipient.phoneNumber) {\n throw new ValidationError('Recipient phone number is required for SMS channel');\n }\n\n if (input.channel === NotificationChannel.PUSH && !input.recipient.pushToken && !input.recipient.userId) {\n throw new ValidationError('Recipient push token or userId is required for PUSH channel');\n }\n }\n}\n","/**\n * Notifications Module\n * Send in-app, email, SMS, and push notifications via workspaces-backend\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\nexport enum NotificationType {\n INFO = 'info',\n SUCCESS = 'success',\n WARNING = 'warning',\n ERROR = 'error',\n}\n\nexport enum NotificationChannel {\n EMAIL = 'EMAIL',\n SMS = 'SMS',\n WHATSAPP = 'WHATSAPP',\n PUSH = 'PUSH',\n SLACK = 'SLACK',\n TEAMS = 'TEAMS',\n WEBHOOK = 'WEBHOOK',\n}\n\n// Re-export from tenant-notifications\nexport { NotificationPriority, TenantNotificationsModule } from './tenant-notifications.js';\n\nexport interface SendNotificationOptions {\n /** Notification title */\n title: string;\n /** Notification message */\n message: string;\n /** Notification type */\n type?: NotificationType;\n /** Target user IDs */\n userIds: string[];\n /** Optional redirect URL */\n redirectUrl?: string;\n /** Application name */\n appName?: string;\n /** Send email notification */\n email?: boolean;\n /** Send SMS notification */\n sms?: boolean;\n}\n\nexport interface NotificationResponse {\n /** Number of successful notifications */\n successCount: number;\n /** Number of failed notifications */\n failureCount: number;\n /** Error messages if any */\n errors: string[];\n /** Created notification IDs */\n notificationIds?: string[];\n}\n\nexport interface GetNotificationsOptions {\n /** User ID to get notifications for */\n userId: string;\n /** Filter by status */\n status?: 'unread' | 'read' | 'all';\n /** Filter by type */\n type?: NotificationType;\n /** Filter by app name */\n appName?: string;\n /** Search term */\n search?: string;\n /** Limit number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\nexport interface Notification {\n id: string;\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n status: 'unread' | 'read';\n redirectUrl?: string;\n appName?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RecipientInput {\n email?: string;\n locale?: string;\n name?: string;\n phoneNumber?: string;\n pushToken?: string;\n slackUserId?: string;\n teamsUserId?: string;\n timezone?: string;\n userId?: string;\n webhookUrl?: string;\n whatsappNumber?: string;\n}\n\nexport interface SendChannelNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Recipient information for primary channel */\n recipient: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Notification subject (for EMAIL) */\n subject?: string;\n /** Notification body/message */\n body: string;\n /** HTML body (for EMAIL) */\n htmlBody?: string;\n /** Notification type */\n type?: NotificationType;\n /** Application name */\n appName?: string;\n /** Redirect URL */\n redirectUrl?: string;\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\nexport interface SendTemplateNotificationOptions {\n /** Primary delivery channel (EMAIL, SMS, WHATSAPP, etc.) */\n platform: NotificationChannel;\n /** Template slug to use */\n templateSlug: string;\n /** Template variables */\n variables: Record<string, unknown>;\n /** Recipient information for primary channel */\n recipient?: RecipientInput;\n /** Multiple recipients for bulk delivery */\n recipients?: RecipientInput[];\n /** Also send as in-app notification */\n includeInApp?: boolean;\n /** User IDs for in-app notifications (required when includeInApp is true) */\n userIds?: string[];\n /** Application name */\n appName?: string;\n /** Track email opens */\n trackOpens?: boolean;\n /** Track link clicks */\n trackClicks?: boolean;\n /** Expiration time */\n expiresAt?: Date;\n /** Scheduled delivery time */\n scheduledFor?: Date;\n /** Timezone for scheduling */\n timezone?: string;\n /** Specific channel instance ID (overrides platform) */\n channelId?: string;\n}\n\n/**\n * Notifications Module\n */\nexport class NotificationsModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Send notification to users\n */\n public async send(options: SendNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.title || options.title.trim().length === 0) {\n throw new ValidationError('Notification title is required');\n }\n\n if (!options.message || options.message.trim().length === 0) {\n throw new ValidationError('Notification message is required');\n }\n\n if (!options.userIds || options.userIds.length === 0) {\n throw new ValidationError('At least one user ID is required');\n }\n\n logger.info('[Notifications] Sending notification', {\n title: options.title,\n userCount: options.userIds.length,\n type: options.type || NotificationType.INFO,\n });\n\n const mutation = `\n mutation CreateNotification($input: CreateNotificationInput!) {\n createNotification(input: $input) {\n successCount\n failureCount\n errors\n notifications {\n id\n }\n }\n }\n `;\n\n const variables = {\n input: {\n title: options.title,\n message: options.message,\n type: options.type || NotificationType.INFO,\n userIds: options.userIds,\n redirectUrl: options.redirectUrl || '',\n appName: options.appName,\n email: options.email || false,\n sms: options.sms || false,\n },\n };\n\n const response = await this.client.query<{\n createNotification: NotificationResponse & { notifications: Array<{ id: string }> };\n }>(mutation, variables, this.context);\n\n const result = {\n successCount: response.createNotification.successCount,\n failureCount: response.createNotification.failureCount,\n errors: response.createNotification.errors,\n notificationIds: response.createNotification.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Notification sent', {\n successCount: result.successCount,\n failureCount: result.failureCount,\n });\n\n return result;\n }\n\n /**\n * Send notification to a single user (convenience method)\n */\n public async sendToUser(\n userId: string,\n title: string,\n message: string,\n options?: Omit<SendNotificationOptions, 'userIds' | 'title' | 'message'>\n ): Promise<NotificationResponse> {\n return this.send({\n title,\n message,\n userIds: [userId],\n ...options,\n });\n }\n\n /**\n * Get notifications for a user\n */\n public async getNotifications(options: GetNotificationsOptions): Promise<{\n notifications: Notification[];\n total: number;\n unreadCount: number;\n }> {\n logger.debug('[Notifications] Getting notifications', { userId: options.userId });\n\n const query = `\n query GetNotifications(\n $userId: ID!\n $status: NotificationStatus\n $type: NotificationType\n $appName: String\n $search: String\n $limit: Int\n $offset: Int\n ) {\n getNotifications(\n userId: $userId\n status: $status\n type: $type\n appName: $appName\n search: $search\n limit: $limit\n offset: $offset\n ) {\n notifications {\n id\n userId\n title\n message\n type\n status\n redirectUrl\n appName\n createdAt\n updatedAt\n }\n total\n unreadCount\n }\n }\n `;\n\n const variables = {\n userId: options.userId,\n status: options.status,\n type: options.type,\n appName: options.appName,\n search: options.search,\n limit: options.limit || 20,\n offset: options.offset || 0,\n };\n\n const response = await this.client.query<{\n getNotifications: {\n notifications: Notification[];\n total: number;\n unreadCount: number;\n };\n }>(query, variables, this.context);\n\n return response.getNotifications;\n }\n\n /**\n * Mark notification as read\n */\n public async markAsRead(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Marking notification as read', { notificationId });\n\n const mutation = `\n mutation MarkNotificationAsRead($notificationId: ID!) {\n markNotificationAsRead(notificationId: $notificationId) {\n id\n status\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification marked as read', { notificationId });\n\n return true;\n }\n\n /**\n * Mark multiple notifications as read\n */\n public async markMultipleAsRead(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Marking multiple notifications as read', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation MarkNotificationsAsRead($notificationIds: [ID!]!) {\n markNotificationsAsRead(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markNotificationsAsRead: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications marked as read', {\n count: response.markNotificationsAsRead.count,\n });\n\n return response.markNotificationsAsRead.count;\n }\n\n /**\n * Mark all notifications as read for the current user\n */\n public async markAllAsRead(): Promise<number> {\n logger.debug('[Notifications] Marking all notifications as read');\n\n const mutation = `\n mutation MarkAllMyNotificationsAsRead {\n markAllMyNotificationsAsRead {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n markAllMyNotificationsAsRead: { count: number };\n }>(mutation, {}, this.context);\n\n logger.info('[Notifications] All notifications marked as read', {\n count: response.markAllMyNotificationsAsRead.count,\n });\n\n return response.markAllMyNotificationsAsRead.count;\n }\n\n /**\n * Delete notification\n */\n public async deleteNotification(notificationId: string): Promise<boolean> {\n logger.debug('[Notifications] Deleting notification', { notificationId });\n\n const mutation = `\n mutation DeleteNotification($notificationId: ID!) {\n deleteNotification(notificationId: $notificationId) {\n success\n }\n }\n `;\n\n await this.client.query(mutation, { notificationId }, this.context);\n\n logger.info('[Notifications] Notification deleted', { notificationId });\n\n return true;\n }\n\n /**\n * Delete multiple notifications\n */\n public async deleteMultiple(notificationIds: string[]): Promise<number> {\n logger.debug('[Notifications] Deleting multiple notifications', {\n count: notificationIds.length,\n });\n\n const mutation = `\n mutation DeleteNotifications($notificationIds: [ID!]!) {\n deleteNotifications(notificationIds: $notificationIds) {\n count\n }\n }\n `;\n\n const response = await this.client.query<{\n deleteNotifications: { count: number };\n }>(mutation, { notificationIds }, this.context);\n\n logger.info('[Notifications] Notifications deleted', {\n count: response.deleteNotifications.count,\n });\n\n return response.deleteNotifications.count;\n }\n\n /**\n * Get unread notification count for a user\n */\n public async getUnreadCount(userId: string): Promise<number> {\n const result = await this.getNotifications({\n userId,\n status: 'unread',\n limit: 0,\n });\n\n return result.unreadCount;\n }\n\n /**\n * Send notification via specific channel (EMAIL, SMS, WHATSAPP, etc.)\n * with optional in-app notification\n */\n public async sendChannelNotification(options: SendChannelNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.body || options.body.trim().length === 0) {\n throw new ValidationError('Notification body is required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending channel notification', {\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotification($input: TriggerNotificationInput!) {\n triggerNotification(input: $input) {\n id\n status\n deliveryStatus\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n notification: {\n subject: options.subject || '',\n body: options.body,\n htmlBody: options.htmlBody || '',\n channel: options.platform,\n type: options.type || NotificationType.INFO,\n recipient: options.recipient,\n appName: options.appName,\n redirectUrl: options.redirectUrl || '',\n metadata: options.metadata || {},\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n },\n },\n };\n\n // Handle bulk recipients\n if (options.recipients && options.recipients.length > 1) {\n const results = await Promise.allSettled(\n options.recipients.map((recipient) =>\n this.client.query(\n mutation,\n {\n input: {\n ...variables.input,\n notification: {\n ...variables.input.notification,\n recipient,\n },\n },\n },\n this.context\n )\n )\n );\n\n let successCount = 0;\n let failureCount = 0;\n const errors: string[] = [];\n const notificationIds: string[] = [];\n\n results.forEach((result, index) => {\n if (result.status === 'fulfilled') {\n successCount++;\n const response = result.value as { triggerNotification: { id: string } };\n notificationIds.push(response.triggerNotification.id);\n } else {\n failureCount++;\n errors.push(\n `Recipient ${index + 1}: ${result.reason instanceof Error ? result.reason.message : 'Unknown error'}`\n );\n }\n });\n\n const response: NotificationResponse = {\n successCount,\n failureCount,\n errors,\n notificationIds,\n };\n\n logger.info('[Notifications] Channel notification sent (bulk)', {\n successCount,\n failureCount,\n });\n\n return response;\n } else {\n // Single recipient\n try {\n const response = await this.client.query<{\n triggerNotification: { id: string; status: string; deliveryStatus: string };\n }>(mutation, variables, this.context);\n\n const result: NotificationResponse = {\n successCount: 1,\n failureCount: 0,\n errors: [],\n notificationIds: [response.triggerNotification.id],\n };\n\n logger.info('[Notifications] Channel notification sent', {\n notificationId: response.triggerNotification.id,\n status: response.triggerNotification.status,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send channel notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n }\n\n /**\n * Send notification using a template with optional in-app notification\n */\n public async sendTemplateNotification(options: SendTemplateNotificationOptions): Promise<NotificationResponse> {\n // Validate inputs\n if (!options.templateSlug || options.templateSlug.trim().length === 0) {\n throw new ValidationError('Template slug is required');\n }\n\n if (!options.variables || typeof options.variables !== 'object') {\n throw new ValidationError('Template variables are required');\n }\n\n if (!options.recipient && !options.recipients) {\n throw new ValidationError('At least one recipient is required');\n }\n\n if (options.includeInApp && (!options.userIds || options.userIds.length === 0)) {\n throw new ValidationError('User IDs are required when includeInApp is true');\n }\n\n logger.info('[Notifications] Sending template notification', {\n templateSlug: options.templateSlug,\n platform: options.platform,\n recipientCount: options.recipients ? options.recipients.length : 1,\n includeInApp: options.includeInApp,\n inAppUserCount: options.userIds ? options.userIds.length : 0,\n });\n\n const mutation = `\n mutation TriggerNotificationWithTemplate($input: TriggerNotificationWithTemplateInput!) {\n triggerNotificationWithTemplate(input: $input) {\n totalRequested\n totalTriggered\n totalFailed\n notifications {\n id\n status\n deliveryStatus\n }\n }\n }\n `;\n\n const variables = {\n input: {\n platform: options.platform,\n channelId: options.channelId,\n includeInApp: options.includeInApp || false,\n userIds: options.userIds || [],\n templateSlug: options.templateSlug,\n variables: options.variables,\n recipient: options.recipient,\n recipients: options.recipients,\n trackOpens: options.trackOpens || false,\n trackClicks: options.trackClicks || false,\n expiresAt: options.expiresAt?.toISOString(),\n scheduledFor: options.scheduledFor?.toISOString(),\n timezone: options.timezone,\n },\n };\n\n try {\n const response = await this.client.query<{\n triggerNotificationWithTemplate: {\n totalRequested: number;\n totalTriggered: number;\n totalFailed: number;\n notifications: Array<{ id: string; status: string; deliveryStatus?: string }>;\n };\n }>(mutation, variables, this.context);\n\n const data = response.triggerNotificationWithTemplate;\n\n const result: NotificationResponse = {\n successCount: data.totalTriggered,\n failureCount: data.totalFailed,\n errors: [],\n notificationIds: data.notifications.map((n) => n.id),\n };\n\n logger.info('[Notifications] Template notification sent', {\n templateSlug: options.templateSlug,\n totalTriggered: data.totalTriggered,\n totalFailed: data.totalFailed,\n notificationIds: result.notificationIds,\n });\n\n return result;\n } catch (error) {\n logger.error('[Notifications] Failed to send template notification', { error });\n\n return {\n successCount: 0,\n failureCount: 1,\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n notificationIds: [],\n };\n }\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { security_exports } from './chunk-L2P4CJUR.js';
1
+ import { security_exports } from './chunk-B527JLOB.js';
2
2
  import { LayerManager } from './chunk-UIMPJNWC.js';
3
+ import { signServiceJwt } from './chunk-VFCMR5GX.js';
3
4
  import { ContextManager } from './chunk-DXX6C6X6.js';
4
5
  import { DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_GATEWAY_RETRY_CONFIG } from './chunk-YFOHAHZE.js';
5
6
  import { logger } from './chunk-CBZNP6RF.js';
6
7
  import { __export, __name } from './chunk-XE4OXN2W.js';
7
- import jwt from 'jsonwebtoken';
8
8
 
9
9
  // src/gateway/index.ts
10
10
  var gateway_exports = {};
@@ -15,50 +15,9 @@ __export(gateway_exports, {
15
15
  GatewayErrorType: () => GatewayErrorType,
16
16
  Security: () => security_exports,
17
17
  createGatewayClient: () => createGatewayClient,
18
- createGatewayClientFromEnv: () => createGatewayClientFromEnv
18
+ createGatewayClientFromEnv: () => createGatewayClientFromEnv,
19
+ signServiceJwt: () => signServiceJwt
19
20
  });
20
- var SIGNING_ENV_VAR = "SERVICE_JWT_SECRET";
21
- var KEY_ID = "service-v1";
22
- var DEFAULT_TTL_SECONDS = 60;
23
- var REFRESH_BEFORE_EXP_MS = 1e4;
24
- var cache = /* @__PURE__ */ new Map();
25
- function cacheKey(actorId, ttlSeconds) {
26
- return `${actorId}:${ttlSeconds}`;
27
- }
28
- __name(cacheKey, "cacheKey");
29
- async function signServiceJwt(actorId, ttlSeconds = DEFAULT_TTL_SECONDS) {
30
- const secret = process.env[SIGNING_ENV_VAR];
31
- if (!secret) {
32
- return null;
33
- }
34
- const key = cacheKey(actorId, ttlSeconds);
35
- const cached = cache.get(key);
36
- if (cached && cached.expiresAtMs - REFRESH_BEFORE_EXP_MS > Date.now()) {
37
- return cached.token;
38
- }
39
- const nowSec = Math.floor(Date.now() / 1e3);
40
- const expSec = nowSec + ttlSeconds;
41
- const token = jwt.sign({
42
- actor_type: "service",
43
- iat: nowSec,
44
- exp: expSec
45
- }, secret, {
46
- algorithm: "HS256",
47
- keyid: KEY_ID,
48
- subject: actorId,
49
- // `iss` = the service identity that minted the token. Matches `sub`
50
- // because these are self-minted tokens (caller is asserting itself).
51
- // Gives the gateway room to enforce a minter allowlist later without
52
- // a token-format change.
53
- issuer: actorId
54
- });
55
- cache.set(key, {
56
- token,
57
- expiresAtMs: expSec * 1e3
58
- });
59
- return token;
60
- }
61
- __name(signServiceJwt, "signServiceJwt");
62
21
 
63
22
  // src/gateway/types.ts
64
23
  var CircuitState = /* @__PURE__ */ (function(CircuitState2) {
@@ -555,5 +514,5 @@ function createGatewayClientFromEnv() {
555
514
  __name(createGatewayClientFromEnv, "createGatewayClientFromEnv");
556
515
 
557
516
  export { CircuitState, GatewayClient, GatewayError, GatewayErrorType, createGatewayClient, createGatewayClientFromEnv, gateway_exports };
558
- //# sourceMappingURL=chunk-N7UJFZQH.js.map
559
- //# sourceMappingURL=chunk-N7UJFZQH.js.map
517
+ //# sourceMappingURL=chunk-OWUVYM2S.js.map
518
+ //# sourceMappingURL=chunk-OWUVYM2S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gateway/index.ts","../src/gateway/types.ts","../src/gateway/client.ts"],"names":["CircuitState","GatewayErrorType","GatewayError","Error","type","gatewayUrl","statusCode","graphqlErrors","cause","message","options","name","Object","setPrototypeOf","prototype","uuidv4","crypto","randomUUID","hasAuthorizationHeader","headers","key","keys","toLowerCase","resolveBypassPermissionValue","token","process","env","normalizedToken","trim","CircuitBreaker","state","CLOSED","failures","successes","consecutiveFailures","lastFailureTime","lastSuccessTime","openedAt","failureTimestamps","config","getState","checkStateTransition","recordSuccess","Date","now","HALF_OPEN","logger","info","recordFailure","push","windowStart","failureWindow","filter","t","length","failureThreshold","OPEN","warn","threshold","allowRequest","forceOpen","forceClose","getStats","elapsed","resetTimeout","GatewayClient","layerManager","internalCircuitBreaker","crossLayerCircuitBreaker","retryConfig","defaultHeaders","timeout","enableLogging","LayerManager","layer","serviceName","serviceIdentity","internalGatewayUrl","crossLayerGatewayUrl","cbConfig","DEFAULT_CIRCUIT_BREAKER_CONFIG","circuitBreaker","DEFAULT_GATEWAY_RETRY_CONFIG","retry","getServiceIdentity","debug","internalUrl","getInternalUrl","crossLayerUrl","getCrossLayerUrl","getInternalGatewayUrl","getCrossLayerGatewayUrl","internalQuery","context","createRequestContext","executeWithRetry","bypassPermission","crossLayerQuery","query","getInternalCircuitBreaker","getCrossLayerCircuitBreaker","getHealthStatus","internal","url","circuitState","stats","crossLayer","updateDefaultHeaders","callType","requestId","actorId","workspaceId","startTime","shouldRetryError","error","GRAPHQL_ERROR","CIRCUIT_OPEN","calculateRetryDelay","attempt","Math","min","initialDelay","pow","backoffMultiplier","maxDelay","logRetryAttempt","maxAttempts","delay","settings","skipCircuitBreaker","skipRetry","lastError","result","executeRequest","String","sleep","UNKNOWN_ERROR","buildRequestHeaders","assign","ContextManager","getCfAccessHeaders","value","entries","undefined","toString","handleGraphQLErrors","duration","errors","errorMessages","map","e","join","handleFetchError","TIMEOUT_ERROR","NETWORK_ERROR","serviceActorId","serviceJwt","signServiceJwt","body","JSON","stringify","variables","operationName","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","method","signal","clearTimeout","ok","status","statusText","json","hasData","data","ms","Promise","resolve","createGatewayClient","createGatewayClientFromEnv"],"mappings":"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","file":"chunk-OWUVYM2S.js","sourcesContent":["/**\n * Gateway Module\n *\n * Provides unified gateway client for layer-aware M2M communication\n * with circuit breaker and retry logic.\n *\n * @module gateway\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient, createGatewayClientFromEnv } from '@burdenoff/be-sdk/gateway';\n *\n * // Create from environment variables\n * const client = createGatewayClientFromEnv();\n *\n * // Or create manually\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer, uses int-gateway with bypass)\n * const internalResult = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call (via public gateway)\n * const crossLayerResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\n// Client exports\nexport { GatewayClient, createGatewayClient, createGatewayClientFromEnv } from './client.js';\n\n// Service-JWT minting for cross-layer M2M auth. Exposed so non-GatewayClient\n// callers (e.g. bespoke graphql-request clients) can authenticate identically.\nexport { signServiceJwt } from './service-jwt.js';\n\n// Type exports\nexport {\n CircuitState,\n GatewayErrorType,\n GatewayError,\n type GatewayClientConfig,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type GraphQLError,\n type IGatewayClient,\n type ICircuitBreaker,\n type CircuitBreakerStats,\n type GatewayClientHealth,\n type RequestContext,\n} from './types.js';\n\n// Gateway-side security plugin stack (for public gateways).\n// Imported by consumers as `@burdenoff/be-sdk/gateway/security` — this\n// re-export lets `@burdenoff/be-sdk/gateway` also resolve the namespace.\nexport * as Security from './security/index.js';\n","/**\n * Gateway Client Types\n *\n * Type definitions for the unified gateway client with\n * circuit breaker and retry logic.\n *\n * @module gateway/types\n * @category Gateway\n */\n\nimport type { ServiceLayer, CircuitBreakerConfig, GatewayRetryConfig, GatewayRequestHeaders } from '../types/layer.js';\n\n/**\n * Gateway client configuration\n */\nexport interface GatewayClientConfig {\n /**\n * Layer this client belongs to\n */\n layer: ServiceLayer;\n\n /**\n * Service name (for logging and headers)\n */\n serviceName: string;\n\n /**\n * Service identity for bypass headers\n * @default serviceName\n */\n serviceIdentity?: string;\n\n /**\n * Internal gateway URL (same layer M2M)\n * @default Resolved from layer defaults or environment\n */\n internalGatewayUrl?: string;\n\n /**\n * Cross-layer gateway URL (cross layer via public gateway)\n * @default Resolved from layer defaults or environment\n */\n crossLayerGatewayUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000 (30 seconds)\n */\n timeout?: number;\n\n /**\n * Circuit breaker configuration\n */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n\n /**\n * Retry configuration\n */\n retry?: Partial<GatewayRetryConfig>;\n\n /**\n * Enable request logging\n * @default true\n */\n enableLogging?: boolean;\n\n /**\n * Default headers to include in all requests\n */\n defaultHeaders?: GatewayRequestHeaders;\n}\n\n/**\n * Circuit breaker states\n */\nexport enum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\n/**\n * Circuit breaker instance interface\n */\nexport interface ICircuitBreaker {\n /**\n * Get current circuit state\n */\n getState(): CircuitState;\n\n /**\n * Record a successful call\n */\n recordSuccess(): void;\n\n /**\n * Record a failed call\n */\n recordFailure(): void;\n\n /**\n * Check if circuit allows calls\n */\n allowRequest(): boolean;\n\n /**\n * Force open the circuit\n */\n forceOpen(): void;\n\n /**\n * Force close the circuit\n */\n forceClose(): void;\n\n /**\n * Get circuit statistics\n */\n getStats(): CircuitBreakerStats;\n}\n\n/**\n * Circuit breaker statistics\n */\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failures: number;\n successes: number;\n consecutiveFailures: number;\n lastFailureTime: number | null;\n lastSuccessTime: number | null;\n openedAt: number | null;\n}\n\n/**\n * GraphQL request options\n */\nexport interface GraphQLRequestOptions {\n /**\n * GraphQL query or mutation string\n */\n query: string;\n\n /**\n * GraphQL variables\n */\n variables?: Record<string, unknown>;\n\n /**\n * Operation name (for multi-operation documents)\n */\n operationName?: string;\n\n /**\n * Additional headers for this request\n */\n headers?: GatewayRequestHeaders;\n\n /**\n * Override timeout for this request\n */\n timeout?: number;\n\n /**\n * Skip circuit breaker for this request\n * @default false\n */\n skipCircuitBreaker?: boolean;\n\n /**\n * Skip retry logic for this request\n * @default false\n */\n skipRetry?: boolean;\n}\n\n/**\n * GraphQL response\n */\nexport interface GraphQLResponse<T = unknown> {\n /**\n * Response data\n */\n data?: T;\n\n /**\n * GraphQL errors\n */\n errors?: GraphQLError[];\n}\n\n/**\n * GraphQL error structure\n */\nexport interface GraphQLError {\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Gateway client interface\n */\nexport interface IGatewayClient {\n /**\n * Execute internal (same layer) GraphQL query/mutation\n *\n * Uses internal gateway with bypass headers for M2M communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute cross-layer GraphQL query/mutation\n *\n * Uses public gateway for cross-layer communication.\n *\n * @param options - Request options\n * @returns GraphQL response\n */\n crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n *\n * @param gatewayUrl - Gateway URL to use\n * @param options - Request options\n * @returns GraphQL response\n */\n query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;\n\n /**\n * Get internal gateway circuit breaker\n */\n getInternalCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get cross-layer gateway circuit breaker\n */\n getCrossLayerCircuitBreaker(): ICircuitBreaker;\n\n /**\n * Get client health status\n */\n getHealthStatus(): GatewayClientHealth;\n\n /**\n * Update default headers\n */\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void;\n}\n\n/**\n * Gateway client health status\n */\nexport interface GatewayClientHealth {\n /**\n * Internal gateway status\n */\n internal: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n\n /**\n * Cross-layer gateway status\n */\n crossLayer: {\n url: string;\n circuitState: CircuitState;\n stats: CircuitBreakerStats;\n };\n}\n\n/**\n * Gateway error types\n */\nexport enum GatewayErrorType {\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT_ERROR = 'TIMEOUT_ERROR',\n CIRCUIT_OPEN = 'CIRCUIT_OPEN',\n GRAPHQL_ERROR = 'GRAPHQL_ERROR',\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\n/**\n * Gateway error class\n */\nexport class GatewayError extends Error {\n type: GatewayErrorType;\n gatewayUrl: string;\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n override cause?: Error;\n\n constructor(\n message: string,\n type: GatewayErrorType,\n gatewayUrl: string,\n options?: {\n statusCode?: number;\n graphqlErrors?: GraphQLError[];\n cause?: Error;\n }\n ) {\n super(message);\n this.name = 'GatewayError';\n this.type = type;\n this.gatewayUrl = gatewayUrl;\n this.statusCode = options?.statusCode;\n this.graphqlErrors = options?.graphqlErrors;\n this.cause = options?.cause;\n Object.setPrototypeOf(this, GatewayError.prototype);\n }\n}\n\n/**\n * Request context for logging and tracing\n */\nexport interface RequestContext {\n /**\n * Request ID for tracing\n */\n requestId: string;\n\n /**\n * Actor ID making the request\n */\n actorId?: string;\n\n /**\n * Workspace ID context\n */\n workspaceId?: string;\n\n /**\n * Timestamp when request started\n */\n startTime: number;\n\n /**\n * Call type\n */\n callType: 'internal' | 'cross-layer' | 'direct';\n}\n","/**\n * Unified Gateway Client\n *\n * Provides a layer-aware GraphQL client with circuit breaker,\n * retry logic, and automatic header management for M2M communication.\n *\n * @module gateway/client\n * @category Gateway\n *\n * @example\n * ```typescript\n * import { GatewayClient } from '@burdenoff/be-sdk/gateway';\n *\n * const client = new GatewayClient({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Internal call (same layer)\n * const result = await client.internalQuery({\n * query: `query { getTag(id: \"123\") { id name } }`,\n * });\n *\n * // Cross-layer call\n * const authResult = await client.crossLayerQuery({\n * query: `query { getCurrentUser { id email } }`,\n * });\n * ```\n */\n\nimport { ContextManager } from '../context/index.js';\nimport { LayerManager } from '../layer/index.js';\nimport { logger } from '../logger/index.js';\nimport { signServiceJwt } from './service-jwt.js';\nimport {\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n DEFAULT_GATEWAY_RETRY_CONFIG,\n type CircuitBreakerConfig,\n type GatewayRequestHeaders,\n type GatewayRetryConfig,\n type ServiceLayer,\n} from '../types/layer.js';\nimport {\n CircuitState,\n GatewayError,\n GatewayErrorType,\n type CircuitBreakerStats,\n type GatewayClientConfig,\n type GatewayClientHealth,\n type GraphQLError,\n type GraphQLRequestOptions,\n type GraphQLResponse,\n type ICircuitBreaker,\n type IGatewayClient,\n type RequestContext,\n} from './types.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Case-insensitive presence check for the `Authorization` header. HTTP header\n * names are case-insensitive (RFC 7230), and while the outbound `fetch` will\n * preserve whatever casing the caller supplies, callers may legitimately set\n * `authorization` / `Authorization` / even `AUTHORIZATION` via defaultHeaders\n * or options.headers. We must not overwrite an already-supplied token.\n */\nfunction hasAuthorizationHeader(headers: Record<string, string>): boolean {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'authorization') return true;\n }\n return false;\n}\n\nexport function resolveBypassPermissionValue(\n token: string | undefined = process.env['INTERNAL_SERVICE_TOKEN']\n): string {\n const normalizedToken = token?.trim();\n\n if (!normalizedToken) {\n throw new Error('INTERNAL_SERVICE_TOKEN must be configured for bypass-enabled gateway calls');\n }\n\n return normalizedToken;\n}\n\n/**\n * Circuit Breaker Implementation\n */\nclass CircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures = 0;\n private successes = 0;\n private consecutiveFailures = 0;\n private lastFailureTime: number | null = null;\n private lastSuccessTime: number | null = null;\n private openedAt: number | null = null;\n private failureTimestamps: number[] = [];\n private config: CircuitBreakerConfig;\n\n constructor(config: CircuitBreakerConfig) {\n this.config = config;\n }\n\n getState(): CircuitState {\n this.checkStateTransition();\n return this.state;\n }\n\n recordSuccess(): void {\n this.successes++;\n this.consecutiveFailures = 0;\n this.lastSuccessTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit closed after successful test');\n }\n }\n\n recordFailure(): void {\n this.failures++;\n this.consecutiveFailures++;\n this.lastFailureTime = Date.now();\n this.failureTimestamps.push(Date.now());\n\n // Clean up old timestamps\n const windowStart = Date.now() - this.config.failureWindow;\n this.failureTimestamps = this.failureTimestamps.filter((t) => t > windowStart);\n\n // Check if we should open the circuit\n if (this.state === CircuitState.CLOSED && this.failureTimestamps.length >= this.config.failureThreshold) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit opened due to failures', {\n failures: this.failureTimestamps.length,\n threshold: this.config.failureThreshold,\n });\n }\n\n // If we're half-open and fail, go back to open\n if (this.state === CircuitState.HALF_OPEN) {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.warn('[CircuitBreaker] Circuit re-opened after failed test');\n }\n }\n\n allowRequest(): boolean {\n this.checkStateTransition();\n\n switch (this.state) {\n case CircuitState.CLOSED:\n return true;\n case CircuitState.OPEN:\n return false;\n case CircuitState.HALF_OPEN:\n // Allow one test request\n return true;\n default:\n return true;\n }\n }\n\n forceOpen(): void {\n this.state = CircuitState.OPEN;\n this.openedAt = Date.now();\n logger.info('[CircuitBreaker] Circuit force-opened');\n }\n\n forceClose(): void {\n this.state = CircuitState.CLOSED;\n this.failures = 0;\n this.consecutiveFailures = 0;\n this.failureTimestamps = [];\n this.openedAt = null;\n logger.info('[CircuitBreaker] Circuit force-closed');\n }\n\n getStats(): CircuitBreakerStats {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n consecutiveFailures: this.consecutiveFailures,\n lastFailureTime: this.lastFailureTime,\n lastSuccessTime: this.lastSuccessTime,\n openedAt: this.openedAt,\n };\n }\n\n private checkStateTransition(): void {\n if (this.state === CircuitState.OPEN && this.openedAt) {\n const elapsed = Date.now() - this.openedAt;\n if (elapsed >= this.config.resetTimeout) {\n this.state = CircuitState.HALF_OPEN;\n logger.info('[CircuitBreaker] Circuit transitioning to half-open');\n }\n }\n }\n}\n\n/**\n * Unified Gateway Client\n */\nexport class GatewayClient implements IGatewayClient {\n private config: GatewayClientConfig;\n private layerManager: LayerManager;\n private internalCircuitBreaker: CircuitBreaker;\n private crossLayerCircuitBreaker: CircuitBreaker;\n private retryConfig: GatewayRetryConfig;\n private defaultHeaders: GatewayRequestHeaders;\n\n constructor(config: GatewayClientConfig) {\n this.config = {\n timeout: 30000,\n enableLogging: true,\n ...config,\n };\n\n // Initialize layer manager\n this.layerManager = new LayerManager({\n layer: config.layer,\n serviceName: config.serviceName,\n serviceIdentity: config.serviceIdentity,\n });\n\n // Override URLs if provided\n if (config.internalGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n if (config.crossLayerGatewayUrl) {\n // Use getter internally, but we'll store the override\n }\n\n // Initialize circuit breakers\n const cbConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...config.circuitBreaker,\n };\n this.internalCircuitBreaker = new CircuitBreaker(cbConfig);\n this.crossLayerCircuitBreaker = new CircuitBreaker(cbConfig);\n\n // Initialize retry config\n this.retryConfig = {\n ...DEFAULT_GATEWAY_RETRY_CONFIG,\n ...config.retry,\n };\n\n // Initialize default headers\n this.defaultHeaders = {\n 'x-service-identity': this.layerManager.getServiceIdentity(),\n 'x-actor-type': 'service',\n ...config.defaultHeaders,\n };\n\n logger.debug('[GatewayClient] Initialized', {\n layer: config.layer,\n serviceName: config.serviceName,\n internalUrl: this.getInternalUrl(),\n crossLayerUrl: this.getCrossLayerUrl(),\n });\n }\n\n private getInternalUrl(): string {\n return this.config.internalGatewayUrl || this.layerManager.getInternalGatewayUrl();\n }\n\n private getCrossLayerUrl(): string {\n return this.config.crossLayerGatewayUrl || this.layerManager.getCrossLayerGatewayUrl();\n }\n\n /**\n * Execute internal (same layer) GraphQL query/mutation\n */\n async internalQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('internal', options);\n\n return this.executeWithRetry(this.getInternalUrl(), options, this.internalCircuitBreaker, context, {\n bypassPermission: true,\n });\n }\n\n /**\n * Execute cross-layer GraphQL query/mutation\n */\n async crossLayerQuery<T = unknown>(options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('cross-layer', options);\n\n return this.executeWithRetry(\n this.getCrossLayerUrl(),\n options,\n this.crossLayerCircuitBreaker,\n context,\n { bypassPermission: false } // Cross-layer calls go through public gateway\n );\n }\n\n /**\n * Execute GraphQL query/mutation with explicit gateway URL\n */\n async query<T = unknown>(gatewayUrl: string, options: GraphQLRequestOptions): Promise<GraphQLResponse<T>> {\n const context = this.createRequestContext('direct', options);\n\n // Use internal circuit breaker for direct calls\n return this.executeWithRetry(gatewayUrl, options, this.internalCircuitBreaker, context, {\n bypassPermission: false,\n });\n }\n\n getInternalCircuitBreaker(): ICircuitBreaker {\n return this.internalCircuitBreaker;\n }\n\n getCrossLayerCircuitBreaker(): ICircuitBreaker {\n return this.crossLayerCircuitBreaker;\n }\n\n getHealthStatus(): GatewayClientHealth {\n return {\n internal: {\n url: this.getInternalUrl(),\n circuitState: this.internalCircuitBreaker.getState(),\n stats: this.internalCircuitBreaker.getStats(),\n },\n crossLayer: {\n url: this.getCrossLayerUrl(),\n circuitState: this.crossLayerCircuitBreaker.getState(),\n stats: this.crossLayerCircuitBreaker.getStats(),\n },\n };\n }\n\n updateDefaultHeaders(headers: Partial<GatewayRequestHeaders>): void {\n this.defaultHeaders = { ...this.defaultHeaders, ...headers };\n }\n\n private createRequestContext(\n callType: 'internal' | 'cross-layer' | 'direct',\n options: GraphQLRequestOptions\n ): RequestContext {\n return {\n requestId: uuidv4(),\n actorId: options.headers?.['x-actor-id'] || this.defaultHeaders['x-actor-id'],\n workspaceId: options.headers?.['x-workspace-id'] || this.defaultHeaders['x-workspace-id'],\n startTime: Date.now(),\n callType,\n };\n }\n\n /**\n * Check if an error should be retried\n */\n private shouldRetryError(error: unknown): boolean {\n if (!(error instanceof GatewayError)) {\n return true;\n }\n // Don't retry GraphQL errors or circuit open errors\n return error.type !== GatewayErrorType.GRAPHQL_ERROR && error.type !== GatewayErrorType.CIRCUIT_OPEN;\n }\n\n /**\n * Calculate retry delay with exponential backoff\n */\n private calculateRetryDelay(attempt: number): number {\n return Math.min(\n this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1),\n this.retryConfig.maxDelay\n );\n }\n\n /**\n * Log retry attempt if logging is enabled\n */\n private logRetryAttempt(\n context: RequestContext,\n attempt: number,\n maxAttempts: number,\n delay: number,\n error: Error\n ): void {\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] Request failed, retrying', {\n requestId: context.requestId,\n attempt,\n maxAttempts,\n delay,\n error: error.message,\n });\n }\n }\n\n private async executeWithRetry<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n circuitBreaker: CircuitBreaker,\n context: RequestContext,\n settings: { bypassPermission: boolean }\n ): Promise<GraphQLResponse<T>> {\n // Check circuit breaker\n if (!options.skipCircuitBreaker && !circuitBreaker.allowRequest()) {\n throw new GatewayError(`Circuit breaker is open for ${gatewayUrl}`, GatewayErrorType.CIRCUIT_OPEN, gatewayUrl);\n }\n\n const maxAttempts = options.skipRetry ? 1 : this.retryConfig.maxAttempts;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const result = await this.executeRequest<T>(gatewayUrl, options, context, settings.bypassPermission);\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordSuccess();\n }\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (!options.skipCircuitBreaker) {\n circuitBreaker.recordFailure();\n }\n\n if (!this.shouldRetryError(error)) {\n throw error;\n }\n\n if (attempt < maxAttempts) {\n const delay = this.calculateRetryDelay(attempt);\n this.logRetryAttempt(context, attempt, maxAttempts, delay, lastError);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError || new GatewayError('Request failed after retries', GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n /**\n * Build headers for a request\n */\n private buildRequestHeaders(\n context: RequestContext,\n options: GraphQLRequestOptions,\n bypassPermission: boolean\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-request-id': context.requestId,\n 'x-call-type': context.callType,\n };\n\n // Cross-layer calls transit the peer layer's PUBLIC gateway, which on alpha\n // sits behind Cloudflare Access. Re-present the inbound request's CF service\n // token so the call passes the CF edge. Added before default/request headers\n // so a caller may still override it explicitly. No-op when the inbound\n // request carried no CF creds (local dev, production) — returns {}.\n if (context.callType === 'cross-layer') {\n Object.assign(headers, ContextManager.getCfAccessHeaders());\n }\n\n // Add default headers\n for (const [key, value] of Object.entries(this.defaultHeaders)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n\n // Add request-specific headers\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n if (value !== undefined) {\n headers[key] = String(value);\n }\n }\n }\n\n // Add bypass headers for internal calls\n if (bypassPermission) {\n headers['x-bypass-permission'] = resolveBypassPermissionValue();\n headers['x-bypass-source'] = this.layerManager.getServiceIdentity();\n headers['x-bypass-timestamp'] = Date.now().toString();\n }\n\n return headers;\n }\n\n /**\n * Handle GraphQL errors in response\n */\n private handleGraphQLErrors<T>(\n result: GraphQLResponse<T>,\n context: RequestContext,\n gatewayUrl: string,\n duration: number\n ): void {\n if (!result.errors || result.errors.length === 0) {\n return;\n }\n\n const errorMessages = result.errors.map((e: GraphQLError) => e.message).join(', ');\n\n if (this.config.enableLogging) {\n logger.warn('[GatewayClient] GraphQL errors', {\n requestId: context.requestId,\n errors: result.errors,\n duration,\n });\n }\n\n throw new GatewayError(`GraphQL error: ${errorMessages}`, GatewayErrorType.GRAPHQL_ERROR, gatewayUrl, {\n graphqlErrors: result.errors,\n });\n }\n\n /**\n * Handle fetch errors\n */\n private handleFetchError(\n error: unknown,\n context: RequestContext,\n gatewayUrl: string,\n timeout: number,\n duration: number\n ): never {\n if (error instanceof GatewayError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new GatewayError(`Request timed out after ${timeout}ms`, GatewayErrorType.TIMEOUT_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n if (this.config.enableLogging) {\n logger.error('[GatewayClient] Request failed', {\n requestId: context.requestId,\n error: error.message,\n duration,\n });\n }\n\n throw new GatewayError(error.message, GatewayErrorType.NETWORK_ERROR, gatewayUrl, {\n cause: error,\n });\n }\n\n throw new GatewayError(String(error), GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);\n }\n\n private async executeRequest<T>(\n gatewayUrl: string,\n options: GraphQLRequestOptions,\n context: RequestContext,\n bypassPermission: boolean\n ): Promise<GraphQLResponse<T>> {\n const timeout = options.timeout || this.config.timeout || 30000;\n const headers = this.buildRequestHeaders(context, options, bypassPermission);\n\n // Cross-layer calls transit the peer layer's PUBLIC gateway, which\n // requires JWT auth to propagate actor context. Mint a short-lived\n // service-actor JWT so the gateway admits the call and preserves\n // `x-actor-type: service` downstream. Skipped when the caller has\n // already supplied an Authorization header (e.g., user-originated\n // cross-layer flows) or when SERVICE_JWT_SECRET is unset.\n if (context.callType === 'cross-layer' && !hasAuthorizationHeader(headers)) {\n const serviceActorId = this.layerManager.getServiceIdentity();\n const serviceJwt = await signServiceJwt(serviceActorId);\n if (serviceJwt) {\n headers['Authorization'] = `Bearer ${serviceJwt}`;\n } else if (this.config.enableLogging) {\n // Subtle failure mode: without the JWT the public gateway strips\n // actor headers and the subgraph rejects with `authenticationRequired`.\n // Surface the root cause so operators rolling out a new caller don't\n // spend time debugging the downstream error.\n logger.debug(\n '[GatewayClient] SERVICE_JWT_SECRET not configured — cross-layer call will proceed without service JWT',\n { requestId: context.requestId, gatewayUrl }\n );\n }\n }\n\n const body = JSON.stringify({\n query: options.query,\n variables: options.variables || {},\n operationName: options.operationName,\n });\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Executing request', {\n requestId: context.requestId,\n gatewayUrl,\n operationName: options.operationName,\n callType: context.callType,\n bypassPermission,\n });\n }\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(gatewayUrl, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n const duration = Date.now() - context.startTime;\n\n if (!response.ok) {\n throw new GatewayError(\n `HTTP ${response.status}: ${response.statusText}`,\n GatewayErrorType.NETWORK_ERROR,\n gatewayUrl,\n { statusCode: response.status }\n );\n }\n\n const result = (await response.json()) as GraphQLResponse<T>;\n this.handleGraphQLErrors(result, context, gatewayUrl, duration);\n\n if (this.config.enableLogging) {\n logger.debug('[GatewayClient] Request completed', {\n requestId: context.requestId,\n duration,\n hasData: !!result.data,\n });\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - context.startTime;\n this.handleFetchError(error, context, gatewayUrl, timeout, duration);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n/**\n * Create a gateway client for a specific layer\n */\nexport function createGatewayClient(config: GatewayClientConfig): GatewayClient {\n return new GatewayClient(config);\n}\n\n/**\n * Create a gateway client from environment variables\n *\n * Required environment variables:\n * - SERVICE_LAYER: 'wspace' | 'global'\n * - SERVICE_NAME: Service name\n *\n * Optional:\n * - SERVICE_IDENTITY: Service identity (defaults to SERVICE_NAME)\n * - {LAYER}_INT_GATEWAY_URL: Internal gateway URL\n * - {OPPOSITE_LAYER}_PUBLIC_GATEWAY_URL: Cross-layer gateway URL\n */\nexport function createGatewayClientFromEnv(): GatewayClient {\n const layer = process.env['SERVICE_LAYER'] as ServiceLayer;\n\n if (!layer || (layer !== 'wspace' && layer !== 'global')) {\n throw new Error(`[GatewayClient] Invalid or missing SERVICE_LAYER. Expected 'wspace' or 'global', got '${layer}'`);\n }\n\n const serviceName = process.env['SERVICE_NAME'];\n if (!serviceName) {\n throw new Error('[GatewayClient] SERVICE_NAME environment variable is required');\n }\n\n const serviceIdentity = process.env['SERVICE_IDENTITY'] || serviceName;\n\n return new GatewayClient({\n layer,\n serviceName,\n serviceIdentity,\n });\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { isTokenExpired, parseJWT } from './chunk-B7I4TABG.js';
2
- import { AuthenticationError } from './chunk-SMGTXYFR.js';
2
+ import { AuthenticationError } from './chunk-EZ4PKRUK.js';
3
3
  import { logger } from './chunk-CBZNP6RF.js';
4
4
  import { __name } from './chunk-XE4OXN2W.js';
5
5
 
@@ -272,5 +272,5 @@ var AuthModule = class {
272
272
  };
273
273
 
274
274
  export { AuthCookieHelper, AuthModule };
275
- //# sourceMappingURL=chunk-FKSMQLIV.js.map
276
- //# sourceMappingURL=chunk-FKSMQLIV.js.map
275
+ //# sourceMappingURL=chunk-SS4XWRYR.js.map
276
+ //# sourceMappingURL=chunk-SS4XWRYR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/cookie-helper.ts","../src/auth/index.ts"],"names":["AuthCookieHelper","ACCESS_TOKEN_COOKIE","REFRESH_TOKEN_COOKIE","PROFILE_ID_COOKIE","setAuthCookies","context","tokens","options","isProd","process","env","domain","setCookie","name","value","accessToken","maxAge","httpOnly","secure","sameSite","path","refreshToken","rememberMe","profileId","clearAuthCookies","clearOptions","cookie","undefined","responseHeaders","append","AuthModule","client","verifyToken","token","logger","debug","isTokenExpired","valid","error","query","response","Error","message","decodeToken","payload","parseJWT","mutation","info","AuthenticationError","validatePermission","userId","permission","resourceId","allowed","isTokenValid","getUserIdFromToken","user_id","getWorkspaceIdFromToken","workspace_id","getTokenClaims","willExpireSoon","withinSeconds","exp","now","Math","floor","Date"],"mappings":"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","file":"chunk-FKSMQLIV.js","sourcesContent":["/**\n * Auth Cookie Helper\n *\n * Utilities for setting secure, HttpOnly cookies for authentication.\n * Used by auth services to transition from localStorage to secure cookies.\n */\n\nimport type { GraphQLContext } from '../server/types.js';\n\nexport interface CookieOptions {\n name: string;\n value: string;\n maxAge?: number;\n domain?: string;\n path?: string;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'Strict' | 'Lax' | 'None';\n}\n\nexport class AuthCookieHelper {\n private static readonly ACCESS_TOKEN_COOKIE = 'bf_at';\n private static readonly REFRESH_TOKEN_COOKIE = 'bf_rt';\n private static readonly PROFILE_ID_COOKIE = 'bf_pid';\n\n /**\n * Set authentication cookies in the context response headers\n */\n public static setAuthCookies(\n context: GraphQLContext,\n tokens: { accessToken: string; refreshToken?: string },\n options: { profileId?: string; rememberMe?: boolean } = {}\n ): void {\n const isProd = process.env['NODE_ENV'] === 'production';\n const domain = process.env['COOKIE_DOMAIN'];\n\n // Access token cookie (short-lived, 15m)\n this.setCookie(context, {\n name: this.ACCESS_TOKEN_COOKIE,\n value: tokens.accessToken,\n maxAge: 15 * 60,\n httpOnly: true,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/',\n });\n\n // Refresh token cookie (long-lived, 7d or 30d)\n if (tokens.refreshToken) {\n this.setCookie(context, {\n name: this.REFRESH_TOKEN_COOKIE,\n value: tokens.refreshToken,\n maxAge: options.rememberMe ? 30 * 24 * 60 * 60 : 7 * 24 * 60 * 60,\n httpOnly: true,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/global/graphql', // Only send to global gateway for refresh\n });\n }\n\n // Profile ID cookie (not HttpOnly, needed for UI profile resolution)\n if (options.profileId) {\n this.setCookie(context, {\n name: this.PROFILE_ID_COOKIE,\n value: options.profileId,\n maxAge: 30 * 24 * 60 * 60,\n httpOnly: false,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/',\n });\n }\n }\n\n /**\n * Clear authentication cookies\n */\n public static clearAuthCookies(context: GraphQLContext): void {\n const domain = process.env['COOKIE_DOMAIN'];\n const isProd = process.env['NODE_ENV'] === 'production';\n\n const clearOptions = {\n value: '',\n maxAge: 0,\n domain,\n path: '/',\n secure: isProd,\n sameSite: 'Lax' as const,\n };\n\n this.setCookie(context, { ...clearOptions, name: this.ACCESS_TOKEN_COOKIE, httpOnly: true });\n this.setCookie(context, {\n ...clearOptions,\n name: this.REFRESH_TOKEN_COOKIE,\n httpOnly: true,\n path: '/global/graphql',\n });\n this.setCookie(context, { ...clearOptions, name: this.PROFILE_ID_COOKIE, httpOnly: false });\n }\n\n /**\n * Internal helper to set a cookie header\n */\n private static setCookie(context: GraphQLContext, options: CookieOptions): void {\n let cookie = `${options.name}=${options.value}`;\n\n if (options.maxAge !== undefined) {\n cookie += `; Max-Age=${options.maxAge}`;\n }\n\n if (options.domain) {\n cookie += `; Domain=${options.domain}`;\n }\n\n if (options.path) {\n cookie += `; Path=${options.path}`;\n }\n\n if (options.httpOnly) {\n cookie += '; HttpOnly';\n }\n\n if (options.secure) {\n cookie += '; Secure';\n }\n\n if (options.sameSite) {\n cookie += `; SameSite=${options.sameSite}`;\n }\n\n context.responseHeaders.append('Set-Cookie', cookie);\n }\n}\n","/**\n * Authentication Module\n * JWT verification, token management, and user authentication\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { AuthenticationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\nimport { parseJWT, isTokenExpired } from '../utils/index.js';\n\nexport { AuthCookieHelper } from './cookie-helper.js';\n\nexport interface TokenPayload {\n jti: string;\n sub: string;\n user_id: string;\n workspace_id?: string;\n org_id?: string;\n tenant_endpoint?: string;\n iat: number;\n exp: number;\n scope?: string;\n}\n\nexport interface VerifyTokenResult {\n valid: boolean;\n payload?: TokenPayload;\n error?: string;\n}\n\nexport interface RefreshTokenResult {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport * from './cookie-helper.js';\n\n/**\n * Authentication Module\n */\nexport class AuthModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Verify JWT token\n */\n public async verifyToken(token: string): Promise<VerifyTokenResult> {\n logger.debug('[Auth] Verifying token');\n\n // First check if token is expired locally\n if (isTokenExpired(token)) {\n return {\n valid: false,\n error: 'Token expired',\n };\n }\n\n const query = `\n query VerifyToken($token: String!) {\n verifyToken(token: $token) {\n valid\n payload\n error\n }\n }\n `;\n\n try {\n const response = await this.client.query<{ verifyToken: VerifyTokenResult }>(query, { token }, this.context);\n\n logger.debug('[Auth] Token verification result', { valid: response.verifyToken.valid });\n\n return response.verifyToken;\n } catch (error) {\n logger.error('[Auth] Token verification failed', { error });\n return {\n valid: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Decode token without verification\n */\n public decodeToken(token: string): TokenPayload | null {\n const payload = parseJWT(token);\n if (!payload) {\n return null;\n }\n return payload as unknown as TokenPayload;\n }\n\n /**\n * Refresh access token using refresh token\n */\n public async refreshToken(refreshToken: string): Promise<RefreshTokenResult> {\n logger.debug('[Auth] Refreshing token');\n\n const mutation = `\n mutation RefreshToken($refreshToken: String!) {\n refreshToken(refreshToken: $refreshToken) {\n accessToken\n refreshToken\n expiresIn\n }\n }\n `;\n\n try {\n const response = await this.client.query<{ refreshToken: RefreshTokenResult }>(\n mutation,\n { refreshToken },\n this.context\n );\n\n logger.info('[Auth] Token refreshed successfully');\n\n return response.refreshToken;\n } catch (error) {\n logger.error('[Auth] Token refresh failed', { error });\n throw new AuthenticationError('Failed to refresh token', {\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n /**\n * Validate user has specific permission\n */\n public async validatePermission(userId: string, permission: string, resourceId?: string): Promise<boolean> {\n logger.debug('[Auth] Validating permission', { userId, permission, resourceId });\n\n const query = `\n query ValidatePermission($userId: ID!, $permission: String!, $resourceId: ID) {\n validatePermission(userId: $userId, permission: $permission, resourceId: $resourceId) {\n allowed\n }\n }\n `;\n\n try {\n const response = await this.client.query<{\n validatePermission: { allowed: boolean };\n }>(query, { userId, permission, resourceId }, this.context);\n\n logger.debug('[Auth] Permission validation result', {\n allowed: response.validatePermission.allowed,\n });\n\n return response.validatePermission.allowed;\n } catch (error) {\n logger.error('[Auth] Permission validation failed', { error });\n return false;\n }\n }\n\n /**\n * Check if token is valid and not expired\n */\n public isTokenValid(token: string): boolean {\n return !isTokenExpired(token);\n }\n\n /**\n * Get user ID from token\n */\n public getUserIdFromToken(token: string): string | null {\n const payload = this.decodeToken(token);\n return payload?.user_id || null;\n }\n\n /**\n * Get workspace ID from token\n */\n public getWorkspaceIdFromToken(token: string): string | null {\n const payload = this.decodeToken(token);\n return payload?.workspace_id || null;\n }\n\n /**\n * Extract all claims from token\n */\n public getTokenClaims(token: string): Record<string, unknown> | null {\n const payload = parseJWT(token);\n return payload;\n }\n\n /**\n * Check if token will expire soon (within given seconds)\n */\n public willExpireSoon(token: string, withinSeconds: number = 300): boolean {\n const payload = this.decodeToken(token);\n if (!payload || typeof payload.exp !== 'number') {\n return true;\n }\n\n const now = Math.floor(Date.now() / 1000);\n return payload.exp - now < withinSeconds;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/auth/cookie-helper.ts","../src/auth/index.ts"],"names":["AuthCookieHelper","ACCESS_TOKEN_COOKIE","REFRESH_TOKEN_COOKIE","PROFILE_ID_COOKIE","setAuthCookies","context","tokens","options","isProd","process","env","domain","setCookie","name","value","accessToken","maxAge","httpOnly","secure","sameSite","path","refreshToken","rememberMe","profileId","clearAuthCookies","clearOptions","cookie","undefined","responseHeaders","append","AuthModule","client","verifyToken","token","logger","debug","isTokenExpired","valid","error","query","response","Error","message","decodeToken","payload","parseJWT","mutation","info","AuthenticationError","validatePermission","userId","permission","resourceId","allowed","isTokenValid","getUserIdFromToken","user_id","getWorkspaceIdFromToken","workspace_id","getTokenClaims","willExpireSoon","withinSeconds","exp","now","Math","floor","Date"],"mappings":"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","file":"chunk-SS4XWRYR.js","sourcesContent":["/**\n * Auth Cookie Helper\n *\n * Utilities for setting secure, HttpOnly cookies for authentication.\n * Used by auth services to transition from localStorage to secure cookies.\n */\n\nimport type { GraphQLContext } from '../server/types.js';\n\nexport interface CookieOptions {\n name: string;\n value: string;\n maxAge?: number;\n domain?: string;\n path?: string;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'Strict' | 'Lax' | 'None';\n}\n\nexport class AuthCookieHelper {\n private static readonly ACCESS_TOKEN_COOKIE = 'bf_at';\n private static readonly REFRESH_TOKEN_COOKIE = 'bf_rt';\n private static readonly PROFILE_ID_COOKIE = 'bf_pid';\n\n /**\n * Set authentication cookies in the context response headers\n */\n public static setAuthCookies(\n context: GraphQLContext,\n tokens: { accessToken: string; refreshToken?: string },\n options: { profileId?: string; rememberMe?: boolean } = {}\n ): void {\n const isProd = process.env['NODE_ENV'] === 'production';\n const domain = process.env['COOKIE_DOMAIN'];\n\n // Access token cookie (short-lived, 15m)\n this.setCookie(context, {\n name: this.ACCESS_TOKEN_COOKIE,\n value: tokens.accessToken,\n maxAge: 15 * 60,\n httpOnly: true,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/',\n });\n\n // Refresh token cookie (long-lived, 7d or 30d)\n if (tokens.refreshToken) {\n this.setCookie(context, {\n name: this.REFRESH_TOKEN_COOKIE,\n value: tokens.refreshToken,\n maxAge: options.rememberMe ? 30 * 24 * 60 * 60 : 7 * 24 * 60 * 60,\n httpOnly: true,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/global/graphql', // Only send to global gateway for refresh\n });\n }\n\n // Profile ID cookie (not HttpOnly, needed for UI profile resolution)\n if (options.profileId) {\n this.setCookie(context, {\n name: this.PROFILE_ID_COOKIE,\n value: options.profileId,\n maxAge: 30 * 24 * 60 * 60,\n httpOnly: false,\n secure: isProd,\n sameSite: 'Lax',\n domain,\n path: '/',\n });\n }\n }\n\n /**\n * Clear authentication cookies\n */\n public static clearAuthCookies(context: GraphQLContext): void {\n const domain = process.env['COOKIE_DOMAIN'];\n const isProd = process.env['NODE_ENV'] === 'production';\n\n const clearOptions = {\n value: '',\n maxAge: 0,\n domain,\n path: '/',\n secure: isProd,\n sameSite: 'Lax' as const,\n };\n\n this.setCookie(context, { ...clearOptions, name: this.ACCESS_TOKEN_COOKIE, httpOnly: true });\n this.setCookie(context, {\n ...clearOptions,\n name: this.REFRESH_TOKEN_COOKIE,\n httpOnly: true,\n path: '/global/graphql',\n });\n this.setCookie(context, { ...clearOptions, name: this.PROFILE_ID_COOKIE, httpOnly: false });\n }\n\n /**\n * Internal helper to set a cookie header\n */\n private static setCookie(context: GraphQLContext, options: CookieOptions): void {\n let cookie = `${options.name}=${options.value}`;\n\n if (options.maxAge !== undefined) {\n cookie += `; Max-Age=${options.maxAge}`;\n }\n\n if (options.domain) {\n cookie += `; Domain=${options.domain}`;\n }\n\n if (options.path) {\n cookie += `; Path=${options.path}`;\n }\n\n if (options.httpOnly) {\n cookie += '; HttpOnly';\n }\n\n if (options.secure) {\n cookie += '; Secure';\n }\n\n if (options.sameSite) {\n cookie += `; SameSite=${options.sameSite}`;\n }\n\n context.responseHeaders.append('Set-Cookie', cookie);\n }\n}\n","/**\n * Authentication Module\n * JWT verification, token management, and user authentication\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { AuthenticationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\nimport { parseJWT, isTokenExpired } from '../utils/index.js';\n\nexport { AuthCookieHelper } from './cookie-helper.js';\n\nexport interface TokenPayload {\n jti: string;\n sub: string;\n user_id: string;\n workspace_id?: string;\n org_id?: string;\n tenant_endpoint?: string;\n iat: number;\n exp: number;\n scope?: string;\n}\n\nexport interface VerifyTokenResult {\n valid: boolean;\n payload?: TokenPayload;\n error?: string;\n}\n\nexport interface RefreshTokenResult {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport * from './cookie-helper.js';\n\n/**\n * Authentication Module\n */\nexport class AuthModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Verify JWT token\n */\n public async verifyToken(token: string): Promise<VerifyTokenResult> {\n logger.debug('[Auth] Verifying token');\n\n // First check if token is expired locally\n if (isTokenExpired(token)) {\n return {\n valid: false,\n error: 'Token expired',\n };\n }\n\n const query = `\n query VerifyToken($token: String!) {\n verifyToken(token: $token) {\n valid\n payload\n error\n }\n }\n `;\n\n try {\n const response = await this.client.query<{ verifyToken: VerifyTokenResult }>(query, { token }, this.context);\n\n logger.debug('[Auth] Token verification result', { valid: response.verifyToken.valid });\n\n return response.verifyToken;\n } catch (error) {\n logger.error('[Auth] Token verification failed', { error });\n return {\n valid: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Decode token without verification\n */\n public decodeToken(token: string): TokenPayload | null {\n const payload = parseJWT(token);\n if (!payload) {\n return null;\n }\n return payload as unknown as TokenPayload;\n }\n\n /**\n * Refresh access token using refresh token\n */\n public async refreshToken(refreshToken: string): Promise<RefreshTokenResult> {\n logger.debug('[Auth] Refreshing token');\n\n const mutation = `\n mutation RefreshToken($refreshToken: String!) {\n refreshToken(refreshToken: $refreshToken) {\n accessToken\n refreshToken\n expiresIn\n }\n }\n `;\n\n try {\n const response = await this.client.query<{ refreshToken: RefreshTokenResult }>(\n mutation,\n { refreshToken },\n this.context\n );\n\n logger.info('[Auth] Token refreshed successfully');\n\n return response.refreshToken;\n } catch (error) {\n logger.error('[Auth] Token refresh failed', { error });\n throw new AuthenticationError('Failed to refresh token', {\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n /**\n * Validate user has specific permission\n */\n public async validatePermission(userId: string, permission: string, resourceId?: string): Promise<boolean> {\n logger.debug('[Auth] Validating permission', { userId, permission, resourceId });\n\n const query = `\n query ValidatePermission($userId: ID!, $permission: String!, $resourceId: ID) {\n validatePermission(userId: $userId, permission: $permission, resourceId: $resourceId) {\n allowed\n }\n }\n `;\n\n try {\n const response = await this.client.query<{\n validatePermission: { allowed: boolean };\n }>(query, { userId, permission, resourceId }, this.context);\n\n logger.debug('[Auth] Permission validation result', {\n allowed: response.validatePermission.allowed,\n });\n\n return response.validatePermission.allowed;\n } catch (error) {\n logger.error('[Auth] Permission validation failed', { error });\n return false;\n }\n }\n\n /**\n * Check if token is valid and not expired\n */\n public isTokenValid(token: string): boolean {\n return !isTokenExpired(token);\n }\n\n /**\n * Get user ID from token\n */\n public getUserIdFromToken(token: string): string | null {\n const payload = this.decodeToken(token);\n return payload?.user_id || null;\n }\n\n /**\n * Get workspace ID from token\n */\n public getWorkspaceIdFromToken(token: string): string | null {\n const payload = this.decodeToken(token);\n return payload?.workspace_id || null;\n }\n\n /**\n * Extract all claims from token\n */\n public getTokenClaims(token: string): Record<string, unknown> | null {\n const payload = parseJWT(token);\n return payload;\n }\n\n /**\n * Check if token will expire soon (within given seconds)\n */\n public willExpireSoon(token: string, withinSeconds: number = 300): boolean {\n const payload = this.decodeToken(token);\n if (!payload || typeof payload.exp !== 'number') {\n return true;\n }\n\n const now = Math.floor(Date.now() / 1000);\n return payload.exp - now < withinSeconds;\n }\n}\n"]}