@aarekaz/switchboard-slack 0.3.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/register.ts","../src/adapter.ts","../src/normalizers.ts"],"sourcesContent":["/**\n * Auto-registration for Slack adapter\n * This file registers the Slack adapter with the global registry when imported\n */\n\nimport { registry } from '@aarekaz/switchboard-core';\nimport { SlackAdapter } from './adapter.js';\n\n// Create and register the adapter\nconst slackAdapter = new SlackAdapter();\nregistry.register('slack', slackAdapter);\n\n// Log registration in development\nif (process.env.NODE_ENV !== 'production') {\n console.log('[Switchboard] Slack adapter registered');\n}\n","/**\n * Slack Platform Adapter\n * Implements the Switchboard PlatformAdapter interface for Slack\n */\n\nimport bolt from '@slack/bolt';\nconst { App } = bolt;\ntype AppOptions = ConstructorParameters<typeof App>[0];\nimport { LRUCache } from 'lru-cache';\nimport type {\n PlatformAdapter,\n Result,\n UnifiedMessage,\n MessageRef,\n UnifiedEvent,\n Channel,\n User,\n SendMessageOptions,\n UploadOptions,\n} from '@aarekaz/switchboard-core';\nimport {\n ok,\n err,\n ConnectionError,\n MessageSendError,\n MessageEditError,\n MessageDeleteError,\n ReactionError,\n} from '@aarekaz/switchboard-core';\nimport {\n normalizeMessage,\n normalizeMessageEvent,\n normalizeReactionEvent,\n toSlackEmoji,\n} from './normalizers.js';\nimport type { SlackCredentials, SlackConfig, MessageContext, SlackMessageOptions } from './types.js';\n\n/**\n * Slack adapter implementation\n */\nexport class SlackAdapter implements PlatformAdapter {\n readonly name = 'slack-adapter';\n readonly platform = 'slack' as const;\n\n private app: InstanceType<typeof App> | null = null;\n private eventHandlers: Set<(event: UnifiedEvent) => void> = new Set();\n private config: SlackConfig;\n private messageCache: LRUCache<string, MessageContext>;\n private cacheHits = 0;\n private cacheMisses = 0;\n\n constructor(config: SlackConfig = {}) {\n this.config = {\n cacheSize: config.cacheSize || 1000,\n cacheTTL: config.cacheTTL || 1000 * 60 * 60, // 1 hour default\n ...config,\n };\n\n // Initialize LRU cache for message context\n this.messageCache = new LRUCache<string, MessageContext>({\n max: this.config.cacheSize!,\n ttl: this.config.cacheTTL!,\n });\n }\n\n /**\n * Connect to Slack\n */\n async connect(credentials: unknown): Promise<void> {\n const slackCreds = credentials as SlackCredentials;\n\n if (!slackCreds.botToken) {\n throw new ConnectionError(\n 'slack',\n new Error('Slack bot token is required')\n );\n }\n\n try {\n // Detect mode based on credentials\n const useSocketMode = !!(slackCreds.appToken || this.config.socketMode);\n\n const appOptions: AppOptions = {\n token: slackCreds.botToken,\n };\n\n if (useSocketMode) {\n // Socket Mode (recommended for development)\n if (!slackCreds.appToken) {\n throw new ConnectionError(\n 'slack',\n new Error('App token (appToken) is required for Socket Mode')\n );\n }\n appOptions.socketMode = true;\n appOptions.appToken = slackCreds.appToken;\n } else if (slackCreds.signingSecret) {\n // Events API (recommended for production)\n appOptions.signingSecret = slackCreds.signingSecret;\n if (this.config.port) {\n appOptions.port = this.config.port;\n }\n } else {\n throw new ConnectionError(\n 'slack',\n new Error(\n 'Either appToken (for Socket Mode) or signingSecret (for Events API) is required'\n )\n );\n }\n\n // Create Slack app\n this.app = new App(appOptions);\n\n // Set up event listeners\n this.setupEventListeners();\n\n // Start the app\n await this.app.start();\n\n if (process.env.NODE_ENV !== 'production') {\n console.log(\n `✅ Slack adapter connected (${useSocketMode ? 'Socket Mode' : 'Events API'})`\n );\n }\n } catch (error) {\n throw new ConnectionError('slack', error);\n }\n }\n\n /**\n * Disconnect from Slack\n */\n async disconnect(): Promise<void> {\n if (this.app) {\n await this.app.stop();\n this.app = null;\n }\n this.messageCache.clear();\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.app !== null;\n }\n\n /**\n * Send a message to a channel\n */\n async sendMessage(\n channelId: string,\n text: string,\n options?: SendMessageOptions\n ): Promise<Result<UnifiedMessage>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n const slackOptions = (options as { slack?: SlackMessageOptions })?.slack;\n\n const result = await this.app.client.chat.postMessage({\n channel: channelId,\n text: text,\n thread_ts: options?.threadId || slackOptions?.thread_ts,\n blocks: slackOptions?.blocks as any,\n unfurl_links: slackOptions?.unfurl_links,\n unfurl_media: slackOptions?.unfurl_media,\n metadata: slackOptions?.metadata as any,\n });\n\n if (!result.ok || !result.message) {\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n new Error(result.error || 'Failed to send message')\n )\n );\n }\n\n const unifiedMessage = normalizeMessage(result.message);\n\n // Ensure channelId is set correctly (Slack's response might not include it)\n if (!unifiedMessage.channelId) {\n unifiedMessage.channelId = channelId;\n }\n\n // Cache the message context\n this.cacheMessage(unifiedMessage);\n\n return ok(unifiedMessage);\n } catch (error) {\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Edit a message\n */\n async editMessage(\n messageRef: MessageRef,\n newText: string\n ): Promise<Result<UnifiedMessage>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // Extract message ID and channel ID from MessageRef\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n let channelId: string;\n\n if (typeof messageRef === 'string') {\n // Look up in cache\n const context = this.messageCache.get(messageRef);\n if (!context) {\n this.cacheMisses++;\n this.logCacheStats();\n return err(\n new MessageEditError(\n 'slack',\n messageRef,\n new Error(\n 'Cannot edit message: channel context not found.\\\\n\\\\n' +\n 'This happens when:\\\\n' +\n '1. The message is older than 1 hour (cache expired)\\\\n' +\n '2. The bot restarted since the message was sent\\\\n' +\n '3. The message was sent by another bot instance\\\\n\\\\n' +\n 'Solution: Pass the full message object instead:\\\\n' +\n ' bot.editMessage(message, \"text\") // ✅ Works reliably\\\\n' +\n ' bot.editMessage(message.id, \"text\") // ❌ May fail on Slack'\n )\n )\n );\n }\n this.cacheHits++;\n this.logCacheStats();\n channelId = context.channelId;\n } else {\n // Use message object\n channelId = messageRef.channelId;\n }\n\n // Edit the message\n const result = await this.app.client.chat.update({\n channel: channelId,\n ts: messageId,\n text: newText,\n });\n\n if (!result.ok || !result.message) {\n return err(\n new MessageEditError(\n 'slack',\n messageId,\n new Error(result.error || 'Failed to edit message')\n )\n );\n }\n\n return ok(normalizeMessage(result.message));\n } catch (error) {\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n return err(\n new MessageEditError(\n 'slack',\n messageId,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Delete a message\n */\n async deleteMessage(messageRef: MessageRef): Promise<Result<void>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // Extract message ID and channel ID from MessageRef\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n let channelId: string;\n\n if (typeof messageRef === 'string') {\n // Look up in cache\n const context = this.messageCache.get(messageRef);\n if (!context) {\n this.cacheMisses++;\n this.logCacheStats();\n return err(\n new MessageDeleteError(\n 'slack',\n messageRef,\n new Error(\n 'Cannot delete message: channel context not found.\\\\n\\\\n' +\n 'Solution: Pass the full message object instead:\\\\n' +\n ' bot.deleteMessage(message) // ✅ Works reliably\\\\n' +\n ' bot.deleteMessage(message.id) // ❌ May fail on Slack'\n )\n )\n );\n }\n this.cacheHits++;\n this.logCacheStats();\n channelId = context.channelId;\n } else {\n // Use message object\n channelId = messageRef.channelId;\n }\n\n // Delete the message\n const result = await this.app.client.chat.delete({\n channel: channelId,\n ts: messageId,\n });\n\n if (!result.ok) {\n return err(\n new MessageDeleteError(\n 'slack',\n messageId,\n new Error(result.error || 'Failed to delete message')\n )\n );\n }\n\n // Remove from cache\n this.messageCache.delete(messageId);\n\n return ok(undefined);\n } catch (error) {\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n return err(\n new MessageDeleteError(\n 'slack',\n messageId,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Add a reaction to a message\n */\n async addReaction(messageRef: MessageRef, emoji: string): Promise<Result<void>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // Extract message ID and channel ID from MessageRef\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n let channelId: string;\n\n if (typeof messageRef === 'string') {\n // Look up in cache\n const context = this.messageCache.get(messageRef);\n if (!context) {\n this.cacheMisses++;\n this.logCacheStats();\n return err(\n new ReactionError(\n 'slack',\n messageRef,\n emoji,\n new Error(\n 'Cannot add reaction: channel context not found.\\\\n\\\\n' +\n 'Solution: Pass the full message object instead:\\\\n' +\n ' bot.addReaction(message, emoji) // ✅ Works reliably\\\\n' +\n ' bot.addReaction(message.id, emoji) // ❌ May fail on Slack'\n )\n )\n );\n }\n this.cacheHits++;\n this.logCacheStats();\n channelId = context.channelId;\n } else {\n // Use message object\n channelId = messageRef.channelId;\n }\n\n // Add reaction\n const slackEmoji = toSlackEmoji(emoji);\n const result = await this.app.client.reactions.add({\n channel: channelId,\n timestamp: messageId,\n name: slackEmoji.replace(/^:|:$/g, ''), // Slack API wants emoji without colons\n });\n\n if (!result.ok) {\n return err(\n new ReactionError(\n 'slack',\n messageId,\n emoji,\n new Error(result.error || 'Failed to add reaction')\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n return err(\n new ReactionError(\n 'slack',\n messageId,\n emoji,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Remove a reaction from a message\n */\n async removeReaction(messageRef: MessageRef, emoji: string): Promise<Result<void>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // Extract message ID and channel ID from MessageRef\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n let channelId: string;\n\n if (typeof messageRef === 'string') {\n // Look up in cache\n const context = this.messageCache.get(messageRef);\n if (!context) {\n this.cacheMisses++;\n this.logCacheStats();\n return err(\n new ReactionError(\n 'slack',\n messageRef,\n emoji,\n new Error(\n 'Cannot remove reaction: channel context not found.\\\\n\\\\n' +\n 'Solution: Pass the full message object instead:\\\\n' +\n ' bot.removeReaction(message, emoji) // ✅ Works reliably\\\\n' +\n ' bot.removeReaction(message.id, emoji) // ❌ May fail on Slack'\n )\n )\n );\n }\n this.cacheHits++;\n this.logCacheStats();\n channelId = context.channelId;\n } else {\n // Use message object\n channelId = messageRef.channelId;\n }\n\n // Remove reaction\n const slackEmoji = toSlackEmoji(emoji);\n const result = await this.app.client.reactions.remove({\n channel: channelId,\n timestamp: messageId,\n name: slackEmoji.replace(/^:|:$/g, ''), // Slack API wants emoji without colons\n });\n\n if (!result.ok) {\n return err(\n new ReactionError(\n 'slack',\n messageId,\n emoji,\n new Error(result.error || 'Failed to remove reaction')\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n return err(\n new ReactionError(\n 'slack',\n messageId,\n emoji,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Create a thread (reply to a message)\n */\n async createThread(\n messageRef: MessageRef,\n text: string\n ): Promise<Result<UnifiedMessage>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // Extract message ID and channel ID from MessageRef\n const messageId = typeof messageRef === 'string' ? messageRef : messageRef.id;\n let channelId: string;\n\n if (typeof messageRef === 'string') {\n // Look up in cache\n const context = this.messageCache.get(messageRef);\n if (!context) {\n this.cacheMisses++;\n this.logCacheStats();\n return err(\n new MessageSendError(\n 'slack',\n 'unknown',\n new Error(\n 'Cannot create thread: channel context not found.\\\\n\\\\n' +\n 'Solution: Pass the full message object instead:\\\\n' +\n ' bot.createThread(message, text) // ✅ Works reliably\\\\n' +\n ' bot.createThread(message.id, text) // ❌ May fail on Slack'\n )\n )\n );\n }\n this.cacheHits++;\n this.logCacheStats();\n channelId = context.channelId;\n } else {\n // Use message object\n channelId = messageRef.channelId;\n }\n\n // Reply in thread\n const result = await this.app.client.chat.postMessage({\n channel: channelId,\n text: text,\n thread_ts: messageId, // This creates/replies in a thread\n });\n\n if (!result.ok || !result.message) {\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n new Error(result.error || 'Failed to create thread')\n )\n );\n }\n\n const unifiedMessage = normalizeMessage(result.message);\n\n // Cache the message context\n this.cacheMessage(unifiedMessage);\n\n return ok(unifiedMessage);\n } catch (error) {\n const channelId = typeof messageRef === 'string' ? 'unknown' : messageRef.channelId;\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Upload a file to a channel\n */\n async uploadFile(\n channelId: string,\n file: unknown,\n options?: UploadOptions\n ): Promise<Result<UnifiedMessage>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n // TODO: Implement file upload\n // Slack file upload is more complex and requires different handling\n // For now, return an error indicating it's not yet implemented\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n new Error('File upload not yet implemented for Slack adapter')\n )\n );\n } catch (error) {\n return err(\n new MessageSendError(\n 'slack',\n channelId,\n error instanceof Error ? error : new Error(String(error))\n )\n );\n }\n }\n\n /**\n * Subscribe to platform events\n */\n onEvent(handler: (event: UnifiedEvent) => void | Promise<void>): void {\n this.eventHandlers.add(handler);\n }\n\n /**\n * Get list of channels\n */\n async getChannels(): Promise<Result<Channel[]>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n const result = await this.app.client.conversations.list({\n types: 'public_channel,private_channel',\n });\n\n if (!result.ok || !result.channels) {\n return err(\n new Error(result.error || 'Failed to fetch channels')\n );\n }\n\n const channels: Channel[] = result.channels.map((channel: any) => ({\n id: channel.id,\n name: channel.name || 'unknown',\n type: 'text' as const,\n isPrivate: channel.is_private || false,\n topic: channel.topic?.value,\n }));\n\n return ok(channels);\n } catch (error) {\n return err(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Get list of users\n */\n async getUsers(channelId?: string): Promise<Result<User[]>> {\n if (!this.app) {\n return err(new ConnectionError('slack', new Error('Not connected')));\n }\n\n try {\n if (channelId) {\n // Get users in a specific channel\n const result = await this.app.client.conversations.members({\n channel: channelId,\n });\n\n if (!result.ok || !result.members) {\n return err(\n new Error(result.error || 'Failed to fetch channel members')\n );\n }\n\n // Fetch user info for each member\n const users: User[] = [];\n for (const userId of result.members) {\n const userInfo = await this.app.client.users.info({ user: userId });\n if (userInfo.ok && userInfo.user) {\n users.push({\n id: userInfo.user.id!,\n username: userInfo.user.name || 'unknown',\n displayName: userInfo.user.real_name || userInfo.user.profile?.display_name,\n isBot: userInfo.user.is_bot || false,\n avatarUrl: userInfo.user.profile?.image_512,\n });\n }\n }\n\n return ok(users);\n } else {\n // Get all users\n const result = await this.app.client.users.list();\n\n if (!result.ok || !result.members) {\n return err(\n new Error(result.error || 'Failed to fetch users')\n );\n }\n\n const users: User[] = result.members.map((user: any) => ({\n id: user.id,\n username: user.name || 'unknown',\n displayName: user.real_name || user.profile?.display_name,\n isBot: user.is_bot || false,\n avatarUrl: user.profile?.image_512,\n }));\n\n return ok(users);\n }\n } catch (error) {\n return err(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Normalize platform message to UnifiedMessage\n */\n normalizeMessage(platformMessage: unknown): UnifiedMessage {\n return normalizeMessage(platformMessage);\n }\n\n /**\n * Normalize platform event to UnifiedEvent\n */\n normalizeEvent(platformEvent: unknown): UnifiedEvent | null {\n // Handle different event types\n const event = platformEvent as any;\n\n if (event.type === 'message' || event.message) {\n return normalizeMessageEvent(event);\n }\n\n if (event.type === 'reaction_added') {\n return normalizeReactionEvent(event, 'added');\n }\n\n if (event.type === 'reaction_removed') {\n return normalizeReactionEvent(event, 'removed');\n }\n\n // Unknown event type\n return null;\n }\n\n /**\n * Set up event listeners for Slack\n */\n private setupEventListeners(): void {\n if (!this.app) return;\n\n // Message events\n this.app.message(async ({ message }: { message: any }) => {\n // Filter out bot messages and message changes to avoid loops\n if ('subtype' in message && message.subtype !== undefined) {\n return;\n }\n\n const unifiedMessage = normalizeMessage(message);\n\n // Cache the message context\n this.cacheMessage(unifiedMessage);\n\n const event: UnifiedEvent = {\n type: 'message',\n message: unifiedMessage,\n };\n\n this.eventHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n console.error('[Switchboard] Error in message handler:', error);\n }\n });\n });\n\n // Reaction added events\n this.app.event('reaction_added', async ({ event }: { event: any }) => {\n const reactionEvent = normalizeReactionEvent(event, 'added');\n\n this.eventHandlers.forEach((handler) => {\n try {\n handler(reactionEvent);\n } catch (error) {\n console.error('[Switchboard] Error in reaction handler:', error);\n }\n });\n });\n\n // Reaction removed events\n this.app.event('reaction_removed', async ({ event }: { event: any }) => {\n const reactionEvent = normalizeReactionEvent(event, 'removed');\n\n this.eventHandlers.forEach((handler) => {\n try {\n handler(reactionEvent);\n } catch (error) {\n console.error('[Switchboard] Error in reaction handler:', error);\n }\n });\n });\n }\n\n /**\n * Cache a message's context\n */\n private cacheMessage(message: UnifiedMessage): void {\n this.messageCache.set(message.id, {\n channelId: message.channelId,\n threadId: message.threadId,\n timestamp: message.timestamp,\n });\n }\n\n /**\n * Log cache statistics (every 1000 operations)\n */\n private logCacheStats(): void {\n const total = this.cacheHits + this.cacheMisses;\n if (total > 0 && total % 1000 === 0) {\n const hitRate = ((this.cacheHits / total) * 100).toFixed(1);\n console.log(`[Switchboard] Slack cache hit rate: ${hitRate}% (${this.cacheHits}/${total})`);\n }\n }\n}\n","/**\n * Normalizers for converting Slack types to Switchboard unified types\n */\n\nimport type { UnifiedMessage, UnifiedEvent, Attachment } from '@aarekaz/switchboard-core';\n\n/**\n * Normalize a Slack message to UnifiedMessage\n */\nexport function normalizeMessage(slackMessage: any): UnifiedMessage {\n // Handle file attachments\n const attachments: Attachment[] = [];\n if (slackMessage.files && Array.isArray(slackMessage.files)) {\n for (const file of slackMessage.files) {\n attachments.push({\n id: file.id,\n filename: file.name || 'unknown',\n url: file.url_private || file.permalink || '',\n mimeType: file.mimetype || 'application/octet-stream',\n size: file.size || 0,\n });\n }\n }\n\n return {\n id: slackMessage.ts || slackMessage.message_ts || slackMessage.event_ts,\n channelId: slackMessage.channel || slackMessage.channel_id || '',\n userId: slackMessage.user || slackMessage.bot_id || 'unknown',\n text: extractPlainText(slackMessage),\n timestamp: new Date(parseFloat(slackMessage.ts || slackMessage.event_ts || '0') * 1000),\n threadId: slackMessage.thread_ts,\n attachments: attachments.length > 0 ? attachments : undefined,\n platform: 'slack',\n _raw: slackMessage,\n };\n}\n\n/**\n * Extract plain text from Slack message\n * Handles mrkdwn formatting and blocks\n */\nfunction extractPlainText(message: any): string {\n // If message has blocks, try to extract text from them\n if (message.blocks && Array.isArray(message.blocks)) {\n const texts: string[] = [];\n for (const block of message.blocks) {\n if (block.type === 'section' && block.text) {\n texts.push(block.text.text || '');\n } else if (block.type === 'context' && block.elements) {\n for (const element of block.elements) {\n if (element.text) {\n texts.push(element.text);\n }\n }\n }\n }\n if (texts.length > 0) {\n return texts.join('\\\\n');\n }\n }\n\n // Fall back to text field\n return message.text || '';\n}\n\n/**\n * Normalize Slack emoji to standard format\n * Slack uses :emoji_name: format, we convert to Unicode or keep as-is\n */\nexport function normalizeEmoji(slackEmoji: string): string {\n // If it's already a unicode emoji, return as-is\n if (!/^:.+:$/.test(slackEmoji)) {\n return slackEmoji;\n }\n\n // Remove colons for storage\n // We'll add them back when sending to Slack\n return slackEmoji.replace(/^:|:$/g, '');\n}\n\n/**\n * Common emoji mappings from Unicode to Slack format\n * Slack's reactions API requires named format like :thumbsup:\n */\nconst EMOJI_MAP: Record<string, string> = {\n '👍': 'thumbsup',\n '👎': 'thumbsdown',\n '❤️': 'heart',\n '😂': 'joy',\n '😊': 'blush',\n '😍': 'heart_eyes',\n '🎉': 'tada',\n '🔥': 'fire',\n '✅': 'white_check_mark',\n '❌': 'x',\n '⭐': 'star',\n '💯': '100',\n '🚀': 'rocket',\n '👀': 'eyes',\n '🤔': 'thinking_face',\n '😭': 'sob',\n '😱': 'scream',\n '🙏': 'pray',\n '💪': 'muscle',\n '👏': 'clap',\n '🎯': 'dart',\n '✨': 'sparkles',\n '🤝': 'handshake',\n '💡': 'bulb',\n '🐛': 'bug',\n '⚡': 'zap',\n '🔧': 'wrench',\n '📝': 'memo',\n '🎨': 'art',\n '♻️': 'recycle',\n '🔒': 'lock',\n '🔓': 'unlock',\n '✏️': 'pencil2',\n '🗑️': 'wastebasket',\n};\n\n/**\n * Convert standard emoji to Slack format\n */\nexport function toSlackEmoji(emoji: string): string {\n // If it's already in Slack format, return as-is\n if (/^:.+:$/.test(emoji)) {\n return emoji.slice(1, -1); // Remove the colons, Slack API adds them\n }\n\n // Check if we have a mapping for this Unicode emoji\n if (EMOJI_MAP[emoji]) {\n return EMOJI_MAP[emoji];\n }\n\n // If it looks like a name (alphanumeric + underscores), return as-is\n if (/^[a-z0-9_+-]+$/i.test(emoji)) {\n return emoji;\n }\n\n // Try to strip variant selectors (like ️ at the end of some emojis)\n const stripped = emoji.replace(/[\\uFE00-\\uFE0F]/g, '');\n if (EMOJI_MAP[stripped]) {\n return EMOJI_MAP[stripped];\n }\n\n // Fallback: return as-is (might fail, but let Slack tell us)\n return emoji;\n}\n\n/**\n * Normalize message event from Slack\n */\nexport function normalizeMessageEvent(event: any): UnifiedEvent {\n return {\n type: 'message',\n message: normalizeMessage(event),\n };\n}\n\n/**\n * Normalize reaction event from Slack\n */\nexport function normalizeReactionEvent(event: any, action: 'added' | 'removed'): UnifiedEvent {\n return {\n type: 'reaction',\n messageId: event.item.ts,\n userId: event.user,\n emoji: normalizeEmoji(event.reaction),\n action,\n };\n}\n"],"mappings":";AAKA,SAAS,gBAAgB;;;ACAzB,OAAO,UAAU;AAGjB,SAAS,gBAAgB;AAYzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACnBA,SAAS,iBAAiB,cAAmC;AAElE,QAAM,cAA4B,CAAC;AACnC,MAAI,aAAa,SAAS,MAAM,QAAQ,aAAa,KAAK,GAAG;AAC3D,eAAW,QAAQ,aAAa,OAAO;AACrC,kBAAY,KAAK;AAAA,QACf,IAAI,KAAK;AAAA,QACT,UAAU,KAAK,QAAQ;AAAA,QACvB,KAAK,KAAK,eAAe,KAAK,aAAa;AAAA,QAC3C,UAAU,KAAK,YAAY;AAAA,QAC3B,MAAM,KAAK,QAAQ;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,aAAa,MAAM,aAAa,cAAc,aAAa;AAAA,IAC/D,WAAW,aAAa,WAAW,aAAa,cAAc;AAAA,IAC9D,QAAQ,aAAa,QAAQ,aAAa,UAAU;AAAA,IACpD,MAAM,iBAAiB,YAAY;AAAA,IACnC,WAAW,IAAI,KAAK,WAAW,aAAa,MAAM,aAAa,YAAY,GAAG,IAAI,GAAI;AAAA,IACtF,UAAU,aAAa;AAAA,IACvB,aAAa,YAAY,SAAS,IAAI,cAAc;AAAA,IACpD,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AACF;AAMA,SAAS,iBAAiB,SAAsB;AAE9C,MAAI,QAAQ,UAAU,MAAM,QAAQ,QAAQ,MAAM,GAAG;AACnD,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,QAAQ,QAAQ;AAClC,UAAI,MAAM,SAAS,aAAa,MAAM,MAAM;AAC1C,cAAM,KAAK,MAAM,KAAK,QAAQ,EAAE;AAAA,MAClC,WAAW,MAAM,SAAS,aAAa,MAAM,UAAU;AACrD,mBAAW,WAAW,MAAM,UAAU;AACpC,cAAI,QAAQ,MAAM;AAChB,kBAAM,KAAK,QAAQ,IAAI;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,MAAM,KAAK,KAAK;AAAA,IACzB;AAAA,EACF;AAGA,SAAO,QAAQ,QAAQ;AACzB;AAMO,SAAS,eAAe,YAA4B;AAEzD,MAAI,CAAC,SAAS,KAAK,UAAU,GAAG;AAC9B,WAAO;AAAA,EACT;AAIA,SAAO,WAAW,QAAQ,UAAU,EAAE;AACxC;AAMA,IAAM,YAAoC;AAAA,EACxC,aAAM;AAAA,EACN,aAAM;AAAA,EACN,gBAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,UAAK;AAAA,EACL,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,UAAK;AAAA,EACL,aAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,gBAAM;AAAA,EACN,aAAM;AAAA,EACN,aAAM;AAAA,EACN,gBAAM;AAAA,EACN,mBAAO;AACT;AAKO,SAAS,aAAa,OAAuB;AAElD,MAAI,SAAS,KAAK,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1B;AAGA,MAAI,UAAU,KAAK,GAAG;AACpB,WAAO,UAAU,KAAK;AAAA,EACxB;AAGA,MAAI,kBAAkB,KAAK,KAAK,GAAG;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,MAAM,QAAQ,oBAAoB,EAAE;AACrD,MAAI,UAAU,QAAQ,GAAG;AACvB,WAAO,UAAU,QAAQ;AAAA,EAC3B;AAGA,SAAO;AACT;AAKO,SAAS,sBAAsB,OAA0B;AAC9D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,iBAAiB,KAAK;AAAA,EACjC;AACF;AAKO,SAAS,uBAAuB,OAAY,QAA2C;AAC5F,SAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW,MAAM,KAAK;AAAA,IACtB,QAAQ,MAAM;AAAA,IACd,OAAO,eAAe,MAAM,QAAQ;AAAA,IACpC;AAAA,EACF;AACF;;;ADrKA,IAAM,EAAE,IAAI,IAAI;AAkCT,IAAM,eAAN,MAA8C;AAAA,EAC1C,OAAO;AAAA,EACP,WAAW;AAAA,EAEZ,MAAuC;AAAA,EACvC,gBAAoD,oBAAI,IAAI;AAAA,EAC5D;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EAEtB,YAAY,SAAsB,CAAC,GAAG;AACpC,SAAK,SAAS;AAAA,MACZ,WAAW,OAAO,aAAa;AAAA,MAC/B,UAAU,OAAO,YAAY,MAAO,KAAK;AAAA;AAAA,MACzC,GAAG;AAAA,IACL;AAGA,SAAK,eAAe,IAAI,SAAiC;AAAA,MACvD,KAAK,KAAK,OAAO;AAAA,MACjB,KAAK,KAAK,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,aAAqC;AACjD,UAAM,aAAa;AAEnB,QAAI,CAAC,WAAW,UAAU;AACxB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,IAAI,MAAM,6BAA6B;AAAA,MACzC;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,gBAAgB,CAAC,EAAE,WAAW,YAAY,KAAK,OAAO;AAE5D,YAAM,aAAyB;AAAA,QAC7B,OAAO,WAAW;AAAA,MACpB;AAEA,UAAI,eAAe;AAEjB,YAAI,CAAC,WAAW,UAAU;AACxB,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,IAAI,MAAM,kDAAkD;AAAA,UAC9D;AAAA,QACF;AACA,mBAAW,aAAa;AACxB,mBAAW,WAAW,WAAW;AAAA,MACnC,WAAW,WAAW,eAAe;AAEnC,mBAAW,gBAAgB,WAAW;AACtC,YAAI,KAAK,OAAO,MAAM;AACpB,qBAAW,OAAO,KAAK,OAAO;AAAA,QAChC;AAAA,MACF,OAAO;AACL,cAAM,IAAI;AAAA,UACR;AAAA,UACA,IAAI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,WAAK,MAAM,IAAI,IAAI,UAAU;AAG7B,WAAK,oBAAoB;AAGzB,YAAM,KAAK,IAAI,MAAM;AAErB,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,gBAAQ;AAAA,UACN,mCAA8B,gBAAgB,gBAAgB,YAAY;AAAA,QAC5E;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI,gBAAgB,SAAS,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,KAAK,KAAK;AACZ,YAAM,KAAK,IAAI,KAAK;AACpB,WAAK,MAAM;AAAA,IACb;AACA,SAAK,aAAa,MAAM;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,WACA,MACA,SACiC;AACjC,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AACF,YAAM,eAAgB,SAA6C;AAEnE,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,KAAK,YAAY;AAAA,QACpD,SAAS;AAAA,QACT;AAAA,QACA,WAAW,SAAS,YAAY,cAAc;AAAA,QAC9C,QAAQ,cAAc;AAAA,QACtB,cAAc,cAAc;AAAA,QAC5B,cAAc,cAAc;AAAA,QAC5B,UAAU,cAAc;AAAA,MAC1B,CAAC;AAED,UAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS;AACjC,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,wBAAwB;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,iBAAiB,iBAAiB,OAAO,OAAO;AAGtD,UAAI,CAAC,eAAe,WAAW;AAC7B,uBAAe,YAAY;AAAA,MAC7B;AAGA,WAAK,aAAa,cAAc;AAEhC,aAAO,GAAG,cAAc;AAAA,IAC1B,SAAS,OAAO;AACd,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,YACA,SACiC;AACjC,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAEF,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,UAAI;AAEJ,UAAI,OAAO,eAAe,UAAU;AAElC,cAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,YAAI,CAAC,SAAS;AACZ,eAAK;AACL,eAAK,cAAc;AACnB,iBAAO;AAAA,YACL,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,IAAI;AAAA,gBACF;AAAA,cAQF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,aAAK;AACL,aAAK,cAAc;AACnB,oBAAY,QAAQ;AAAA,MACtB,OAAO;AAEL,oBAAY,WAAW;AAAA,MACzB;AAGA,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,KAAK,OAAO;AAAA,QAC/C,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,MAAM;AAAA,MACR,CAAC;AAED,UAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS;AACjC,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,wBAAwB;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,aAAO,GAAG,iBAAiB,OAAO,OAAO,CAAC;AAAA,IAC5C,SAAS,OAAO;AACd,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,YAA+C;AACjE,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAEF,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,UAAI;AAEJ,UAAI,OAAO,eAAe,UAAU;AAElC,cAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,YAAI,CAAC,SAAS;AACZ,eAAK;AACL,eAAK,cAAc;AACnB,iBAAO;AAAA,YACL,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,IAAI;AAAA,gBACF;AAAA,cAIF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,aAAK;AACL,aAAK,cAAc;AACnB,oBAAY,QAAQ;AAAA,MACtB,OAAO;AAEL,oBAAY,WAAW;AAAA,MACzB;AAGA,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,KAAK,OAAO;AAAA,QAC/C,SAAS;AAAA,QACT,IAAI;AAAA,MACN,CAAC;AAED,UAAI,CAAC,OAAO,IAAI;AACd,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,0BAA0B;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAGA,WAAK,aAAa,OAAO,SAAS;AAElC,aAAO,GAAG,MAAS;AAAA,IACrB,SAAS,OAAO;AACd,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,YAAwB,OAAsC;AAC9E,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAEF,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,UAAI;AAEJ,UAAI,OAAO,eAAe,UAAU;AAElC,cAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,YAAI,CAAC,SAAS;AACZ,eAAK;AACL,eAAK,cAAc;AACnB,iBAAO;AAAA,YACL,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,cACA,IAAI;AAAA,gBACF;AAAA,cAIF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,aAAK;AACL,aAAK,cAAc;AACnB,oBAAY,QAAQ;AAAA,MACtB,OAAO;AAEL,oBAAY,WAAW;AAAA,MACzB;AAGA,YAAM,aAAa,aAAa,KAAK;AACrC,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,UAAU,IAAI;AAAA,QACjD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAM,WAAW,QAAQ,UAAU,EAAE;AAAA;AAAA,MACvC,CAAC;AAED,UAAI,CAAC,OAAO,IAAI;AACd,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,wBAAwB;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,aAAO,GAAG,MAAS;AAAA,IACrB,SAAS,OAAO;AACd,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,YAAwB,OAAsC;AACjF,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAEF,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,UAAI;AAEJ,UAAI,OAAO,eAAe,UAAU;AAElC,cAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,YAAI,CAAC,SAAS;AACZ,eAAK;AACL,eAAK,cAAc;AACnB,iBAAO;AAAA,YACL,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,cACA,IAAI;AAAA,gBACF;AAAA,cAIF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,aAAK;AACL,aAAK,cAAc;AACnB,oBAAY,QAAQ;AAAA,MACtB,OAAO;AAEL,oBAAY,WAAW;AAAA,MACzB;AAGA,YAAM,aAAa,aAAa,KAAK;AACrC,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,UAAU,OAAO;AAAA,QACpD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAM,WAAW,QAAQ,UAAU,EAAE;AAAA;AAAA,MACvC,CAAC;AAED,UAAI,CAAC,OAAO,IAAI;AACd,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,2BAA2B;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAEA,aAAO,GAAG,MAAS;AAAA,IACrB,SAAS,OAAO;AACd,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,YACA,MACiC;AACjC,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAEF,YAAM,YAAY,OAAO,eAAe,WAAW,aAAa,WAAW;AAC3E,UAAI;AAEJ,UAAI,OAAO,eAAe,UAAU;AAElC,cAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,YAAI,CAAC,SAAS;AACZ,eAAK;AACL,eAAK,cAAc;AACnB,iBAAO;AAAA,YACL,IAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,IAAI;AAAA,gBACF;AAAA,cAIF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,aAAK;AACL,aAAK,cAAc;AACnB,oBAAY,QAAQ;AAAA,MACtB,OAAO;AAEL,oBAAY,WAAW;AAAA,MACzB;AAGA,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,KAAK,YAAY;AAAA,QACpD,SAAS;AAAA,QACT;AAAA,QACA,WAAW;AAAA;AAAA,MACb,CAAC;AAED,UAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS;AACjC,eAAO;AAAA,UACL,IAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,IAAI,MAAM,OAAO,SAAS,yBAAyB;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,iBAAiB,iBAAiB,OAAO,OAAO;AAGtD,WAAK,aAAa,cAAc;AAEhC,aAAO,GAAG,cAAc;AAAA,IAC1B,SAAS,OAAO;AACd,YAAM,YAAY,OAAO,eAAe,WAAW,YAAY,WAAW;AAC1E,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,WACA,MACA,SACiC;AACjC,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AAIF,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,IAAI,MAAM,mDAAmD;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,IAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,SAA8D;AACpE,SAAK,cAAc,IAAI,OAAO;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA0C;AAC9C,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO,cAAc,KAAK;AAAA,QACtD,OAAO;AAAA,MACT,CAAC;AAED,UAAI,CAAC,OAAO,MAAM,CAAC,OAAO,UAAU;AAClC,eAAO;AAAA,UACL,IAAI,MAAM,OAAO,SAAS,0BAA0B;AAAA,QACtD;AAAA,MACF;AAEA,YAAM,WAAsB,OAAO,SAAS,IAAI,CAAC,aAAkB;AAAA,QACjE,IAAI,QAAQ;AAAA,QACZ,MAAM,QAAQ,QAAQ;AAAA,QACtB,MAAM;AAAA,QACN,WAAW,QAAQ,cAAc;AAAA,QACjC,OAAO,QAAQ,OAAO;AAAA,MACxB,EAAE;AAEF,aAAO,GAAG,QAAQ;AAAA,IACpB,SAAS,OAAO;AACd,aAAO,IAAI,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,WAA6C;AAC1D,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,IAAI,IAAI,gBAAgB,SAAS,IAAI,MAAM,eAAe,CAAC,CAAC;AAAA,IACrE;AAEA,QAAI;AACF,UAAI,WAAW;AAEb,cAAM,SAAS,MAAM,KAAK,IAAI,OAAO,cAAc,QAAQ;AAAA,UACzD,SAAS;AAAA,QACX,CAAC;AAED,YAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS;AACjC,iBAAO;AAAA,YACL,IAAI,MAAM,OAAO,SAAS,iCAAiC;AAAA,UAC7D;AAAA,QACF;AAGA,cAAM,QAAgB,CAAC;AACvB,mBAAW,UAAU,OAAO,SAAS;AACnC,gBAAM,WAAW,MAAM,KAAK,IAAI,OAAO,MAAM,KAAK,EAAE,MAAM,OAAO,CAAC;AAClE,cAAI,SAAS,MAAM,SAAS,MAAM;AAChC,kBAAM,KAAK;AAAA,cACT,IAAI,SAAS,KAAK;AAAA,cAClB,UAAU,SAAS,KAAK,QAAQ;AAAA,cAChC,aAAa,SAAS,KAAK,aAAa,SAAS,KAAK,SAAS;AAAA,cAC/D,OAAO,SAAS,KAAK,UAAU;AAAA,cAC/B,WAAW,SAAS,KAAK,SAAS;AAAA,YACpC,CAAC;AAAA,UACH;AAAA,QACF;AAEA,eAAO,GAAG,KAAK;AAAA,MACjB,OAAO;AAEL,cAAM,SAAS,MAAM,KAAK,IAAI,OAAO,MAAM,KAAK;AAEhD,YAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS;AACjC,iBAAO;AAAA,YACL,IAAI,MAAM,OAAO,SAAS,uBAAuB;AAAA,UACnD;AAAA,QACF;AAEA,cAAM,QAAgB,OAAO,QAAQ,IAAI,CAAC,UAAe;AAAA,UACvD,IAAI,KAAK;AAAA,UACT,UAAU,KAAK,QAAQ;AAAA,UACvB,aAAa,KAAK,aAAa,KAAK,SAAS;AAAA,UAC7C,OAAO,KAAK,UAAU;AAAA,UACtB,WAAW,KAAK,SAAS;AAAA,QAC3B,EAAE;AAEF,eAAO,GAAG,KAAK;AAAA,MACjB;AAAA,IACF,SAAS,OAAO;AACd,aAAO,IAAI,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,iBAA0C;AACzD,WAAO,iBAAiB,eAAe;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,eAA6C;AAE1D,UAAM,QAAQ;AAEd,QAAI,MAAM,SAAS,aAAa,MAAM,SAAS;AAC7C,aAAO,sBAAsB,KAAK;AAAA,IACpC;AAEA,QAAI,MAAM,SAAS,kBAAkB;AACnC,aAAO,uBAAuB,OAAO,OAAO;AAAA,IAC9C;AAEA,QAAI,MAAM,SAAS,oBAAoB;AACrC,aAAO,uBAAuB,OAAO,SAAS;AAAA,IAChD;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAA4B;AAClC,QAAI,CAAC,KAAK,IAAK;AAGf,SAAK,IAAI,QAAQ,OAAO,EAAE,QAAQ,MAAwB;AAExD,UAAI,aAAa,WAAW,QAAQ,YAAY,QAAW;AACzD;AAAA,MACF;AAEA,YAAM,iBAAiB,iBAAiB,OAAO;AAG/C,WAAK,aAAa,cAAc;AAEhC,YAAM,QAAsB;AAAA,QAC1B,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAEA,WAAK,cAAc,QAAQ,CAAC,YAAY;AACtC,YAAI;AACF,kBAAQ,KAAK;AAAA,QACf,SAAS,OAAO;AACd,kBAAQ,MAAM,2CAA2C,KAAK;AAAA,QAChE;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,SAAK,IAAI,MAAM,kBAAkB,OAAO,EAAE,MAAM,MAAsB;AACpE,YAAM,gBAAgB,uBAAuB,OAAO,OAAO;AAE3D,WAAK,cAAc,QAAQ,CAAC,YAAY;AACtC,YAAI;AACF,kBAAQ,aAAa;AAAA,QACvB,SAAS,OAAO;AACd,kBAAQ,MAAM,4CAA4C,KAAK;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,SAAK,IAAI,MAAM,oBAAoB,OAAO,EAAE,MAAM,MAAsB;AACtE,YAAM,gBAAgB,uBAAuB,OAAO,SAAS;AAE7D,WAAK,cAAc,QAAQ,CAAC,YAAY;AACtC,YAAI;AACF,kBAAQ,aAAa;AAAA,QACvB,SAAS,OAAO;AACd,kBAAQ,MAAM,4CAA4C,KAAK;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,SAA+B;AAClD,SAAK,aAAa,IAAI,QAAQ,IAAI;AAAA,MAChC,WAAW,QAAQ;AAAA,MACnB,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,IACrB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAsB;AAC5B,UAAM,QAAQ,KAAK,YAAY,KAAK;AACpC,QAAI,QAAQ,KAAK,QAAQ,QAAS,GAAG;AACnC,YAAM,WAAY,KAAK,YAAY,QAAS,KAAK,QAAQ,CAAC;AAC1D,cAAQ,IAAI,uCAAuC,OAAO,MAAM,KAAK,SAAS,IAAI,KAAK,GAAG;AAAA,IAC5F;AAAA,EACF;AACF;;;ADjzBA,IAAM,eAAe,IAAI,aAAa;AACtC,SAAS,SAAS,SAAS,YAAY;AAGvC,IAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAQ,IAAI,wCAAwC;AACtD;","names":[]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@aarekaz/switchboard-slack",
3
+ "version": "0.3.1",
4
+ "description": "Slack adapter for Switchboard SDK",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "dependencies": {
19
+ "@slack/bolt": "^3.17.0",
20
+ "lru-cache": "^10.2.0",
21
+ "@aarekaz/switchboard-core": "0.3.1"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.11.17",
25
+ "tsup": "^8.0.1",
26
+ "typescript": "^5.3.3"
27
+ },
28
+ "keywords": [
29
+ "switchboard",
30
+ "slack",
31
+ "bot",
32
+ "chat",
33
+ "adapter"
34
+ ],
35
+ "author": "",
36
+ "license": "MIT",
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "dev": "tsup --watch",
40
+ "typecheck": "tsc --noEmit",
41
+ "clean": "rm -rf dist"
42
+ }
43
+ }