@chirp-dev/chirp-sdk 1.2.0 → 1.3.0
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.
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -210,6 +210,12 @@ var RESTClient = class {
|
|
|
210
210
|
if (options.page) params.append("page", String(options.page));
|
|
211
211
|
if (options.limit) params.append("limit", String(options.limit));
|
|
212
212
|
const query = params.toString();
|
|
213
|
+
if (channelId.startsWith("dm-")) {
|
|
214
|
+
const receiverId = channelId.substring(3);
|
|
215
|
+
return this.get(
|
|
216
|
+
`/api/dms/${receiverId}/messages${query ? `?${query}` : ""}`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
213
219
|
return this.get(
|
|
214
220
|
`/api/channels/${channelId}/messages${query ? `?${query}` : ""}`
|
|
215
221
|
);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/types.ts","../src/client/ChirpClient.ts","../src/api/REST.ts","../src/client/events/EventEmitter.ts","../src/commands/CommandContext.ts","../src/commands/CommandManager.ts","../src/client/managers/ChannelManager.ts","../src/client/managers/MessageManager.ts","../src/client/managers/ServerManager.ts","../src/util/helpers.ts","../src/util/logger.ts","../src/commands/CommandBuilder.ts","../src/errors/index.ts"],"sourcesContent":["/**\r\n * Core API types for the Chirp Bot SDK\r\n * Based on the Chirp REST API and WebSocket events\r\n */\r\n\r\n// ============================================================================\r\n// User Types\r\n// ============================================================================\r\n\r\nexport interface User {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n isBot: true;\r\n botTokenId: string;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialUser {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status?: string;\r\n isBot?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// Server Types\r\n// ============================================================================\r\n\r\nexport interface Server {\r\n id: string;\r\n name: string;\r\n iconUrl: string | null;\r\n ownerId: string;\r\n createdAt: string;\r\n memberCount?: number;\r\n}\r\n\r\nexport interface ServerMember {\r\n serverId: string;\r\n userId: string;\r\n roles: string[];\r\n joinedAt: string;\r\n user: PartialUser;\r\n}\r\n\r\n// ============================================================================\r\n// Channel Types\r\n// ============================================================================\r\n\r\nexport interface Channel {\r\n id: string;\r\n serverId: string;\r\n name: string;\r\n type: 'text' | 'voice' | 'media' | 'forum';\r\n parentId: string | null;\r\n position: number;\r\n permissions?: Record<string, boolean>;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialChannel {\r\n id: string;\r\n name: string;\r\n type: string;\r\n serverId?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Message Types\r\n// ============================================================================\r\n\r\nexport interface Message {\r\n id: string;\r\n // Server uses snake_case for channel_id\r\n channel_id: string;\r\n // Server sends author as string (username) for backward compatibility\r\n // Also sends username as the same value\r\n author: string;\r\n username: string;\r\n avatar_url: string | null;\r\n // User info for bots\r\n bot_id?: string;\r\n user_id?: string;\r\n content: string;\r\n // Server uses snake_case for these fields\r\n created_at: string;\r\n updated_at?: string;\r\n edited?: boolean;\r\n edited_at?: string;\r\n // Reply info (server uses snake_case)\r\n replying_to_id?: string;\r\n replying_to_author?: string;\r\n replying_to_content?: string;\r\n replyingTo?: MessageReply;\r\n reactions?: Reaction[];\r\n attachments?: Attachment[];\r\n // Server compatibility fields\r\n is_bot?: boolean;\r\n authorAvatar?: string | null;\r\n server_id?: string;\r\n everyone_ping?: boolean;\r\n // CamelCase aliases (added by SDK for convenience)\r\n channelId?: string; // Alias for channel_id\r\n createdAt?: string; // Alias for created_at\r\n updatedAt?: string; // Alias for updated_at\r\n isEdited?: boolean; // Alias for edited\r\n}\r\n\r\nexport interface MessageReply {\r\n id: string;\r\n content: string;\r\n author: string; // Server sends author as string (username), not object\r\n}\r\n\r\nexport interface Reaction {\r\n id: string;\r\n messageId: string;\r\n userId: string;\r\n emoji: string;\r\n customEmojiId: string | null;\r\n createdAt: string;\r\n}\r\n\r\nexport interface Attachment {\r\n id: string;\r\n messageId: string;\r\n fileName: string;\r\n fileSize: number;\r\n mimeType: string;\r\n url: string;\r\n thumbnailUrl?: string;\r\n width?: number;\r\n height?: number;\r\n}\r\n\r\nexport interface PollData {\r\n question: string;\r\n options: string[];\r\n allowMultipleVotes?: boolean;\r\n expiresAt?: string | null;\r\n}\r\n\r\nexport interface MessageOptions {\r\n replyTo?: string;\r\n pollData?: PollData;\r\n attachments?: Array<{\r\n fileName: string;\r\n file: Blob | Buffer;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\n// ============================================================================\r\n// Bot Token Types\r\n// ============================================================================\r\n\r\nexport interface BotTokenInfo {\r\n id: string;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n userId: string;\r\n createdAt: string;\r\n lastUsedAt: string | null;\r\n}\r\n\r\nexport interface BotServerInfo {\r\n serverId: string;\r\n serverName: string;\r\n serverIconUrl: string | null;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n joinedAt: string;\r\n}\r\n\r\n// ============================================================================\r\n// API Response Types\r\n// ============================================================================\r\n\r\nexport interface PaginatedResponse<T> {\r\n data: T[];\r\n pagination: {\r\n page: number;\r\n limit: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n}\r\n\r\nexport interface APIError {\r\n message: string;\r\n statusCode: number;\r\n code?: string;\r\n}\r\n\r\n// ============================================================================\r\n// WebSocket Event Types\r\n// ============================================================================\r\n\r\nexport interface MessageNewEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageUpdatedEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageDeletedEvent {\r\n messageId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface UserStatusEvent {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n}\r\n\r\nexport interface TypingStartEvent {\r\n userId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface PollVotedEvent {\r\n pollId: string;\r\n userId: string;\r\n optionId: string;\r\n}\r\n\r\nexport interface VoiceEvent {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n}\r\n\r\nexport interface BotServerJoinedEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\nexport interface BotServerLeftEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\n// ============================================================================\r\n// Client Options Types\r\n// ============================================================================\r\n\r\nexport interface ChirpClientOptions {\r\n token?: string;\r\n baseUrl?: string;\r\n wsUrl?: string;\r\n commandPrefix?: string;\r\n intents?: Intent[];\r\n reconnectAttempts?: number;\r\n reconnectDelay?: number;\r\n}\r\n\r\nexport type Intent =\r\n | 'messages'\r\n | 'messageUpdates'\r\n | 'userStatus'\r\n | 'typing'\r\n | 'voice'\r\n | 'polls'\r\n | 'threads'\r\n | 'servers';\r\n\r\nexport const DEFAULT_INTENTS: Intent[] = [\r\n 'messages',\r\n 'messageUpdates',\r\n 'userStatus',\r\n 'typing',\r\n 'servers',\r\n];\r\n\r\n// ============================================================================\r\n// Command Types\r\n// ============================================================================\r\n\r\nexport interface Command {\r\n name: string;\r\n description: string;\r\n usage?: string;\r\n handler: (context: CommandContext) => void | Promise<void>;\r\n}\r\n\r\nexport interface CommandContext {\r\n command: string;\r\n args: string[];\r\n message: Message;\r\n channel: Channel;\r\n client: any; // ChirpClient - avoid circular reference\r\n api: any; // RESTClient - avoid circular reference\r\n}\r\n\r\n// ============================================================================\r\n// REST Client Type (forward declaration)\r\n// ============================================================================\r\n\r\nexport interface RESTClient {\r\n getBotInfo(): Promise<User>;\r\n getServers(): Promise<Server[]>;\r\n getBotServers(): Promise<BotServerInfo[]>;\r\n getChannels(serverId: string): Promise<Channel[]>;\r\n getMessages(channelId: string, options?: { page?: number; limit?: number }): Promise<PaginatedResponse<Message>>;\r\n sendMessage(channelId: string, content: string, options?: { replyTo?: string }): Promise<Message>;\r\n reply(channelId: string, messageId: string, content: string, author: string, originalContent: string): Promise<Message>;\r\n editMessage(messageId: string, content: string): Promise<Message>;\r\n deleteMessage(messageId: string): Promise<void>;\r\n joinServer(inviteCode: string): Promise<Server>;\r\n leaveServer(serverId: string): Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// Collection Type (for managers)\r\n// ============================================================================\r\n\r\nexport class Collection<K, V> extends Map<K, V> {\r\n constructor(entries?: readonly (readonly [K, V])[] | null) {\r\n super(entries);\r\n }\r\n\r\n public get(key: K): V | undefined {\r\n return super.get(key);\r\n }\r\n\r\n public set(key: K, value: V): this {\r\n return super.set(key, value);\r\n }\r\n\r\n public find(predicate: (value: V, key: K) => boolean): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n return value;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n public filter(predicate: (value: V, key: K) => boolean): V[] {\r\n const result: V[] = [];\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n result.push(value);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n public first(): V | undefined {\r\n return this.values().next().value;\r\n }\r\n\r\n public last(): V | undefined {\r\n let last: V | undefined;\r\n for (const value of this.values()) {\r\n last = value;\r\n }\r\n return last;\r\n }\r\n}\r\n","/**\r\n * Main ChirpClient class\r\n * The primary entry point for the Chirp Bot SDK\r\n */\r\n\r\nimport { io, Socket } from 'socket.io-client';\r\nimport type { SocketOptions } from 'socket.io-client';\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n PartialUser,\r\n Collection,\r\n ChirpClientOptions,\r\n Intent,\r\n Command,\r\n} from '../api/types.js';\r\nimport { RESTClient, APIError } from '../api/REST.js';\r\nimport { SafeEventEmitter } from './events/EventEmitter.js';\r\nimport type { ChirpEvents } from './events/Events.js';\r\nimport { CommandManager } from '../commands/CommandManager.js';\r\nimport { ChannelManager } from './managers/ChannelManager.js';\r\nimport { MessageManager } from './managers/MessageManager.js';\r\nimport { ServerManager } from './managers/ServerManager.js';\r\nimport { wsToHttp, delay } from '../util/helpers.js';\r\nimport { Logger } from '../util/logger.js';\r\n\r\n// Import Collection at runtime\r\nlet CollectionClass: any;\r\n\r\nfunction getCollection(): any {\r\n if (!CollectionClass) {\r\n // Dynamic import to avoid circular dependency\r\n const module = require('../api/types.js');\r\n CollectionClass = module.Collection;\r\n }\r\n return CollectionClass;\r\n}\r\n\r\n/**\r\n * Connection status enum\r\n */\r\nexport enum ConnectionStatus {\r\n Disconnected = 'disconnected',\r\n Connecting = 'connecting',\r\n Connected = 'connected',\r\n Reconnecting = 'reconnecting',\r\n}\r\n\r\n/**\r\n * Main Chirp Bot SDK client\r\n */\r\nexport class ChirpClient extends SafeEventEmitter<ChirpEvents> {\r\n // ========================================================================\r\n // Public Properties\r\n // ========================================================================\r\n\r\n public readonly options: Required<ChirpClientOptions>;\r\n public readonly commands: CommandManager;\r\n public api!: RESTClient;\r\n\r\n public user: User | null = null;\r\n public servers: Collection<string, Server>;\r\n public channels: Collection<string, Channel>;\r\n public ws!: Socket;\r\n\r\n public channelsManager!: ChannelManager;\r\n public messagesManager!: MessageManager;\r\n public serversManager!: ServerManager;\r\n\r\n // ========================================================================\r\n // Private Properties\r\n // ========================================================================\r\n\r\n private token: string | null = null;\r\n private baseUrl!: string;\r\n private wsUrl!: string;\r\n private socket!: Socket;\r\n private status: ConnectionStatus = ConnectionStatus.Disconnected;\r\n private reconnectAttempts: number = 0;\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n private readonly log: Logger;\r\n\r\n // ========================================================================\r\n // Constructor\r\n // ========================================================================\r\n\r\n constructor(options: ChirpClientOptions = {}) {\r\n super();\r\n\r\n // Set up options with defaults\r\n this.options = {\r\n token: options.token ?? '',\r\n baseUrl: options.baseUrl ?? '',\r\n wsUrl: options.wsUrl ?? 'ws://localhost:3001',\r\n commandPrefix: options.commandPrefix ?? '/',\r\n intents: options.intents ?? ['messages', 'messageUpdates', 'userStatus', 'typing', 'servers'],\r\n reconnectAttempts: options.reconnectAttempts ?? Infinity,\r\n reconnectDelay: options.reconnectDelay ?? 1000,\r\n };\r\n\r\n // Derive baseUrl from wsUrl if not provided\r\n if (!this.options.baseUrl) {\r\n this.baseUrl = wsToHttp(this.options.wsUrl);\r\n } else {\r\n this.baseUrl = this.options.baseUrl;\r\n }\r\n this.wsUrl = this.options.wsUrl;\r\n\r\n // Initialize logger\r\n this.log = new Logger('ChirpClient');\r\n\r\n // Initialize managers with temporary API client\r\n // Will be replaced after login with proper token\r\n this.api = new RESTClient(this.baseUrl, '');\r\n\r\n // Initialize command manager\r\n this.commands = new CommandManager(this.options.commandPrefix);\r\n\r\n // Initialize collections\r\n const Collection = getCollection();\r\n this.servers = new Collection();\r\n this.channels = new Collection();\r\n\r\n // Set up process handlers\r\n this.setupProcessHandlers();\r\n }\r\n\r\n // ========================================================================\r\n // Public Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Connect and authenticate the bot\r\n */\r\n async login(token?: string): Promise<void> {\r\n if (this.status !== ConnectionStatus.Disconnected) {\r\n throw new Error('Client is already connected or connecting');\r\n }\r\n\r\n this.token = token || this.options.token;\r\n if (!this.token) {\r\n throw new Error('No token provided. Set token in options or pass to login()');\r\n }\r\n\r\n this.status = ConnectionStatus.Connecting;\r\n this.log.info('Connecting to', this.wsUrl);\r\n\r\n try {\r\n // Initialize API client with token\r\n this.api = new RESTClient(this.baseUrl, this.token);\r\n\r\n // Fetch bot info to validate token\r\n this.user = await this.api.getBotInfo();\r\n this.log.info(`Authenticated as ${this.user.username}`);\r\n\r\n // Initialize managers with proper API client\r\n this.channelsManager = new ChannelManager(this.api);\r\n this.messagesManager = new MessageManager(this.api);\r\n this.serversManager = new ServerManager(this.api);\r\n\r\n // Set up command manager client reference\r\n this.commands._setClient(this);\r\n\r\n // Fetch initial data\r\n await this.fetchInitialData();\r\n\r\n // Connect WebSocket\r\n await this.connectWebSocket();\r\n\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('ready');\r\n this.log.info('Bot is ready');\r\n\r\n } catch (error) {\r\n this.status = ConnectionStatus.Disconnected;\r\n this.log.error('Login failed:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect the bot\r\n */\r\n async logout(): Promise<void> {\r\n this.clearReconnectTimer();\r\n this.socket?.disconnect();\r\n this.status = ConnectionStatus.Disconnected;\r\n this.user = null;\r\n this.log.info('Logged out');\r\n }\r\n\r\n /**\r\n * Get current connection status\r\n */\r\n getStatus(): ConnectionStatus {\r\n return this.status;\r\n }\r\n\r\n /**\r\n * Check if the client is connected\r\n */\r\n isConnected(): boolean {\r\n return this.status === ConnectionStatus.Connected && this.socket?.connected === true;\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Initialization\r\n // ========================================================================\r\n\r\n private async fetchInitialData(): Promise<void> {\r\n try {\r\n const servers = await this.serversManager.fetch();\r\n this.log.debug(`Fetched ${servers.length} servers`);\r\n\r\n // Populate client's servers collection from manager's cache\r\n for (const [serverId, server] of this.serversManager.cache) {\r\n this.servers.set(serverId, server);\r\n }\r\n\r\n // Fetch channels for each server\r\n for (const server of servers) {\r\n try {\r\n const channels = await this.channelsManager.fetch(server.id);\r\n this.log.debug(`Fetched ${channels.length} channels for ${server.name}`);\r\n\r\n // Populate client's channels collection from manager's cache\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n } catch (error) {\r\n this.log.warn(`Failed to fetch channels for ${server.name}:`, error);\r\n }\r\n }\r\n } catch (error) {\r\n this.log.warn('Failed to fetch initial data:', error);\r\n }\r\n }\r\n\r\n private setupProcessHandlers(): void {\r\n const shutdown = async () => {\r\n await this.logout();\r\n process.exit(0);\r\n };\r\n\r\n process.on('SIGINT', shutdown);\r\n process.on('SIGTERM', shutdown);\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - WebSocket Connection\r\n // ========================================================================\r\n\r\n private async connectWebSocket(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const socketOptions: any = {\r\n auth: { token: `Bot ${this.token}` },\r\n reconnection: false, // We handle reconnection ourselves\r\n transports: ['websocket'],\r\n };\r\n\r\n this.socket = io(this.wsUrl, socketOptions);\r\n this.ws = this.socket;\r\n\r\n // Connection successful\r\n this.socket.on('connect', () => {\r\n this.log.debug('WebSocket connected');\r\n this.reconnectAttempts = 0;\r\n resolve();\r\n });\r\n\r\n // Connection error\r\n this.socket.on('connect_error', (error) => {\r\n this.log.error('WebSocket connection error:', error);\r\n this.status = ConnectionStatus.Disconnected;\r\n reject(error);\r\n });\r\n\r\n // Handle disconnect\r\n this.socket.on('disconnect', (reason) => {\r\n this.log.warn('WebSocket disconnected:', reason);\r\n this.status = ConnectionStatus.Disconnected;\r\n this.emit('disconnected', reason);\r\n\r\n // Attempt to reconnect if not intentionally disconnected\r\n if (reason !== 'io client disconnect') {\r\n this.scheduleReconnect();\r\n }\r\n });\r\n\r\n // Set up event handlers\r\n this.setupEventHandlers();\r\n });\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectAttempts >= this.options.reconnectAttempts) {\r\n this.log.error('Max reconnect attempts reached');\r\n this.emit('error', new Error('Max reconnect attempts reached'));\r\n return;\r\n }\r\n\r\n this.status = ConnectionStatus.Reconnecting;\r\n this.reconnectAttempts++;\r\n\r\n const delay = this.options.reconnectDelay * Math.min(this.reconnectAttempts, 10);\r\n\r\n this.log.info(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);\r\n this.emit('reconnecting', this.reconnectAttempts);\r\n\r\n this.reconnectTimer = setTimeout(async () => {\r\n try {\r\n await this.connectWebSocket();\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('reconnected', this.reconnectAttempts);\r\n this.log.info('Reconnected successfully');\r\n } catch (error) {\r\n this.log.error('Reconnect failed:', error);\r\n this.scheduleReconnect();\r\n }\r\n }, delay);\r\n }\r\n\r\n private clearReconnectTimer(): void {\r\n if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Event Handlers\r\n // ========================================================================\r\n\r\n private setupEventHandlers(): void {\r\n // Message events\r\n this.socket.on('message:new', this.handleMessageNew.bind(this));\r\n this.socket.on('message:updated', this.handleMessageUpdated.bind(this));\r\n this.socket.on('message:deleted', this.handleMessageDeleted.bind(this));\r\n this.socket.on('dm:new', this.handleDMNew.bind(this));\r\n\r\n // User events\r\n this.socket.on('user:status', this.handleUserStatus.bind(this));\r\n this.socket.on('typing:start', this.handleTypingStart.bind(this));\r\n\r\n // Poll events\r\n if (this.hasIntent('polls')) {\r\n this.socket.on('poll:voted', this.handlePollVoted.bind(this));\r\n }\r\n\r\n // Thread events\r\n if (this.hasIntent('threads')) {\r\n this.socket.on('thread:reopened', this.handleThreadReopened.bind(this));\r\n this.socket.on('user_joined_thread', this.handleUserJoinedThread.bind(this));\r\n }\r\n\r\n // Voice events\r\n if (this.hasIntent('voice')) {\r\n this.socket.on('voice:joined', this.handleVoiceJoined.bind(this));\r\n this.socket.on('voice:left', this.handleVoiceLeft.bind(this));\r\n }\r\n\r\n // Bot events\r\n this.socket.on('bot:server_joined', this.handleBotServerJoined.bind(this));\r\n this.socket.on('bot:server_left', this.handleBotServerLeft.bind(this));\r\n\r\n // Subscription events\r\n this.socket.on('subscription:added', this.handleSubscriptionAdded.bind(this));\r\n }\r\n\r\n private hasIntent(intent: Intent): boolean {\r\n return this.options.intents.includes(intent);\r\n }\r\n\r\n // ========================================================================\r\n // Message Event Handlers\r\n // ========================================================================\r\n\r\n private async handleMessageNew(data: any): Promise<void> {\r\n // Server sends message object directly, not wrapped\r\n // The message has channel_id property and author as string\r\n const message = data as Message;\r\n const channelId = message.channel_id;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n // message.bot_id is set for all bot messages\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Update cache\r\n this.messagesManager.set(message);\r\n\r\n // Get channel\r\n const channel = this.channels.get(channelId);\r\n if (!channel) return;\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n channel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event\r\n this.emit('message:new', message, channelId);\r\n }\r\n\r\n private async handleDMNew(data: any): Promise<void> {\r\n const message = data;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Determine the \"partner\" ID to construct the DM channel ID\r\n // If I am the sender, partner is receiver. If I am receiver, partner is sender.\r\n const partnerId = message.sender_id === this.user?.id ? message.receiver_id : message.sender_id;\r\n\r\n if (!partnerId) return;\r\n\r\n const dmChannelId = `dm-${partnerId}`;\r\n\r\n // Construct a fake channel object for DM\r\n const dmChannel: any = {\r\n id: dmChannelId,\r\n type: 'dm',\r\n name: message.sender_username || 'DM',\r\n serverId: null,\r\n createdAt: new Date().toISOString(),\r\n recipientId: partnerId\r\n };\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n dmChannel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event so bot code sees it\r\n this.emit('message:new', message, dmChannelId);\r\n }\r\n\r\n private handleMessageUpdated(data: {\r\n channelId: string;\r\n messageId: string;\r\n content: string;\r\n edited: boolean;\r\n edited_at: string;\r\n }): void {\r\n const { channelId, messageId, content, edited, edited_at } = data;\r\n // Update the message in cache if it exists\r\n const cachedMessage = this.messagesManager.get(messageId);\r\n if (cachedMessage) {\r\n const updatedMessage = {\r\n ...cachedMessage,\r\n content,\r\n edited,\r\n edited_at: edited_at,\r\n updated_at: edited_at,\r\n };\r\n this.messagesManager.cache.set(messageId, updatedMessage);\r\n }\r\n this.emit('message:updated', messageId, channelId, data);\r\n }\r\n\r\n private handleMessageDeleted(data: { messageId: string; channelId: string }): void {\r\n const { messageId, channelId } = data;\r\n this.messagesManager.deleteFromCache(messageId);\r\n this.emit('message:deleted', messageId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // User Event Handlers\r\n // ========================================================================\r\n\r\n private handleUserStatus(data: {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n }): void {\r\n const { userId, status, user } = data;\r\n this.emit('user:status', userId, status, user);\r\n }\r\n\r\n private handleTypingStart(data: { userId: string; channelId: string }): void {\r\n const { userId, channelId } = data;\r\n this.emit('typing:start', userId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // Poll Event Handlers\r\n // ========================================================================\r\n\r\n private handlePollVoted(data: { pollId: string; userId: string; optionId: string }): void {\r\n const { pollId, userId, optionId } = data;\r\n this.emit('poll:voted', pollId, userId, optionId);\r\n }\r\n\r\n // ========================================================================\r\n // Thread Event Handlers\r\n // ========================================================================\r\n\r\n private handleThreadReopened(data: { threadId: string; channelId: string }): void {\r\n const { threadId, channelId } = data;\r\n this.emit('thread:reopened', threadId, channelId);\r\n }\r\n\r\n private handleUserJoinedThread(data: { threadId: string; userId: string }): void {\r\n const { threadId, userId } = data;\r\n this.emit('user_joined_thread', threadId, userId);\r\n }\r\n\r\n // ========================================================================\r\n // Voice Event Handlers\r\n // ========================================================================\r\n\r\n private handleVoiceJoined(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:joined', userId, channelId, serverId);\r\n }\r\n\r\n private handleVoiceLeft(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:left', userId, channelId, serverId);\r\n }\r\n\r\n // ========================================================================\r\n // Bot Event Handlers\r\n // ========================================================================\r\n\r\n private handleBotServerJoined(data: { server: { id: string; name: string; icon_url: string | null } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Joined server: ${serverName}`);\r\n this.emit('bot:server_joined', serverId, serverName);\r\n\r\n // Add to servers collection with minimal server info\r\n // We'll fetch full server info later if needed\r\n const serverInfo: Server = {\r\n id: serverId,\r\n name: serverName,\r\n iconUrl: server.icon_url,\r\n ownerId: '', // Unknown at this point\r\n createdAt: new Date().toISOString(), // Approximate\r\n };\r\n this.servers.set(serverId, serverInfo);\r\n\r\n // Fetch channels for the new server\r\n this.channelsManager.fetch(serverId)\r\n .then((channels) => {\r\n // Populate channels collection\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n })\r\n .catch((error) => {\r\n this.log.warn(`Failed to fetch channels for ${serverName}:`, error);\r\n });\r\n }\r\n\r\n private handleBotServerLeft(data: { server: { id: string; name: string } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Left server: ${serverName}`);\r\n this.emit('bot:server_left', serverId, serverName);\r\n\r\n // Remove from cache\r\n this.servers.delete(serverId);\r\n\r\n // Remove channels for this server\r\n for (const [channelId, channel] of this.channels) {\r\n if (channel.serverId === serverId) {\r\n this.channels.delete(channelId);\r\n }\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Subscription Event Handlers\r\n // ========================================================================\r\n\r\n private handleSubscriptionAdded(data: {\r\n subscriptionId: string;\r\n channelId: string;\r\n userId: string;\r\n tier: string;\r\n }): void {\r\n this.emit('subscription:added', data);\r\n }\r\n}\r\n\r\n// Export types\r\nexport * from './events/Events.js';\r\nexport * from './managers/index.js';\r\n","/**\r\n * REST API Client for Chirp Bot SDK\r\n * Extracted and refactored from examples/demo-bot/src/api.js\r\n */\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n BotTokenInfo,\r\n BotServerInfo,\r\n MessageOptions,\r\n PaginatedResponse,\r\n} from './types.js';\r\n\r\nexport class APIError extends Error {\r\n public statusCode: number;\r\n public code?: string;\r\n\r\n constructor(message: string, statusCode: number, code?: string) {\r\n super(message);\r\n this.name = 'APIError';\r\n this.statusCode = statusCode;\r\n this.code = code;\r\n }\r\n}\r\n\r\nexport class RESTClient {\r\n private readonly baseUrl: string;\r\n private readonly token: string;\r\n\r\n constructor(baseUrl: string, token: string) {\r\n this.baseUrl = baseUrl;\r\n this.token = token;\r\n }\r\n\r\n /**\r\n * Make an authenticated API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n const headers: HeadersInit = {\r\n 'Authorization': `Bot ${this.token}`,\r\n 'Content-Type': 'application/json',\r\n ...options.headers,\r\n };\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n headers,\r\n });\r\n\r\n const contentType = response.headers.get('content-type');\r\n const isJson = contentType?.includes('application/json');\r\n\r\n if (!response.ok) {\r\n let errorMessage = `HTTP ${response.status}`;\r\n if (isJson) {\r\n try {\r\n const errorData = await response.json();\r\n errorMessage = errorData.message || errorData.error || errorMessage;\r\n } catch {\r\n // Use default error message\r\n }\r\n }\r\n throw new APIError(errorMessage, response.status);\r\n }\r\n\r\n if (isJson && response.status !== 204) {\r\n return response.json();\r\n }\r\n\r\n return undefined as T;\r\n }\r\n\r\n /**\r\n * GET request\r\n */\r\n private async get<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'GET' });\r\n }\r\n\r\n /**\r\n * POST request\r\n */\r\n private async post<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'POST',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PATCH request\r\n */\r\n private async patch<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PATCH',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PUT request\r\n */\r\n private async put<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PUT',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * DELETE request\r\n */\r\n private async delete<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'DELETE' });\r\n }\r\n\r\n // ========================================================================\r\n // Bot API Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Get the bot's user information\r\n */\r\n async getBotInfo(): Promise<User> {\r\n return this.get<User>('/api/auth/me');\r\n }\r\n\r\n /**\r\n * Get the bot's token information\r\n */\r\n async getTokenInfo(): Promise<BotTokenInfo> {\r\n return this.get<BotTokenInfo>('/api/bot-tokens');\r\n }\r\n\r\n /**\r\n * List all servers the bot has access to\r\n */\r\n async getServers(): Promise<Server[]> {\r\n return this.get<Server[]>('/api/servers');\r\n }\r\n\r\n /**\r\n * List the bot's server memberships with details\r\n */\r\n async getBotServers(): Promise<BotServerInfo[]> {\r\n return this.get<BotServerInfo[]>('/api/bot-tokens/servers');\r\n }\r\n\r\n /**\r\n * Get channels in a server\r\n */\r\n async getChannels(serverId: string): Promise<Channel[]> {\r\n return this.get<Channel[]>(`/api/servers/${serverId}/channels`);\r\n }\r\n\r\n /**\r\n * Get messages in a channel\r\n */\r\n async getMessages(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const params = new URLSearchParams();\r\n if (options.page) params.append('page', String(options.page));\r\n if (options.limit) params.append('limit', String(options.limit));\r\n const query = params.toString();\r\n return this.get<PaginatedResponse<Message>>(\r\n `/api/channels/${channelId}/messages${query ? `?${query}` : ''}`\r\n );\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async sendMessage(\r\n channelId: string,\r\n content: string,\r\n options: MessageOptions = {}\r\n ): Promise<Message> {\r\n const body: Record<string, any> = {\r\n content,\r\n replyTo: options.replyTo,\r\n };\r\n if (options.pollData) {\r\n body.poll_data = options.pollData;\r\n }\r\n\r\n if (channelId.startsWith('dm-')) {\r\n const receiverId = channelId.substring(3);\r\n return this.post<Message>(`/api/dms/${receiverId}/messages`, body);\r\n }\r\n\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, body);\r\n }\r\n\r\n /**\r\n * Reply to a specific message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, {\r\n content,\r\n replyTo: messageId,\r\n });\r\n }\r\n\r\n /**\r\n * Edit a message (only works for bot's own messages)\r\n */\r\n async editMessage(messageId: string, content: string, channelId?: string): Promise<Message> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.patch<Message>(`/api/direct-messages/${messageId}`, { content });\r\n }\r\n return this.patch<Message>(`/api/messages/${messageId}`, { content });\r\n }\r\n\r\n /**\r\n * Delete a message (only works for bot's own messages)\r\n */\r\n async deleteMessage(messageId: string, channelId?: string): Promise<void> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.delete<void>(`/api/direct-messages/${messageId}`);\r\n }\r\n return this.delete<void>(`/api/messages/${messageId}`);\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async joinServer(inviteCode: string): Promise<Server> {\r\n return this.post<Server>('/api/bot-tokens/servers/join', { inviteCode });\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leaveServer(serverId: string): Promise<void> {\r\n return this.delete<void>(`/api/bot-tokens/servers/${serverId}/leave`);\r\n }\r\n}\r\n","/**\r\n * Type-safe EventEmitter wrapper around EventEmitter3\r\n */\r\n\r\nimport EventEmitter from 'eventemitter3';\r\n\r\n// Extract event names from their signature\r\ntype EventNames<T> = T extends any ? (keyof T & string) : never;\r\ntype EventListener<T, K extends keyof T & string> = T[K] extends (\r\n ...args: any[]\r\n) => any\r\n ? T[K]\r\n : (...args: any[]) => void;\r\n\r\n/**\r\n * Type-safe event emitter\r\n */\r\nexport class SafeEventEmitter<TEvents extends Record<string, any>> {\r\n private readonly emitter: EventEmitter;\r\n\r\n constructor() {\r\n this.emitter = new EventEmitter();\r\n }\r\n\r\n /**\r\n * Register an event listener\r\n */\r\n public on<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.on(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register a one-time event listener\r\n */\r\n public once<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.once(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an event listener\r\n */\r\n public off<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.off(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n public emit<K extends EventNames<TEvents>>(\r\n event: K,\r\n ...args: any[]\r\n ): boolean {\r\n return this.emitter.emit(event, ...args);\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event or all events\r\n */\r\n public removeAllListeners<K extends EventNames<TEvents>>(event?: K): this {\r\n this.emitter.removeAllListeners(event);\r\n return this;\r\n }\r\n\r\n /**\r\n * Get the count of listeners for an event\r\n */\r\n public listenerCount<K extends EventNames<TEvents>>(event: K): number {\r\n return this.emitter.listenerCount(event);\r\n }\r\n}\r\n\r\n/**\r\n * Event listener types\r\n */\r\nexport type EventHandler<T = any> = (...args: T[]) => void;\r\n","/**\r\n * Command Context - provides context for command execution\r\n */\r\n\r\nimport type { Message, Channel, CommandContext as ICommandContext } from '../api/types.js';\r\n\r\n// Import types dynamically to avoid circular dependency\r\ntype ChirpClientType = any;\r\ntype RESTClientType = any;\r\n\r\n/**\r\n * Command execution context\r\n */\r\nexport class CommandContext implements ICommandContext {\r\n public readonly command: string;\r\n public readonly args: string[];\r\n public readonly message: Message;\r\n public readonly channel: Channel;\r\n public readonly client: ChirpClientType;\r\n public readonly api: RESTClientType;\r\n\r\n constructor(\r\n command: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientType,\r\n api: RESTClientType\r\n ) {\r\n this.command = command;\r\n this.args = args;\r\n this.message = message;\r\n this.channel = channel;\r\n this.client = client;\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Reply to the command message\r\n */\r\n async reply(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, {\r\n replyTo: this.message.id,\r\n });\r\n }\r\n\r\n /**\r\n * Send a message to the same channel\r\n */\r\n async send(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content);\r\n }\r\n\r\n /**\r\n * Edit the bot's response message\r\n */\r\n /**\r\n * Edit the bot's response message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n return this.api.editMessage(messageId, content, this.channel.id);\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n return this.api.deleteMessage(messageId, this.channel.id);\r\n }\r\n\r\n /**\r\n * Get the raw command string\r\n */\r\n get rawCommand(): string {\r\n return `${this.command}${this.args.length ? ' ' + this.args.join(' ') : ''}`;\r\n }\r\n}\r\n","/**\r\n * Command Manager - handles command registration and execution\r\n */\r\n\r\nimport type { Command, Message, Channel, RESTClient } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\nimport type { ChirpClient } from '../client/ChirpClient.js';\r\n\r\ntype ChirpClientInstance = ChirpClient;\r\n\r\n/**\r\n * Command Manager class\r\n */\r\nexport class CommandManager {\r\n private readonly commands: Map<string, Command>;\r\n private readonly prefix: string;\r\n private client?: ChirpClientInstance;\r\n\r\n constructor(prefix: string = '/') {\r\n this.commands = new Map();\r\n this.prefix = prefix;\r\n }\r\n\r\n /**\r\n * Set the client reference (called by ChirpClient)\r\n * @internal\r\n */\r\n _setClient(client: ChirpClientInstance): void {\r\n this.client = client;\r\n }\r\n\r\n /**\r\n * Register a command\r\n */\r\n register(command: Command): this;\r\n register(builder: { build(): Command }): this;\r\n register(commandOrBuilder: Command | { build(): Command }): this {\r\n const command =\r\n 'build' in commandOrBuilder ? commandOrBuilder.build() : commandOrBuilder;\r\n\r\n this.commands.set(command.name, command);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register multiple commands\r\n */\r\n registerMany(commands: (Command | { build(): Command })[]): this {\r\n for (const commandOrBuilder of commands) {\r\n if ('build' in commandOrBuilder) {\r\n this.register(commandOrBuilder);\r\n } else {\r\n this.register(commandOrBuilder);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Unregister a command\r\n */\r\n unregister(name: string): boolean {\r\n return this.commands.delete(name);\r\n }\r\n\r\n /**\r\n * Get a command by name\r\n */\r\n get(name: string): Command | undefined {\r\n return this.commands.get(name);\r\n }\r\n\r\n /**\r\n * Check if a command exists\r\n */\r\n has(name: string): boolean {\r\n return this.commands.has(name);\r\n }\r\n\r\n /**\r\n * Get all registered commands\r\n */\r\n getAll(): Map<string, Command> {\r\n return new Map(this.commands);\r\n }\r\n\r\n /**\r\n * Clear all commands\r\n */\r\n clear(): void {\r\n this.commands.clear();\r\n }\r\n\r\n /**\r\n * Parse a message to check if it's a command\r\n * Returns { command, args } if it's a command, null otherwise\r\n */\r\n parse(message: Message): { command: string; args: string[] } | null {\r\n const content = message.content.trim();\r\n\r\n if (!content.startsWith(this.prefix)) {\r\n return null;\r\n }\r\n\r\n const parts = content.slice(this.prefix.length).trim().split(/\\s+/);\r\n const command = parts[0];\r\n const args = parts.slice(1);\r\n\r\n return { command, args };\r\n }\r\n\r\n /**\r\n * Execute a command\r\n * @internal\r\n */\r\n async execute(\r\n commandName: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientInstance,\r\n api: RESTClient\r\n ): Promise<void> {\r\n const command = this.commands.get(commandName);\r\n\r\n if (!command) {\r\n return;\r\n }\r\n\r\n const context = new CommandContext(\r\n commandName,\r\n args,\r\n message,\r\n channel,\r\n client,\r\n api\r\n );\r\n\r\n try {\r\n await command.handler(context);\r\n } catch (error) {\r\n // Emit error event through client if available\r\n if (this.client) {\r\n this.client.emit('error', error);\r\n }\r\n throw error;\r\n }\r\n }\r\n}\r\n","/**\r\n * Channel Manager - manages channel caching and operations\r\n */\r\n\r\nimport type { Channel, Collection, RESTClient } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for channel operations\r\n */\r\nexport class ChannelManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Channel>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ChannelManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch channels for a server\r\n */\r\n async fetch(serverId: string): Promise<Channel[]> {\r\n const channels = await this.api.getChannels(serverId);\r\n\r\n // Update cache\r\n for (const channel of channels) {\r\n this.cache.set(channel.id, channel);\r\n }\r\n\r\n return channels;\r\n }\r\n\r\n /**\r\n * Get a channel from cache by ID\r\n */\r\n get(channelId: string): Channel | undefined {\r\n return this.cache.get(channelId);\r\n }\r\n\r\n /**\r\n * Find a channel by name in a server\r\n */\r\n findByName(serverId: string, name: string): Channel | undefined {\r\n return this.cache.find(\r\n (channel) => channel.serverId === serverId && channel.name === name\r\n );\r\n }\r\n\r\n /**\r\n * Get all channels from cache\r\n */\r\n getAll(): Collection<string, Channel> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the channel cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a channel in cache\r\n */\r\n set(channel: Channel): this {\r\n this.cache.set(channel.id, channel);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a channel from cache\r\n */\r\n delete(channelId: string): boolean {\r\n return this.cache.delete(channelId);\r\n }\r\n}\r\n","/**\r\n * Message Manager - manages message operations\r\n */\r\n\r\nimport type {\r\n Message,\r\n MessageOptions,\r\n PaginatedResponse,\r\n RESTClient,\r\n Collection,\r\n} from '../../api/types.js';\r\n\r\n/**\r\n * Manager for message operations\r\n */\r\nexport class MessageManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Message>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof MessageManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch messages for a channel\r\n */\r\n async fetch(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const response = await this.api.getMessages(channelId, options);\r\n\r\n // Update cache\r\n for (const message of response.data) {\r\n this.cache.set(message.id, message);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async send(channelId: string, content: string, options?: MessageOptions): Promise<Message> {\r\n const message = await this.api.sendMessage(channelId, content, options);\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Reply to a message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n const message = await this.api.reply(\r\n channelId,\r\n messageId,\r\n content,\r\n author,\r\n originalContent\r\n );\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Edit a message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n const message = await this.api.editMessage(messageId, content);\r\n\r\n // Update cache\r\n this.cache.set(messageId, message);\r\n\r\n return message;\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n await this.api.deleteMessage(messageId);\r\n this.cache.delete(messageId);\r\n }\r\n\r\n /**\r\n * Get a message from cache by ID\r\n */\r\n get(messageId: string): Message | undefined {\r\n return this.cache.get(messageId);\r\n }\r\n\r\n /**\r\n * Get all messages from cache\r\n */\r\n getAll(): Collection<string, Message> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the message cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a message in cache\r\n */\r\n set(message: Message): this {\r\n this.cache.set(message.id, message);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a message from cache\r\n */\r\n deleteFromCache(messageId: string): boolean {\r\n return this.cache.delete(messageId);\r\n }\r\n}\r\n","/**\r\n * Server Manager - manages server caching and operations\r\n */\r\n\r\nimport type { Server, RESTClient, Collection } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for server operations\r\n */\r\nexport class ServerManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Server>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ServerManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch all servers the bot has access to\r\n */\r\n async fetch(): Promise<Server[]> {\r\n const servers = await this.api.getServers();\r\n\r\n // Update cache\r\n for (const server of servers) {\r\n this.cache.set(server.id, server);\r\n }\r\n\r\n return servers;\r\n }\r\n\r\n /**\r\n * Fetch the bot's server memberships with details\r\n */\r\n async fetchBotServers(): Promise<Server[]> {\r\n const botServers = await this.api.getBotServers();\r\n\r\n // Update cache with server info\r\n for (const botServer of botServers) {\r\n this.cache.set(botServer.serverId, {\r\n id: botServer.serverId,\r\n name: botServer.serverName,\r\n iconUrl: botServer.serverIconUrl,\r\n ownerId: '',\r\n createdAt: botServer.joinedAt,\r\n });\r\n }\r\n\r\n return botServers.map((bs: any) => ({\r\n id: bs.serverId,\r\n name: bs.serverName,\r\n iconUrl: bs.serverIconUrl,\r\n ownerId: '',\r\n createdAt: bs.joinedAt,\r\n }));\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async join(inviteCode: string): Promise<Server> {\r\n const server = await this.api.joinServer(inviteCode);\r\n this.cache.set(server.id, server);\r\n return server;\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leave(serverId: string): Promise<void> {\r\n await this.api.leaveServer(serverId);\r\n this.cache.delete(serverId);\r\n }\r\n\r\n /**\r\n * Get a server from cache by ID\r\n */\r\n get(serverId: string): Server | undefined {\r\n return this.cache.get(serverId);\r\n }\r\n\r\n /**\r\n * Find a server by name\r\n */\r\n findByName(name: string): Server | undefined {\r\n return this.cache.find((server) => server.name === name);\r\n }\r\n\r\n /**\r\n * Get all servers from cache\r\n */\r\n getAll(): Collection<string, Server> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the server cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a server in cache\r\n */\r\n set(server: Server): this {\r\n this.cache.set(server.id, server);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a server from cache\r\n */\r\n delete(serverId: string): boolean {\r\n return this.cache.delete(serverId);\r\n }\r\n}\r\n","/**\r\n * Utility helper functions\r\n */\r\n\r\n/**\r\n * Convert a WebSocket URL to HTTP URL\r\n */\r\nexport function wsToHttp(wsUrl: string): string {\r\n return wsUrl\r\n .replace(/^ws:\\/\\//i, 'http://')\r\n .replace(/^wss:\\/\\//i, 'https://');\r\n}\r\n\r\n/**\r\n * Convert an HTTP URL to WebSocket URL\r\n */\r\nexport function httpToWs(httpUrl: string): string {\r\n return httpUrl\r\n .replace(/^http:\\/\\//i, 'ws://')\r\n .replace(/^https:\\/\\//i, 'wss://');\r\n}\r\n\r\n/**\r\n * Parse command arguments from a string\r\n * Handles quoted strings as single arguments\r\n */\r\nexport function parseArgs(input: string): string[] {\r\n const args: string[] = [];\r\n let current = '';\r\n let inQuotes = false;\r\n\r\n for (let i = 0; i < input.length; i++) {\r\n const char = input[i];\r\n\r\n if (char === '\"' || char === \"'\") {\r\n inQuotes = !inQuotes;\r\n } else if (char === ' ' && !inQuotes) {\r\n if (current) {\r\n args.push(current);\r\n current = '';\r\n }\r\n } else {\r\n current += char;\r\n }\r\n }\r\n\r\n if (current) {\r\n args.push(current);\r\n }\r\n\r\n return args;\r\n}\r\n\r\n/**\r\n * Format a user mention\r\n */\r\nexport function formatMention(userId: string): string {\r\n return `<@${userId}>`;\r\n}\r\n\r\n/**\r\n * Format a channel mention\r\n */\r\nexport function formatChannelMention(channelId: string): string {\r\n return `<#${channelId}>`;\r\n}\r\n\r\n/**\r\n * Extract user IDs from mentions in a message\r\n */\r\nexport function extractMentionIds(content: string): string[] {\r\n const mentionRegex = /<@([^>]+)>/g;\r\n const ids: string[] = [];\r\n let match;\r\n\r\n while ((match = mentionRegex.exec(content)) !== null) {\r\n ids.push(match[1]);\r\n }\r\n\r\n return ids;\r\n}\r\n\r\n/**\r\n * Delay execution for a specified time\r\n */\r\nexport function delay(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Retry a function with exponential backoff\r\n */\r\nexport async function retry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts?: number;\r\n initialDelay?: number;\r\n maxDelay?: number;\r\n factor?: number;\r\n } = {}\r\n): Promise<T> {\r\n const {\r\n maxAttempts = 3,\r\n initialDelay = 1000,\r\n maxDelay = 10000,\r\n factor = 2,\r\n } = options;\r\n\r\n let delayTime = initialDelay;\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error as Error;\r\n\r\n if (attempt === maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n await delay(delayTime);\r\n delayTime = Math.min(delayTime * factor, maxDelay);\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n","/**\r\n * Logger utility for the SDK\r\n */\r\n\r\nexport enum LogLevel {\r\n DEBUG = 0,\r\n INFO = 1,\r\n WARN = 2,\r\n ERROR = 3,\r\n}\r\n\r\nexport class Logger {\r\n private level: LogLevel;\r\n private prefix: string;\r\n\r\n constructor(prefix: string = 'ChirpSDK', level: LogLevel = LogLevel.INFO) {\r\n this.prefix = prefix;\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Set the log level\r\n */\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Format a log message\r\n */\r\n private format(level: string, message: string, ...args: any[]): string {\r\n const timestamp = new Date().toISOString();\r\n return `[${timestamp}] [${level}] [${this.prefix}] ${message}`;\r\n }\r\n\r\n /**\r\n * Log a debug message\r\n */\r\n debug(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.DEBUG) {\r\n console.debug(this.format('DEBUG', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an info message\r\n */\r\n info(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.INFO) {\r\n console.info(this.format('INFO', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log a warning message\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.WARN) {\r\n console.warn(this.format('WARN', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an error message\r\n */\r\n error(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.ERROR) {\r\n console.error(this.format('ERROR', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Create a child logger with a different prefix\r\n */\r\n child(prefix: string): Logger {\r\n return new Logger(`${this.prefix}:${prefix}`, this.level);\r\n }\r\n}\r\n\r\n/**\r\n * Default logger instance\r\n */\r\nexport const logger = new Logger();\r\n","/**\r\n * Command Builder - fluent API for building commands\r\n */\r\n\r\nimport type { Command } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\n\r\nexport class CommandBuilder {\r\n private name: string = '';\r\n private description: string = '';\r\n private usage?: string;\r\n private handler?: (context: CommandContext) => void | Promise<void>;\r\n\r\n /**\r\n * Set the command name\r\n */\r\n setName(name: string): this {\r\n this.name = name;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command description\r\n */\r\n setDescription(description: string): this {\r\n this.description = description;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command usage example\r\n */\r\n setUsage(usage: string): this {\r\n this.usage = usage;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command handler\r\n */\r\n setHandler(handler: (context: CommandContext) => void | Promise<void>): this {\r\n this.handler = handler;\r\n return this;\r\n }\r\n\r\n /**\r\n * Build the command object\r\n */\r\n build(): Command {\r\n if (!this.name) {\r\n throw new Error('Command name is required');\r\n }\r\n if (!this.description) {\r\n throw new Error('Command description is required');\r\n }\r\n if (!this.handler) {\r\n throw new Error('Command handler is required');\r\n }\r\n\r\n return {\r\n name: this.name,\r\n description: this.description,\r\n usage: this.usage,\r\n handler: this.handler as any, // Cast to satisfy Command type\r\n };\r\n }\r\n}\r\n","/**\r\n * Custom error classes for the Chirp Bot SDK\r\n */\r\n\r\n/**\r\n * Base error class for all SDK errors\r\n */\r\nexport class ChirpError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'ChirpError';\r\n Error.captureStackTrace?.(this, this.constructor);\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends ChirpError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a rate limit is hit\r\n */\r\nexport class RateLimitError extends ChirpError {\r\n public readonly retryAfter: number;\r\n\r\n constructor(message: string, retryAfter: number = 0) {\r\n super(message);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a requested resource is not found\r\n */\r\nexport class NotFoundError extends ChirpError {\r\n constructor(message: string = 'Resource not found') {\r\n super(message);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the client lacks permission for an action\r\n */\r\nexport class PermissionError extends ChirpError {\r\n constructor(message: string = 'Insufficient permissions') {\r\n super(message);\r\n this.name = 'PermissionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a request is invalid\r\n */\r\nexport class ValidationError extends ChirpError {\r\n constructor(message: string = 'Validation failed') {\r\n super(message);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the WebSocket connection fails\r\n */\r\nexport class ConnectionError extends ChirpError {\r\n constructor(message: string = 'Connection failed') {\r\n super(message);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when command execution fails\r\n */\r\nexport class CommandError extends ChirpError {\r\n public readonly commandName: string;\r\n\r\n constructor(message: string, commandName: string) {\r\n super(message);\r\n this.name = 'CommandError';\r\n this.commandName = commandName;\r\n }\r\n}\r\n"],"mappings":"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","names":["Collection","Collection","Collection","LogLevel","ConnectionStatus","Collection","delay"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/types.ts","../src/client/ChirpClient.ts","../src/api/REST.ts","../src/client/events/EventEmitter.ts","../src/commands/CommandContext.ts","../src/commands/CommandManager.ts","../src/client/managers/ChannelManager.ts","../src/client/managers/MessageManager.ts","../src/client/managers/ServerManager.ts","../src/util/helpers.ts","../src/util/logger.ts","../src/commands/CommandBuilder.ts","../src/errors/index.ts"],"sourcesContent":["/**\r\n * Core API types for the Chirp Bot SDK\r\n * Based on the Chirp REST API and WebSocket events\r\n */\r\n\r\n// ============================================================================\r\n// User Types\r\n// ============================================================================\r\n\r\nexport interface User {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n isBot: true;\r\n botTokenId: string;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialUser {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status?: string;\r\n isBot?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// Server Types\r\n// ============================================================================\r\n\r\nexport interface Server {\r\n id: string;\r\n name: string;\r\n iconUrl: string | null;\r\n ownerId: string;\r\n createdAt: string;\r\n memberCount?: number;\r\n}\r\n\r\nexport interface ServerMember {\r\n serverId: string;\r\n userId: string;\r\n roles: string[];\r\n joinedAt: string;\r\n user: PartialUser;\r\n}\r\n\r\n// ============================================================================\r\n// Channel Types\r\n// ============================================================================\r\n\r\nexport interface Channel {\r\n id: string;\r\n serverId: string;\r\n name: string;\r\n type: 'text' | 'voice' | 'media' | 'forum';\r\n parentId: string | null;\r\n position: number;\r\n permissions?: Record<string, boolean>;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialChannel {\r\n id: string;\r\n name: string;\r\n type: string;\r\n serverId?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Message Types\r\n// ============================================================================\r\n\r\nexport interface Message {\r\n id: string;\r\n // Server uses snake_case for channel_id\r\n channel_id: string;\r\n // Server sends author as string (username) for backward compatibility\r\n // Also sends username as the same value\r\n author: string;\r\n username: string;\r\n avatar_url: string | null;\r\n // User info for bots\r\n bot_id?: string;\r\n user_id?: string;\r\n content: string;\r\n // Server uses snake_case for these fields\r\n created_at: string;\r\n updated_at?: string;\r\n edited?: boolean;\r\n edited_at?: string;\r\n // Reply info (server uses snake_case)\r\n replying_to_id?: string;\r\n replying_to_author?: string;\r\n replying_to_content?: string;\r\n replyingTo?: MessageReply;\r\n reactions?: Reaction[];\r\n attachments?: Attachment[];\r\n // Server compatibility fields\r\n is_bot?: boolean;\r\n authorAvatar?: string | null;\r\n server_id?: string;\r\n everyone_ping?: boolean;\r\n // CamelCase aliases (added by SDK for convenience)\r\n channelId?: string; // Alias for channel_id\r\n createdAt?: string; // Alias for created_at\r\n updatedAt?: string; // Alias for updated_at\r\n isEdited?: boolean; // Alias for edited\r\n}\r\n\r\nexport interface MessageReply {\r\n id: string;\r\n content: string;\r\n author: string; // Server sends author as string (username), not object\r\n}\r\n\r\nexport interface Reaction {\r\n id: string;\r\n messageId: string;\r\n userId: string;\r\n emoji: string;\r\n customEmojiId: string | null;\r\n createdAt: string;\r\n}\r\n\r\nexport interface Attachment {\r\n id: string;\r\n messageId: string;\r\n fileName: string;\r\n fileSize: number;\r\n mimeType: string;\r\n url: string;\r\n thumbnailUrl?: string;\r\n width?: number;\r\n height?: number;\r\n}\r\n\r\nexport interface PollData {\r\n question: string;\r\n options: string[];\r\n allowMultipleVotes?: boolean;\r\n expiresAt?: string | null;\r\n}\r\n\r\nexport interface MessageOptions {\r\n replyTo?: string;\r\n pollData?: PollData;\r\n attachments?: Array<{\r\n fileName: string;\r\n file: Blob | Buffer;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\n// ============================================================================\r\n// Bot Token Types\r\n// ============================================================================\r\n\r\nexport interface BotTokenInfo {\r\n id: string;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n userId: string;\r\n createdAt: string;\r\n lastUsedAt: string | null;\r\n}\r\n\r\nexport interface BotServerInfo {\r\n serverId: string;\r\n serverName: string;\r\n serverIconUrl: string | null;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n joinedAt: string;\r\n}\r\n\r\n// ============================================================================\r\n// API Response Types\r\n// ============================================================================\r\n\r\nexport interface PaginatedResponse<T> {\r\n data: T[];\r\n pagination: {\r\n page: number;\r\n limit: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n}\r\n\r\nexport interface APIError {\r\n message: string;\r\n statusCode: number;\r\n code?: string;\r\n}\r\n\r\n// ============================================================================\r\n// WebSocket Event Types\r\n// ============================================================================\r\n\r\nexport interface MessageNewEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageUpdatedEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageDeletedEvent {\r\n messageId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface UserStatusEvent {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n}\r\n\r\nexport interface TypingStartEvent {\r\n userId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface PollVotedEvent {\r\n pollId: string;\r\n userId: string;\r\n optionId: string;\r\n}\r\n\r\nexport interface VoiceEvent {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n}\r\n\r\nexport interface BotServerJoinedEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\nexport interface BotServerLeftEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\n// ============================================================================\r\n// Client Options Types\r\n// ============================================================================\r\n\r\nexport interface ChirpClientOptions {\r\n token?: string;\r\n baseUrl?: string;\r\n wsUrl?: string;\r\n commandPrefix?: string;\r\n intents?: Intent[];\r\n reconnectAttempts?: number;\r\n reconnectDelay?: number;\r\n}\r\n\r\nexport type Intent =\r\n | 'messages'\r\n | 'messageUpdates'\r\n | 'userStatus'\r\n | 'typing'\r\n | 'voice'\r\n | 'polls'\r\n | 'threads'\r\n | 'servers';\r\n\r\nexport const DEFAULT_INTENTS: Intent[] = [\r\n 'messages',\r\n 'messageUpdates',\r\n 'userStatus',\r\n 'typing',\r\n 'servers',\r\n];\r\n\r\n// ============================================================================\r\n// Command Types\r\n// ============================================================================\r\n\r\nexport interface Command {\r\n name: string;\r\n description: string;\r\n usage?: string;\r\n handler: (context: CommandContext) => void | Promise<void>;\r\n}\r\n\r\nexport interface CommandContext {\r\n command: string;\r\n args: string[];\r\n message: Message;\r\n channel: Channel;\r\n client: any; // ChirpClient - avoid circular reference\r\n api: any; // RESTClient - avoid circular reference\r\n}\r\n\r\n// ============================================================================\r\n// REST Client Type (forward declaration)\r\n// ============================================================================\r\n\r\nexport interface RESTClient {\r\n getBotInfo(): Promise<User>;\r\n getServers(): Promise<Server[]>;\r\n getBotServers(): Promise<BotServerInfo[]>;\r\n getChannels(serverId: string): Promise<Channel[]>;\r\n getMessages(channelId: string, options?: { page?: number; limit?: number }): Promise<PaginatedResponse<Message>>;\r\n sendMessage(channelId: string, content: string, options?: { replyTo?: string }): Promise<Message>;\r\n reply(channelId: string, messageId: string, content: string, author: string, originalContent: string): Promise<Message>;\r\n editMessage(messageId: string, content: string): Promise<Message>;\r\n deleteMessage(messageId: string): Promise<void>;\r\n joinServer(inviteCode: string): Promise<Server>;\r\n leaveServer(serverId: string): Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// Collection Type (for managers)\r\n// ============================================================================\r\n\r\nexport class Collection<K, V> extends Map<K, V> {\r\n constructor(entries?: readonly (readonly [K, V])[] | null) {\r\n super(entries);\r\n }\r\n\r\n public get(key: K): V | undefined {\r\n return super.get(key);\r\n }\r\n\r\n public set(key: K, value: V): this {\r\n return super.set(key, value);\r\n }\r\n\r\n public find(predicate: (value: V, key: K) => boolean): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n return value;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n public filter(predicate: (value: V, key: K) => boolean): V[] {\r\n const result: V[] = [];\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n result.push(value);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n public first(): V | undefined {\r\n return this.values().next().value;\r\n }\r\n\r\n public last(): V | undefined {\r\n let last: V | undefined;\r\n for (const value of this.values()) {\r\n last = value;\r\n }\r\n return last;\r\n }\r\n}\r\n","/**\r\n * Main ChirpClient class\r\n * The primary entry point for the Chirp Bot SDK\r\n */\r\n\r\nimport { io, Socket } from 'socket.io-client';\r\nimport type { SocketOptions } from 'socket.io-client';\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n PartialUser,\r\n Collection,\r\n ChirpClientOptions,\r\n Intent,\r\n Command,\r\n} from '../api/types.js';\r\nimport { RESTClient, APIError } from '../api/REST.js';\r\nimport { SafeEventEmitter } from './events/EventEmitter.js';\r\nimport type { ChirpEvents } from './events/Events.js';\r\nimport { CommandManager } from '../commands/CommandManager.js';\r\nimport { ChannelManager } from './managers/ChannelManager.js';\r\nimport { MessageManager } from './managers/MessageManager.js';\r\nimport { ServerManager } from './managers/ServerManager.js';\r\nimport { wsToHttp, delay } from '../util/helpers.js';\r\nimport { Logger } from '../util/logger.js';\r\n\r\n// Import Collection at runtime\r\nlet CollectionClass: any;\r\n\r\nfunction getCollection(): any {\r\n if (!CollectionClass) {\r\n // Dynamic import to avoid circular dependency\r\n const module = require('../api/types.js');\r\n CollectionClass = module.Collection;\r\n }\r\n return CollectionClass;\r\n}\r\n\r\n/**\r\n * Connection status enum\r\n */\r\nexport enum ConnectionStatus {\r\n Disconnected = 'disconnected',\r\n Connecting = 'connecting',\r\n Connected = 'connected',\r\n Reconnecting = 'reconnecting',\r\n}\r\n\r\n/**\r\n * Main Chirp Bot SDK client\r\n */\r\nexport class ChirpClient extends SafeEventEmitter<ChirpEvents> {\r\n // ========================================================================\r\n // Public Properties\r\n // ========================================================================\r\n\r\n public readonly options: Required<ChirpClientOptions>;\r\n public readonly commands: CommandManager;\r\n public api!: RESTClient;\r\n\r\n public user: User | null = null;\r\n public servers: Collection<string, Server>;\r\n public channels: Collection<string, Channel>;\r\n public ws!: Socket;\r\n\r\n public channelsManager!: ChannelManager;\r\n public messagesManager!: MessageManager;\r\n public serversManager!: ServerManager;\r\n\r\n // ========================================================================\r\n // Private Properties\r\n // ========================================================================\r\n\r\n private token: string | null = null;\r\n private baseUrl!: string;\r\n private wsUrl!: string;\r\n private socket!: Socket;\r\n private status: ConnectionStatus = ConnectionStatus.Disconnected;\r\n private reconnectAttempts: number = 0;\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n private readonly log: Logger;\r\n\r\n // ========================================================================\r\n // Constructor\r\n // ========================================================================\r\n\r\n constructor(options: ChirpClientOptions = {}) {\r\n super();\r\n\r\n // Set up options with defaults\r\n this.options = {\r\n token: options.token ?? '',\r\n baseUrl: options.baseUrl ?? '',\r\n wsUrl: options.wsUrl ?? 'ws://localhost:3001',\r\n commandPrefix: options.commandPrefix ?? '/',\r\n intents: options.intents ?? ['messages', 'messageUpdates', 'userStatus', 'typing', 'servers'],\r\n reconnectAttempts: options.reconnectAttempts ?? Infinity,\r\n reconnectDelay: options.reconnectDelay ?? 1000,\r\n };\r\n\r\n // Derive baseUrl from wsUrl if not provided\r\n if (!this.options.baseUrl) {\r\n this.baseUrl = wsToHttp(this.options.wsUrl);\r\n } else {\r\n this.baseUrl = this.options.baseUrl;\r\n }\r\n this.wsUrl = this.options.wsUrl;\r\n\r\n // Initialize logger\r\n this.log = new Logger('ChirpClient');\r\n\r\n // Initialize managers with temporary API client\r\n // Will be replaced after login with proper token\r\n this.api = new RESTClient(this.baseUrl, '');\r\n\r\n // Initialize command manager\r\n this.commands = new CommandManager(this.options.commandPrefix);\r\n\r\n // Initialize collections\r\n const Collection = getCollection();\r\n this.servers = new Collection();\r\n this.channels = new Collection();\r\n\r\n // Set up process handlers\r\n this.setupProcessHandlers();\r\n }\r\n\r\n // ========================================================================\r\n // Public Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Connect and authenticate the bot\r\n */\r\n async login(token?: string): Promise<void> {\r\n if (this.status !== ConnectionStatus.Disconnected) {\r\n throw new Error('Client is already connected or connecting');\r\n }\r\n\r\n this.token = token || this.options.token;\r\n if (!this.token) {\r\n throw new Error('No token provided. Set token in options or pass to login()');\r\n }\r\n\r\n this.status = ConnectionStatus.Connecting;\r\n this.log.info('Connecting to', this.wsUrl);\r\n\r\n try {\r\n // Initialize API client with token\r\n this.api = new RESTClient(this.baseUrl, this.token);\r\n\r\n // Fetch bot info to validate token\r\n this.user = await this.api.getBotInfo();\r\n this.log.info(`Authenticated as ${this.user.username}`);\r\n\r\n // Initialize managers with proper API client\r\n this.channelsManager = new ChannelManager(this.api);\r\n this.messagesManager = new MessageManager(this.api);\r\n this.serversManager = new ServerManager(this.api);\r\n\r\n // Set up command manager client reference\r\n this.commands._setClient(this);\r\n\r\n // Fetch initial data\r\n await this.fetchInitialData();\r\n\r\n // Connect WebSocket\r\n await this.connectWebSocket();\r\n\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('ready');\r\n this.log.info('Bot is ready');\r\n\r\n } catch (error) {\r\n this.status = ConnectionStatus.Disconnected;\r\n this.log.error('Login failed:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect the bot\r\n */\r\n async logout(): Promise<void> {\r\n this.clearReconnectTimer();\r\n this.socket?.disconnect();\r\n this.status = ConnectionStatus.Disconnected;\r\n this.user = null;\r\n this.log.info('Logged out');\r\n }\r\n\r\n /**\r\n * Get current connection status\r\n */\r\n getStatus(): ConnectionStatus {\r\n return this.status;\r\n }\r\n\r\n /**\r\n * Check if the client is connected\r\n */\r\n isConnected(): boolean {\r\n return this.status === ConnectionStatus.Connected && this.socket?.connected === true;\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Initialization\r\n // ========================================================================\r\n\r\n private async fetchInitialData(): Promise<void> {\r\n try {\r\n const servers = await this.serversManager.fetch();\r\n this.log.debug(`Fetched ${servers.length} servers`);\r\n\r\n // Populate client's servers collection from manager's cache\r\n for (const [serverId, server] of this.serversManager.cache) {\r\n this.servers.set(serverId, server);\r\n }\r\n\r\n // Fetch channels for each server\r\n for (const server of servers) {\r\n try {\r\n const channels = await this.channelsManager.fetch(server.id);\r\n this.log.debug(`Fetched ${channels.length} channels for ${server.name}`);\r\n\r\n // Populate client's channels collection from manager's cache\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n } catch (error) {\r\n this.log.warn(`Failed to fetch channels for ${server.name}:`, error);\r\n }\r\n }\r\n } catch (error) {\r\n this.log.warn('Failed to fetch initial data:', error);\r\n }\r\n }\r\n\r\n private setupProcessHandlers(): void {\r\n const shutdown = async () => {\r\n await this.logout();\r\n process.exit(0);\r\n };\r\n\r\n process.on('SIGINT', shutdown);\r\n process.on('SIGTERM', shutdown);\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - WebSocket Connection\r\n // ========================================================================\r\n\r\n private async connectWebSocket(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const socketOptions: any = {\r\n auth: { token: `Bot ${this.token}` },\r\n reconnection: false, // We handle reconnection ourselves\r\n transports: ['websocket'],\r\n };\r\n\r\n this.socket = io(this.wsUrl, socketOptions);\r\n this.ws = this.socket;\r\n\r\n // Connection successful\r\n this.socket.on('connect', () => {\r\n this.log.debug('WebSocket connected');\r\n this.reconnectAttempts = 0;\r\n resolve();\r\n });\r\n\r\n // Connection error\r\n this.socket.on('connect_error', (error) => {\r\n this.log.error('WebSocket connection error:', error);\r\n this.status = ConnectionStatus.Disconnected;\r\n reject(error);\r\n });\r\n\r\n // Handle disconnect\r\n this.socket.on('disconnect', (reason) => {\r\n this.log.warn('WebSocket disconnected:', reason);\r\n this.status = ConnectionStatus.Disconnected;\r\n this.emit('disconnected', reason);\r\n\r\n // Attempt to reconnect if not intentionally disconnected\r\n if (reason !== 'io client disconnect') {\r\n this.scheduleReconnect();\r\n }\r\n });\r\n\r\n // Set up event handlers\r\n this.setupEventHandlers();\r\n });\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectAttempts >= this.options.reconnectAttempts) {\r\n this.log.error('Max reconnect attempts reached');\r\n this.emit('error', new Error('Max reconnect attempts reached'));\r\n return;\r\n }\r\n\r\n this.status = ConnectionStatus.Reconnecting;\r\n this.reconnectAttempts++;\r\n\r\n const delay = this.options.reconnectDelay * Math.min(this.reconnectAttempts, 10);\r\n\r\n this.log.info(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);\r\n this.emit('reconnecting', this.reconnectAttempts);\r\n\r\n this.reconnectTimer = setTimeout(async () => {\r\n try {\r\n await this.connectWebSocket();\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('reconnected', this.reconnectAttempts);\r\n this.log.info('Reconnected successfully');\r\n } catch (error) {\r\n this.log.error('Reconnect failed:', error);\r\n this.scheduleReconnect();\r\n }\r\n }, delay);\r\n }\r\n\r\n private clearReconnectTimer(): void {\r\n if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Event Handlers\r\n // ========================================================================\r\n\r\n private setupEventHandlers(): void {\r\n // Message events\r\n this.socket.on('message:new', this.handleMessageNew.bind(this));\r\n this.socket.on('message:updated', this.handleMessageUpdated.bind(this));\r\n this.socket.on('message:deleted', this.handleMessageDeleted.bind(this));\r\n this.socket.on('dm:new', this.handleDMNew.bind(this));\r\n\r\n // User events\r\n this.socket.on('user:status', this.handleUserStatus.bind(this));\r\n this.socket.on('typing:start', this.handleTypingStart.bind(this));\r\n\r\n // Poll events\r\n if (this.hasIntent('polls')) {\r\n this.socket.on('poll:voted', this.handlePollVoted.bind(this));\r\n }\r\n\r\n // Thread events\r\n if (this.hasIntent('threads')) {\r\n this.socket.on('thread:reopened', this.handleThreadReopened.bind(this));\r\n this.socket.on('user_joined_thread', this.handleUserJoinedThread.bind(this));\r\n }\r\n\r\n // Voice events\r\n if (this.hasIntent('voice')) {\r\n this.socket.on('voice:joined', this.handleVoiceJoined.bind(this));\r\n this.socket.on('voice:left', this.handleVoiceLeft.bind(this));\r\n }\r\n\r\n // Bot events\r\n this.socket.on('bot:server_joined', this.handleBotServerJoined.bind(this));\r\n this.socket.on('bot:server_left', this.handleBotServerLeft.bind(this));\r\n\r\n // Subscription events\r\n this.socket.on('subscription:added', this.handleSubscriptionAdded.bind(this));\r\n }\r\n\r\n private hasIntent(intent: Intent): boolean {\r\n return this.options.intents.includes(intent);\r\n }\r\n\r\n // ========================================================================\r\n // Message Event Handlers\r\n // ========================================================================\r\n\r\n private async handleMessageNew(data: any): Promise<void> {\r\n // Server sends message object directly, not wrapped\r\n // The message has channel_id property and author as string\r\n const message = data as Message;\r\n const channelId = message.channel_id;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n // message.bot_id is set for all bot messages\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Update cache\r\n this.messagesManager.set(message);\r\n\r\n // Get channel\r\n const channel = this.channels.get(channelId);\r\n if (!channel) return;\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n channel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event\r\n this.emit('message:new', message, channelId);\r\n }\r\n\r\n private async handleDMNew(data: any): Promise<void> {\r\n const message = data;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Determine the \"partner\" ID to construct the DM channel ID\r\n // If I am the sender, partner is receiver. If I am receiver, partner is sender.\r\n const partnerId = message.sender_id === this.user?.id ? message.receiver_id : message.sender_id;\r\n\r\n if (!partnerId) return;\r\n\r\n const dmChannelId = `dm-${partnerId}`;\r\n\r\n // Construct a fake channel object for DM\r\n const dmChannel: any = {\r\n id: dmChannelId,\r\n type: 'dm',\r\n name: message.sender_username || 'DM',\r\n serverId: null,\r\n createdAt: new Date().toISOString(),\r\n recipientId: partnerId\r\n };\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n dmChannel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event so bot code sees it\r\n this.emit('message:new', message, dmChannelId);\r\n }\r\n\r\n private handleMessageUpdated(data: {\r\n channelId: string;\r\n messageId: string;\r\n content: string;\r\n edited: boolean;\r\n edited_at: string;\r\n }): void {\r\n const { channelId, messageId, content, edited, edited_at } = data;\r\n // Update the message in cache if it exists\r\n const cachedMessage = this.messagesManager.get(messageId);\r\n if (cachedMessage) {\r\n const updatedMessage = {\r\n ...cachedMessage,\r\n content,\r\n edited,\r\n edited_at: edited_at,\r\n updated_at: edited_at,\r\n };\r\n this.messagesManager.cache.set(messageId, updatedMessage);\r\n }\r\n this.emit('message:updated', messageId, channelId, data);\r\n }\r\n\r\n private handleMessageDeleted(data: { messageId: string; channelId: string }): void {\r\n const { messageId, channelId } = data;\r\n this.messagesManager.deleteFromCache(messageId);\r\n this.emit('message:deleted', messageId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // User Event Handlers\r\n // ========================================================================\r\n\r\n private handleUserStatus(data: {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n }): void {\r\n const { userId, status, user } = data;\r\n this.emit('user:status', userId, status, user);\r\n }\r\n\r\n private handleTypingStart(data: { userId: string; channelId: string }): void {\r\n const { userId, channelId } = data;\r\n this.emit('typing:start', userId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // Poll Event Handlers\r\n // ========================================================================\r\n\r\n private handlePollVoted(data: { pollId: string; userId: string; optionId: string }): void {\r\n const { pollId, userId, optionId } = data;\r\n this.emit('poll:voted', pollId, userId, optionId);\r\n }\r\n\r\n // ========================================================================\r\n // Thread Event Handlers\r\n // ========================================================================\r\n\r\n private handleThreadReopened(data: { threadId: string; channelId: string }): void {\r\n const { threadId, channelId } = data;\r\n this.emit('thread:reopened', threadId, channelId);\r\n }\r\n\r\n private handleUserJoinedThread(data: { threadId: string; userId: string }): void {\r\n const { threadId, userId } = data;\r\n this.emit('user_joined_thread', threadId, userId);\r\n }\r\n\r\n // ========================================================================\r\n // Voice Event Handlers\r\n // ========================================================================\r\n\r\n private handleVoiceJoined(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:joined', userId, channelId, serverId);\r\n }\r\n\r\n private handleVoiceLeft(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:left', userId, channelId, serverId);\r\n }\r\n\r\n // ========================================================================\r\n // Bot Event Handlers\r\n // ========================================================================\r\n\r\n private handleBotServerJoined(data: { server: { id: string; name: string; icon_url: string | null } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Joined server: ${serverName}`);\r\n this.emit('bot:server_joined', serverId, serverName);\r\n\r\n // Add to servers collection with minimal server info\r\n // We'll fetch full server info later if needed\r\n const serverInfo: Server = {\r\n id: serverId,\r\n name: serverName,\r\n iconUrl: server.icon_url,\r\n ownerId: '', // Unknown at this point\r\n createdAt: new Date().toISOString(), // Approximate\r\n };\r\n this.servers.set(serverId, serverInfo);\r\n\r\n // Fetch channels for the new server\r\n this.channelsManager.fetch(serverId)\r\n .then((channels) => {\r\n // Populate channels collection\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n })\r\n .catch((error) => {\r\n this.log.warn(`Failed to fetch channels for ${serverName}:`, error);\r\n });\r\n }\r\n\r\n private handleBotServerLeft(data: { server: { id: string; name: string } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Left server: ${serverName}`);\r\n this.emit('bot:server_left', serverId, serverName);\r\n\r\n // Remove from cache\r\n this.servers.delete(serverId);\r\n\r\n // Remove channels for this server\r\n for (const [channelId, channel] of this.channels) {\r\n if (channel.serverId === serverId) {\r\n this.channels.delete(channelId);\r\n }\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Subscription Event Handlers\r\n // ========================================================================\r\n\r\n private handleSubscriptionAdded(data: {\r\n subscriptionId: string;\r\n channelId: string;\r\n userId: string;\r\n tier: string;\r\n }): void {\r\n this.emit('subscription:added', data);\r\n }\r\n}\r\n\r\n// Export types\r\nexport * from './events/Events.js';\r\nexport * from './managers/index.js';\r\n","/**\r\n * REST API Client for Chirp Bot SDK\r\n * Extracted and refactored from examples/demo-bot/src/api.js\r\n */\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n BotTokenInfo,\r\n BotServerInfo,\r\n MessageOptions,\r\n PaginatedResponse,\r\n} from './types.js';\r\n\r\nexport class APIError extends Error {\r\n public statusCode: number;\r\n public code?: string;\r\n\r\n constructor(message: string, statusCode: number, code?: string) {\r\n super(message);\r\n this.name = 'APIError';\r\n this.statusCode = statusCode;\r\n this.code = code;\r\n }\r\n}\r\n\r\nexport class RESTClient {\r\n private readonly baseUrl: string;\r\n private readonly token: string;\r\n\r\n constructor(baseUrl: string, token: string) {\r\n this.baseUrl = baseUrl;\r\n this.token = token;\r\n }\r\n\r\n /**\r\n * Make an authenticated API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n const headers: HeadersInit = {\r\n 'Authorization': `Bot ${this.token}`,\r\n 'Content-Type': 'application/json',\r\n ...options.headers,\r\n };\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n headers,\r\n });\r\n\r\n const contentType = response.headers.get('content-type');\r\n const isJson = contentType?.includes('application/json');\r\n\r\n if (!response.ok) {\r\n let errorMessage = `HTTP ${response.status}`;\r\n if (isJson) {\r\n try {\r\n const errorData = await response.json();\r\n errorMessage = errorData.message || errorData.error || errorMessage;\r\n } catch {\r\n // Use default error message\r\n }\r\n }\r\n throw new APIError(errorMessage, response.status);\r\n }\r\n\r\n if (isJson && response.status !== 204) {\r\n return response.json();\r\n }\r\n\r\n return undefined as T;\r\n }\r\n\r\n /**\r\n * GET request\r\n */\r\n private async get<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'GET' });\r\n }\r\n\r\n /**\r\n * POST request\r\n */\r\n private async post<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'POST',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PATCH request\r\n */\r\n private async patch<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PATCH',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PUT request\r\n */\r\n private async put<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PUT',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * DELETE request\r\n */\r\n private async delete<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'DELETE' });\r\n }\r\n\r\n // ========================================================================\r\n // Bot API Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Get the bot's user information\r\n */\r\n async getBotInfo(): Promise<User> {\r\n return this.get<User>('/api/auth/me');\r\n }\r\n\r\n /**\r\n * Get the bot's token information\r\n */\r\n async getTokenInfo(): Promise<BotTokenInfo> {\r\n return this.get<BotTokenInfo>('/api/bot-tokens');\r\n }\r\n\r\n /**\r\n * List all servers the bot has access to\r\n */\r\n async getServers(): Promise<Server[]> {\r\n return this.get<Server[]>('/api/servers');\r\n }\r\n\r\n /**\r\n * List the bot's server memberships with details\r\n */\r\n async getBotServers(): Promise<BotServerInfo[]> {\r\n return this.get<BotServerInfo[]>('/api/bot-tokens/servers');\r\n }\r\n\r\n /**\r\n * Get channels in a server\r\n */\r\n async getChannels(serverId: string): Promise<Channel[]> {\r\n return this.get<Channel[]>(`/api/servers/${serverId}/channels`);\r\n }\r\n\r\n /**\r\n * Get messages in a channel\r\n */\r\n async getMessages(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const params = new URLSearchParams();\r\n if (options.page) params.append('page', String(options.page));\r\n if (options.limit) params.append('limit', String(options.limit));\r\n const query = params.toString();\r\n\r\n if (channelId.startsWith('dm-')) {\r\n const receiverId = channelId.substring(3);\r\n return this.get<PaginatedResponse<Message>>(\r\n `/api/dms/${receiverId}/messages${query ? `?${query}` : ''}`\r\n );\r\n }\r\n\r\n return this.get<PaginatedResponse<Message>>(\r\n `/api/channels/${channelId}/messages${query ? `?${query}` : ''}`\r\n );\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async sendMessage(\r\n channelId: string,\r\n content: string,\r\n options: MessageOptions = {}\r\n ): Promise<Message> {\r\n const body: Record<string, any> = {\r\n content,\r\n replyTo: options.replyTo,\r\n };\r\n if (options.pollData) {\r\n body.poll_data = options.pollData;\r\n }\r\n\r\n if (channelId.startsWith('dm-')) {\r\n const receiverId = channelId.substring(3);\r\n return this.post<Message>(`/api/dms/${receiverId}/messages`, body);\r\n }\r\n\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, body);\r\n }\r\n\r\n /**\r\n * Reply to a specific message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, {\r\n content,\r\n replyTo: messageId,\r\n });\r\n }\r\n\r\n /**\r\n * Edit a message (only works for bot's own messages)\r\n */\r\n async editMessage(messageId: string, content: string, channelId?: string): Promise<Message> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.patch<Message>(`/api/direct-messages/${messageId}`, { content });\r\n }\r\n return this.patch<Message>(`/api/messages/${messageId}`, { content });\r\n }\r\n\r\n /**\r\n * Delete a message (only works for bot's own messages)\r\n */\r\n async deleteMessage(messageId: string, channelId?: string): Promise<void> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.delete<void>(`/api/direct-messages/${messageId}`);\r\n }\r\n return this.delete<void>(`/api/messages/${messageId}`);\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async joinServer(inviteCode: string): Promise<Server> {\r\n return this.post<Server>('/api/bot-tokens/servers/join', { inviteCode });\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leaveServer(serverId: string): Promise<void> {\r\n return this.delete<void>(`/api/bot-tokens/servers/${serverId}/leave`);\r\n }\r\n}\r\n","/**\r\n * Type-safe EventEmitter wrapper around EventEmitter3\r\n */\r\n\r\nimport EventEmitter from 'eventemitter3';\r\n\r\n// Extract event names from their signature\r\ntype EventNames<T> = T extends any ? (keyof T & string) : never;\r\ntype EventListener<T, K extends keyof T & string> = T[K] extends (\r\n ...args: any[]\r\n) => any\r\n ? T[K]\r\n : (...args: any[]) => void;\r\n\r\n/**\r\n * Type-safe event emitter\r\n */\r\nexport class SafeEventEmitter<TEvents extends Record<string, any>> {\r\n private readonly emitter: EventEmitter;\r\n\r\n constructor() {\r\n this.emitter = new EventEmitter();\r\n }\r\n\r\n /**\r\n * Register an event listener\r\n */\r\n public on<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.on(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register a one-time event listener\r\n */\r\n public once<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.once(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an event listener\r\n */\r\n public off<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.off(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n public emit<K extends EventNames<TEvents>>(\r\n event: K,\r\n ...args: any[]\r\n ): boolean {\r\n return this.emitter.emit(event, ...args);\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event or all events\r\n */\r\n public removeAllListeners<K extends EventNames<TEvents>>(event?: K): this {\r\n this.emitter.removeAllListeners(event);\r\n return this;\r\n }\r\n\r\n /**\r\n * Get the count of listeners for an event\r\n */\r\n public listenerCount<K extends EventNames<TEvents>>(event: K): number {\r\n return this.emitter.listenerCount(event);\r\n }\r\n}\r\n\r\n/**\r\n * Event listener types\r\n */\r\nexport type EventHandler<T = any> = (...args: T[]) => void;\r\n","/**\r\n * Command Context - provides context for command execution\r\n */\r\n\r\nimport type { Message, Channel, CommandContext as ICommandContext } from '../api/types.js';\r\n\r\n// Import types dynamically to avoid circular dependency\r\ntype ChirpClientType = any;\r\ntype RESTClientType = any;\r\n\r\n/**\r\n * Command execution context\r\n */\r\nexport class CommandContext implements ICommandContext {\r\n public readonly command: string;\r\n public readonly args: string[];\r\n public readonly message: Message;\r\n public readonly channel: Channel;\r\n public readonly client: ChirpClientType;\r\n public readonly api: RESTClientType;\r\n\r\n constructor(\r\n command: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientType,\r\n api: RESTClientType\r\n ) {\r\n this.command = command;\r\n this.args = args;\r\n this.message = message;\r\n this.channel = channel;\r\n this.client = client;\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Reply to the command message\r\n */\r\n async reply(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, {\r\n replyTo: this.message.id,\r\n });\r\n }\r\n\r\n /**\r\n * Send a message to the same channel\r\n */\r\n async send(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content);\r\n }\r\n\r\n /**\r\n * Edit the bot's response message\r\n */\r\n /**\r\n * Edit the bot's response message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n return this.api.editMessage(messageId, content, this.channel.id);\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n return this.api.deleteMessage(messageId, this.channel.id);\r\n }\r\n\r\n /**\r\n * Get the raw command string\r\n */\r\n get rawCommand(): string {\r\n return `${this.command}${this.args.length ? ' ' + this.args.join(' ') : ''}`;\r\n }\r\n}\r\n","/**\r\n * Command Manager - handles command registration and execution\r\n */\r\n\r\nimport type { Command, Message, Channel, RESTClient } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\nimport type { ChirpClient } from '../client/ChirpClient.js';\r\n\r\ntype ChirpClientInstance = ChirpClient;\r\n\r\n/**\r\n * Command Manager class\r\n */\r\nexport class CommandManager {\r\n private readonly commands: Map<string, Command>;\r\n private readonly prefix: string;\r\n private client?: ChirpClientInstance;\r\n\r\n constructor(prefix: string = '/') {\r\n this.commands = new Map();\r\n this.prefix = prefix;\r\n }\r\n\r\n /**\r\n * Set the client reference (called by ChirpClient)\r\n * @internal\r\n */\r\n _setClient(client: ChirpClientInstance): void {\r\n this.client = client;\r\n }\r\n\r\n /**\r\n * Register a command\r\n */\r\n register(command: Command): this;\r\n register(builder: { build(): Command }): this;\r\n register(commandOrBuilder: Command | { build(): Command }): this {\r\n const command =\r\n 'build' in commandOrBuilder ? commandOrBuilder.build() : commandOrBuilder;\r\n\r\n this.commands.set(command.name, command);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register multiple commands\r\n */\r\n registerMany(commands: (Command | { build(): Command })[]): this {\r\n for (const commandOrBuilder of commands) {\r\n if ('build' in commandOrBuilder) {\r\n this.register(commandOrBuilder);\r\n } else {\r\n this.register(commandOrBuilder);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Unregister a command\r\n */\r\n unregister(name: string): boolean {\r\n return this.commands.delete(name);\r\n }\r\n\r\n /**\r\n * Get a command by name\r\n */\r\n get(name: string): Command | undefined {\r\n return this.commands.get(name);\r\n }\r\n\r\n /**\r\n * Check if a command exists\r\n */\r\n has(name: string): boolean {\r\n return this.commands.has(name);\r\n }\r\n\r\n /**\r\n * Get all registered commands\r\n */\r\n getAll(): Map<string, Command> {\r\n return new Map(this.commands);\r\n }\r\n\r\n /**\r\n * Clear all commands\r\n */\r\n clear(): void {\r\n this.commands.clear();\r\n }\r\n\r\n /**\r\n * Parse a message to check if it's a command\r\n * Returns { command, args } if it's a command, null otherwise\r\n */\r\n parse(message: Message): { command: string; args: string[] } | null {\r\n const content = message.content.trim();\r\n\r\n if (!content.startsWith(this.prefix)) {\r\n return null;\r\n }\r\n\r\n const parts = content.slice(this.prefix.length).trim().split(/\\s+/);\r\n const command = parts[0];\r\n const args = parts.slice(1);\r\n\r\n return { command, args };\r\n }\r\n\r\n /**\r\n * Execute a command\r\n * @internal\r\n */\r\n async execute(\r\n commandName: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientInstance,\r\n api: RESTClient\r\n ): Promise<void> {\r\n const command = this.commands.get(commandName);\r\n\r\n if (!command) {\r\n return;\r\n }\r\n\r\n const context = new CommandContext(\r\n commandName,\r\n args,\r\n message,\r\n channel,\r\n client,\r\n api\r\n );\r\n\r\n try {\r\n await command.handler(context);\r\n } catch (error) {\r\n // Emit error event through client if available\r\n if (this.client) {\r\n this.client.emit('error', error);\r\n }\r\n throw error;\r\n }\r\n }\r\n}\r\n","/**\r\n * Channel Manager - manages channel caching and operations\r\n */\r\n\r\nimport type { Channel, Collection, RESTClient } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for channel operations\r\n */\r\nexport class ChannelManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Channel>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ChannelManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch channels for a server\r\n */\r\n async fetch(serverId: string): Promise<Channel[]> {\r\n const channels = await this.api.getChannels(serverId);\r\n\r\n // Update cache\r\n for (const channel of channels) {\r\n this.cache.set(channel.id, channel);\r\n }\r\n\r\n return channels;\r\n }\r\n\r\n /**\r\n * Get a channel from cache by ID\r\n */\r\n get(channelId: string): Channel | undefined {\r\n return this.cache.get(channelId);\r\n }\r\n\r\n /**\r\n * Find a channel by name in a server\r\n */\r\n findByName(serverId: string, name: string): Channel | undefined {\r\n return this.cache.find(\r\n (channel) => channel.serverId === serverId && channel.name === name\r\n );\r\n }\r\n\r\n /**\r\n * Get all channels from cache\r\n */\r\n getAll(): Collection<string, Channel> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the channel cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a channel in cache\r\n */\r\n set(channel: Channel): this {\r\n this.cache.set(channel.id, channel);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a channel from cache\r\n */\r\n delete(channelId: string): boolean {\r\n return this.cache.delete(channelId);\r\n }\r\n}\r\n","/**\r\n * Message Manager - manages message operations\r\n */\r\n\r\nimport type {\r\n Message,\r\n MessageOptions,\r\n PaginatedResponse,\r\n RESTClient,\r\n Collection,\r\n} from '../../api/types.js';\r\n\r\n/**\r\n * Manager for message operations\r\n */\r\nexport class MessageManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Message>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof MessageManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch messages for a channel\r\n */\r\n async fetch(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const response = await this.api.getMessages(channelId, options);\r\n\r\n // Update cache\r\n for (const message of response.data) {\r\n this.cache.set(message.id, message);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async send(channelId: string, content: string, options?: MessageOptions): Promise<Message> {\r\n const message = await this.api.sendMessage(channelId, content, options);\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Reply to a message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n const message = await this.api.reply(\r\n channelId,\r\n messageId,\r\n content,\r\n author,\r\n originalContent\r\n );\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Edit a message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n const message = await this.api.editMessage(messageId, content);\r\n\r\n // Update cache\r\n this.cache.set(messageId, message);\r\n\r\n return message;\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n await this.api.deleteMessage(messageId);\r\n this.cache.delete(messageId);\r\n }\r\n\r\n /**\r\n * Get a message from cache by ID\r\n */\r\n get(messageId: string): Message | undefined {\r\n return this.cache.get(messageId);\r\n }\r\n\r\n /**\r\n * Get all messages from cache\r\n */\r\n getAll(): Collection<string, Message> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the message cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a message in cache\r\n */\r\n set(message: Message): this {\r\n this.cache.set(message.id, message);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a message from cache\r\n */\r\n deleteFromCache(messageId: string): boolean {\r\n return this.cache.delete(messageId);\r\n }\r\n}\r\n","/**\r\n * Server Manager - manages server caching and operations\r\n */\r\n\r\nimport type { Server, RESTClient, Collection } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for server operations\r\n */\r\nexport class ServerManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Server>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ServerManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch all servers the bot has access to\r\n */\r\n async fetch(): Promise<Server[]> {\r\n const servers = await this.api.getServers();\r\n\r\n // Update cache\r\n for (const server of servers) {\r\n this.cache.set(server.id, server);\r\n }\r\n\r\n return servers;\r\n }\r\n\r\n /**\r\n * Fetch the bot's server memberships with details\r\n */\r\n async fetchBotServers(): Promise<Server[]> {\r\n const botServers = await this.api.getBotServers();\r\n\r\n // Update cache with server info\r\n for (const botServer of botServers) {\r\n this.cache.set(botServer.serverId, {\r\n id: botServer.serverId,\r\n name: botServer.serverName,\r\n iconUrl: botServer.serverIconUrl,\r\n ownerId: '',\r\n createdAt: botServer.joinedAt,\r\n });\r\n }\r\n\r\n return botServers.map((bs: any) => ({\r\n id: bs.serverId,\r\n name: bs.serverName,\r\n iconUrl: bs.serverIconUrl,\r\n ownerId: '',\r\n createdAt: bs.joinedAt,\r\n }));\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async join(inviteCode: string): Promise<Server> {\r\n const server = await this.api.joinServer(inviteCode);\r\n this.cache.set(server.id, server);\r\n return server;\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leave(serverId: string): Promise<void> {\r\n await this.api.leaveServer(serverId);\r\n this.cache.delete(serverId);\r\n }\r\n\r\n /**\r\n * Get a server from cache by ID\r\n */\r\n get(serverId: string): Server | undefined {\r\n return this.cache.get(serverId);\r\n }\r\n\r\n /**\r\n * Find a server by name\r\n */\r\n findByName(name: string): Server | undefined {\r\n return this.cache.find((server) => server.name === name);\r\n }\r\n\r\n /**\r\n * Get all servers from cache\r\n */\r\n getAll(): Collection<string, Server> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the server cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a server in cache\r\n */\r\n set(server: Server): this {\r\n this.cache.set(server.id, server);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a server from cache\r\n */\r\n delete(serverId: string): boolean {\r\n return this.cache.delete(serverId);\r\n }\r\n}\r\n","/**\r\n * Utility helper functions\r\n */\r\n\r\n/**\r\n * Convert a WebSocket URL to HTTP URL\r\n */\r\nexport function wsToHttp(wsUrl: string): string {\r\n return wsUrl\r\n .replace(/^ws:\\/\\//i, 'http://')\r\n .replace(/^wss:\\/\\//i, 'https://');\r\n}\r\n\r\n/**\r\n * Convert an HTTP URL to WebSocket URL\r\n */\r\nexport function httpToWs(httpUrl: string): string {\r\n return httpUrl\r\n .replace(/^http:\\/\\//i, 'ws://')\r\n .replace(/^https:\\/\\//i, 'wss://');\r\n}\r\n\r\n/**\r\n * Parse command arguments from a string\r\n * Handles quoted strings as single arguments\r\n */\r\nexport function parseArgs(input: string): string[] {\r\n const args: string[] = [];\r\n let current = '';\r\n let inQuotes = false;\r\n\r\n for (let i = 0; i < input.length; i++) {\r\n const char = input[i];\r\n\r\n if (char === '\"' || char === \"'\") {\r\n inQuotes = !inQuotes;\r\n } else if (char === ' ' && !inQuotes) {\r\n if (current) {\r\n args.push(current);\r\n current = '';\r\n }\r\n } else {\r\n current += char;\r\n }\r\n }\r\n\r\n if (current) {\r\n args.push(current);\r\n }\r\n\r\n return args;\r\n}\r\n\r\n/**\r\n * Format a user mention\r\n */\r\nexport function formatMention(userId: string): string {\r\n return `<@${userId}>`;\r\n}\r\n\r\n/**\r\n * Format a channel mention\r\n */\r\nexport function formatChannelMention(channelId: string): string {\r\n return `<#${channelId}>`;\r\n}\r\n\r\n/**\r\n * Extract user IDs from mentions in a message\r\n */\r\nexport function extractMentionIds(content: string): string[] {\r\n const mentionRegex = /<@([^>]+)>/g;\r\n const ids: string[] = [];\r\n let match;\r\n\r\n while ((match = mentionRegex.exec(content)) !== null) {\r\n ids.push(match[1]);\r\n }\r\n\r\n return ids;\r\n}\r\n\r\n/**\r\n * Delay execution for a specified time\r\n */\r\nexport function delay(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Retry a function with exponential backoff\r\n */\r\nexport async function retry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts?: number;\r\n initialDelay?: number;\r\n maxDelay?: number;\r\n factor?: number;\r\n } = {}\r\n): Promise<T> {\r\n const {\r\n maxAttempts = 3,\r\n initialDelay = 1000,\r\n maxDelay = 10000,\r\n factor = 2,\r\n } = options;\r\n\r\n let delayTime = initialDelay;\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error as Error;\r\n\r\n if (attempt === maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n await delay(delayTime);\r\n delayTime = Math.min(delayTime * factor, maxDelay);\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n","/**\r\n * Logger utility for the SDK\r\n */\r\n\r\nexport enum LogLevel {\r\n DEBUG = 0,\r\n INFO = 1,\r\n WARN = 2,\r\n ERROR = 3,\r\n}\r\n\r\nexport class Logger {\r\n private level: LogLevel;\r\n private prefix: string;\r\n\r\n constructor(prefix: string = 'ChirpSDK', level: LogLevel = LogLevel.INFO) {\r\n this.prefix = prefix;\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Set the log level\r\n */\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Format a log message\r\n */\r\n private format(level: string, message: string, ...args: any[]): string {\r\n const timestamp = new Date().toISOString();\r\n return `[${timestamp}] [${level}] [${this.prefix}] ${message}`;\r\n }\r\n\r\n /**\r\n * Log a debug message\r\n */\r\n debug(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.DEBUG) {\r\n console.debug(this.format('DEBUG', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an info message\r\n */\r\n info(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.INFO) {\r\n console.info(this.format('INFO', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log a warning message\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.WARN) {\r\n console.warn(this.format('WARN', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an error message\r\n */\r\n error(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.ERROR) {\r\n console.error(this.format('ERROR', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Create a child logger with a different prefix\r\n */\r\n child(prefix: string): Logger {\r\n return new Logger(`${this.prefix}:${prefix}`, this.level);\r\n }\r\n}\r\n\r\n/**\r\n * Default logger instance\r\n */\r\nexport const logger = new Logger();\r\n","/**\r\n * Command Builder - fluent API for building commands\r\n */\r\n\r\nimport type { Command } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\n\r\nexport class CommandBuilder {\r\n private name: string = '';\r\n private description: string = '';\r\n private usage?: string;\r\n private handler?: (context: CommandContext) => void | Promise<void>;\r\n\r\n /**\r\n * Set the command name\r\n */\r\n setName(name: string): this {\r\n this.name = name;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command description\r\n */\r\n setDescription(description: string): this {\r\n this.description = description;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command usage example\r\n */\r\n setUsage(usage: string): this {\r\n this.usage = usage;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command handler\r\n */\r\n setHandler(handler: (context: CommandContext) => void | Promise<void>): this {\r\n this.handler = handler;\r\n return this;\r\n }\r\n\r\n /**\r\n * Build the command object\r\n */\r\n build(): Command {\r\n if (!this.name) {\r\n throw new Error('Command name is required');\r\n }\r\n if (!this.description) {\r\n throw new Error('Command description is required');\r\n }\r\n if (!this.handler) {\r\n throw new Error('Command handler is required');\r\n }\r\n\r\n return {\r\n name: this.name,\r\n description: this.description,\r\n usage: this.usage,\r\n handler: this.handler as any, // Cast to satisfy Command type\r\n };\r\n }\r\n}\r\n","/**\r\n * Custom error classes for the Chirp Bot SDK\r\n */\r\n\r\n/**\r\n * Base error class for all SDK errors\r\n */\r\nexport class ChirpError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'ChirpError';\r\n Error.captureStackTrace?.(this, this.constructor);\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends ChirpError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a rate limit is hit\r\n */\r\nexport class RateLimitError extends ChirpError {\r\n public readonly retryAfter: number;\r\n\r\n constructor(message: string, retryAfter: number = 0) {\r\n super(message);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a requested resource is not found\r\n */\r\nexport class NotFoundError extends ChirpError {\r\n constructor(message: string = 'Resource not found') {\r\n super(message);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the client lacks permission for an action\r\n */\r\nexport class PermissionError extends ChirpError {\r\n constructor(message: string = 'Insufficient permissions') {\r\n super(message);\r\n this.name = 'PermissionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a request is invalid\r\n */\r\nexport class ValidationError extends ChirpError {\r\n constructor(message: string = 'Validation failed') {\r\n super(message);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the WebSocket connection fails\r\n */\r\nexport class ConnectionError extends ChirpError {\r\n constructor(message: string = 'Connection failed') {\r\n super(message);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when command execution fails\r\n */\r\nexport class CommandError extends ChirpError {\r\n public readonly commandName: string;\r\n\r\n constructor(message: string, commandName: string) {\r\n super(message);\r\n this.name = 'CommandError';\r\n this.commandName = commandName;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmRa,iBAkDA;AArUb;AAAA;AAAA;AAmRO,IAAM,kBAA4B;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AA4CO,IAAM,aAAN,cAA+B,IAAU;AAAA,MAC9C,YAAY,SAA+C;AACzD,cAAM,OAAO;AAAA,MACf;AAAA,MAEO,IAAI,KAAuB;AAChC,eAAO,MAAM,IAAI,GAAG;AAAA,MACtB;AAAA,MAEO,IAAI,KAAQ,OAAgB;AACjC,eAAO,MAAM,IAAI,KAAK,KAAK;AAAA,MAC7B;AAAA,MAEO,KAAK,WAAyD;AACnE,mBAAW,CAAC,KAAK,KAAK,KAAK,MAAM;AAC/B,cAAI,UAAU,OAAO,GAAG,GAAG;AACzB,mBAAO;AAAA,UACT;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MAEO,OAAO,WAA+C;AAC3D,cAAM,SAAc,CAAC;AACrB,mBAAW,CAAC,KAAK,KAAK,KAAK,MAAM;AAC/B,cAAI,UAAU,OAAO,GAAG,GAAG;AACzB,mBAAO,KAAK,KAAK;AAAA,UACnB;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MAEO,QAAuB;AAC5B,eAAO,KAAK,OAAO,EAAE,KAAK,EAAE;AAAA,MAC9B;AAAA,MAEO,OAAsB;AAC3B,YAAI;AACJ,mBAAW,SAAS,KAAK,OAAO,GAAG;AACjC,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;;;AC3WA,SAAS,UAAkB;;;ACWpB,IAAM,WAAN,cAAuB,MAAM;AAAA,EAC3B;AAAA,EACA;AAAA,EAEP,YAAY,SAAiB,YAAoB,MAAe;AAC9D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EAEjB,YAAY,SAAiB,OAAe;AAC1C,SAAK,UAAU;AACf,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QACZ,UACA,UAAuB,CAAC,GACZ;AACZ,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AACtC,UAAM,UAAuB;AAAA,MAC3B,iBAAiB,OAAO,KAAK,KAAK;AAAA,MAClC,gBAAgB;AAAA,MAChB,GAAG,QAAQ;AAAA,IACb;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,UAAM,SAAS,aAAa,SAAS,kBAAkB;AAEvD,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,eAAe,QAAQ,SAAS,MAAM;AAC1C,UAAI,QAAQ;AACV,YAAI;AACF,gBAAM,YAAY,MAAM,SAAS,KAAK;AACtC,yBAAe,UAAU,WAAW,UAAU,SAAS;AAAA,QACzD,QAAQ;AAAA,QAER;AAAA,MACF;AACA,YAAM,IAAI,SAAS,cAAc,SAAS,MAAM;AAAA,IAClD;AAEA,QAAI,UAAU,SAAS,WAAW,KAAK;AACrC,aAAO,SAAS,KAAK;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,IAAO,UAA8B;AACjD,WAAO,KAAK,QAAW,UAAU,EAAE,QAAQ,MAAM,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,KAAQ,UAAkB,MAA4B;AAClE,WAAO,KAAK,QAAW,UAAU;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,MAAS,UAAkB,MAA4B;AACnE,WAAO,KAAK,QAAW,UAAU;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,IAAO,UAAkB,MAA4B;AACjE,WAAO,KAAK,QAAW,UAAU;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,OAAU,UAA8B;AACpD,WAAO,KAAK,QAAW,UAAU,EAAE,QAAQ,SAAS,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAA4B;AAChC,WAAO,KAAK,IAAU,cAAc;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAsC;AAC1C,WAAO,KAAK,IAAkB,iBAAiB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAgC;AACpC,WAAO,KAAK,IAAc,cAAc;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAA0C;AAC9C,WAAO,KAAK,IAAqB,yBAAyB;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,UAAsC;AACtD,WAAO,KAAK,IAAe,gBAAgB,QAAQ,WAAW;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,WACA,UAA6C,CAAC,GACT;AACrC,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,QAAQ,KAAM,QAAO,OAAO,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAC5D,QAAI,QAAQ,MAAO,QAAO,OAAO,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC/D,UAAM,QAAQ,OAAO,SAAS;AAE9B,QAAI,UAAU,WAAW,KAAK,GAAG;AAC/B,YAAM,aAAa,UAAU,UAAU,CAAC;AACxC,aAAO,KAAK;AAAA,QACV,YAAY,UAAU,YAAY,QAAQ,IAAI,KAAK,KAAK,EAAE;AAAA,MAC5D;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,iBAAiB,SAAS,YAAY,QAAQ,IAAI,KAAK,KAAK,EAAE;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACJ,WACA,SACA,UAA0B,CAAC,GACT;AAClB,UAAM,OAA4B;AAAA,MAChC;AAAA,MACA,SAAS,QAAQ;AAAA,IACnB;AACA,QAAI,QAAQ,UAAU;AACpB,WAAK,YAAY,QAAQ;AAAA,IAC3B;AAEA,QAAI,UAAU,WAAW,KAAK,GAAG;AAC/B,YAAM,aAAa,UAAU,UAAU,CAAC;AACxC,aAAO,KAAK,KAAc,YAAY,UAAU,aAAa,IAAI;AAAA,IACnE;AAEA,WAAO,KAAK,KAAc,iBAAiB,SAAS,aAAa,IAAI;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MACJ,WACA,WACA,SACA,QACA,iBACkB;AAClB,WAAO,KAAK,KAAc,iBAAiB,SAAS,aAAa;AAAA,MAC/D;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,WAAmB,SAAiB,WAAsC;AAC1F,QAAI,WAAW,WAAW,KAAK,GAAG;AAChC,aAAO,KAAK,MAAe,wBAAwB,SAAS,IAAI,EAAE,QAAQ,CAAC;AAAA,IAC7E;AACA,WAAO,KAAK,MAAe,iBAAiB,SAAS,IAAI,EAAE,QAAQ,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAmB,WAAmC;AACxE,QAAI,WAAW,WAAW,KAAK,GAAG;AAChC,aAAO,KAAK,OAAa,wBAAwB,SAAS,EAAE;AAAA,IAC9D;AACA,WAAO,KAAK,OAAa,iBAAiB,SAAS,EAAE;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,YAAqC;AACpD,WAAO,KAAK,KAAa,gCAAgC,EAAE,WAAW,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,UAAiC;AACjD,WAAO,KAAK,OAAa,2BAA2B,QAAQ,QAAQ;AAAA,EACtE;AACF;;;AC/PA,OAAO,kBAAkB;AAalB,IAAM,mBAAN,MAA4D;AAAA,EAChD;AAAA,EAEjB,cAAc;AACZ,SAAK,UAAU,IAAI,aAAa;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKO,GACL,OACA,UACM;AACN,SAAK,QAAQ,GAAG,OAAO,QAAe;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,KACL,OACA,UACM;AACN,SAAK,QAAQ,KAAK,OAAO,QAAe;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,IACL,OACA,UACM;AACN,SAAK,QAAQ,IAAI,OAAO,QAAe;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,KACL,UACG,MACM;AACT,WAAO,KAAK,QAAQ,KAAK,OAAO,GAAG,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKO,mBAAkD,OAAiB;AACxE,SAAK,QAAQ,mBAAmB,KAAK;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,cAA6C,OAAkB;AACpE,WAAO,KAAK,QAAQ,cAAc,KAAK;AAAA,EACzC;AACF;;;ACpEO,IAAM,iBAAN,MAAgD;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,MACA,SACA,SACA,QACA,KACA;AACA,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,MAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAAmC;AAC7C,WAAO,KAAK,IAAI,YAAY,KAAK,QAAQ,IAAI,SAAS;AAAA,MACpD,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,SAAmC;AAC5C,WAAO,KAAK,IAAI,YAAY,KAAK,QAAQ,IAAI,OAAO;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,WAAmB,SAAmC;AAC/D,WAAO,KAAK,IAAI,YAAY,WAAW,SAAS,KAAK,QAAQ,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,WAAkC;AAC7C,WAAO,KAAK,IAAI,cAAc,WAAW,KAAK,QAAQ,EAAE;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAqB;AACvB,WAAO,GAAG,KAAK,OAAO,GAAG,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,KAAK,GAAG,IAAI,EAAE;AAAA,EAC5E;AACF;;;AC/DO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EACA;AAAA,EACT;AAAA,EAER,YAAY,SAAiB,KAAK;AAChC,SAAK,WAAW,oBAAI,IAAI;AACxB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,QAAmC;AAC5C,SAAK,SAAS;AAAA,EAChB;AAAA,EAOA,SAAS,kBAAwD;AAC/D,UAAM,UACJ,WAAW,mBAAmB,iBAAiB,MAAM,IAAI;AAE3D,SAAK,SAAS,IAAI,QAAQ,MAAM,OAAO;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAoD;AAC/D,eAAW,oBAAoB,UAAU;AACvC,UAAI,WAAW,kBAAkB;AAC/B,aAAK,SAAS,gBAAgB;AAAA,MAChC,OAAO;AACL,aAAK,SAAS,gBAAgB;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAuB;AAChC,WAAO,KAAK,SAAS,OAAO,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAmC;AACrC,WAAO,KAAK,SAAS,IAAI,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAuB;AACzB,WAAO,KAAK,SAAS,IAAI,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,SAA+B;AAC7B,WAAO,IAAI,IAAI,KAAK,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAA8D;AAClE,UAAM,UAAU,QAAQ,QAAQ,KAAK;AAErC,QAAI,CAAC,QAAQ,WAAW,KAAK,MAAM,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,QAAQ,MAAM,KAAK,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;AAClE,UAAM,UAAU,MAAM,CAAC;AACvB,UAAM,OAAO,MAAM,MAAM,CAAC;AAE1B,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QACJ,aACA,MACA,SACA,SACA,QACA,KACe;AACf,UAAM,UAAU,KAAK,SAAS,IAAI,WAAW;AAE7C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,UAAU,IAAI;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,QAAQ,OAAO;AAAA,IAC/B,SAAS,OAAO;AAEd,UAAI,KAAK,QAAQ;AACf,aAAK,OAAO,KAAK,SAAS,KAAK;AAAA,MACjC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC3IO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EACD;AAAA,EAEhB,YAAY,KAAiB;AAC3B,SAAK,MAAM;AACX,SAAK,QAAS,KAAK,YAAsC,iBAAiB;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,mBAAwB;AACrC,UAAM,EAAE,YAAAA,YAAW,IAAI;AACvB,WAAO,IAAIA,YAAW;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,UAAsC;AAChD,UAAM,WAAW,MAAM,KAAK,IAAI,YAAY,QAAQ;AAGpD,eAAW,WAAW,UAAU;AAC9B,WAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAAA,IACpC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAwC;AAC1C,WAAO,KAAK,MAAM,IAAI,SAAS;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,UAAkB,MAAmC;AAC9D,WAAO,KAAK,MAAM;AAAA,MAChB,CAAC,YAAY,QAAQ,aAAa,YAAY,QAAQ,SAAS;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAwB;AAC1B,SAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAA4B;AACjC,WAAO,KAAK,MAAM,OAAO,SAAS;AAAA,EACpC;AACF;;;ACrEO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EACD;AAAA,EAEhB,YAAY,KAAiB;AAC3B,SAAK,MAAM;AACX,SAAK,QAAS,KAAK,YAAsC,iBAAiB;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,mBAAwB;AACrC,UAAM,EAAE,YAAAC,YAAW,IAAI;AACvB,WAAO,IAAIA,YAAW;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MACJ,WACA,UAA6C,CAAC,GACT;AACrC,UAAM,WAAW,MAAM,KAAK,IAAI,YAAY,WAAW,OAAO;AAG9D,eAAW,WAAW,SAAS,MAAM;AACnC,WAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAAA,IACpC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,WAAmB,SAAiB,SAA4C;AACzF,UAAM,UAAU,MAAM,KAAK,IAAI,YAAY,WAAW,SAAS,OAAO;AACtE,SAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MACJ,WACA,WACA,SACA,QACA,iBACkB;AAClB,UAAM,UAAU,MAAM,KAAK,IAAI;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,WAAmB,SAAmC;AAC/D,UAAM,UAAU,MAAM,KAAK,IAAI,YAAY,WAAW,OAAO;AAG7D,SAAK,MAAM,IAAI,WAAW,OAAO;AAEjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,WAAkC;AAC7C,UAAM,KAAK,IAAI,cAAc,SAAS;AACtC,SAAK,MAAM,OAAO,SAAS;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAwC;AAC1C,WAAO,KAAK,MAAM,IAAI,SAAS;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAwB;AAC1B,SAAK,MAAM,IAAI,QAAQ,IAAI,OAAO;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,WAA4B;AAC1C,WAAO,KAAK,MAAM,OAAO,SAAS;AAAA,EACpC;AACF;;;AC7HO,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EACD;AAAA,EAEhB,YAAY,KAAiB;AAC3B,SAAK,MAAM;AACX,SAAK,QAAS,KAAK,YAAqC,iBAAiB;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,mBAAwB;AACrC,UAAM,EAAE,YAAAC,YAAW,IAAI;AACvB,WAAO,IAAIA,YAAW;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAA2B;AAC/B,UAAM,UAAU,MAAM,KAAK,IAAI,WAAW;AAG1C,eAAW,UAAU,SAAS;AAC5B,WAAK,MAAM,IAAI,OAAO,IAAI,MAAM;AAAA,IAClC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAqC;AACzC,UAAM,aAAa,MAAM,KAAK,IAAI,cAAc;AAGhD,eAAW,aAAa,YAAY;AAClC,WAAK,MAAM,IAAI,UAAU,UAAU;AAAA,QACjC,IAAI,UAAU;AAAA,QACd,MAAM,UAAU;AAAA,QAChB,SAAS,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,WAAW,UAAU;AAAA,MACvB,CAAC;AAAA,IACH;AAEA,WAAO,WAAW,IAAI,CAAC,QAAa;AAAA,MAClC,IAAI,GAAG;AAAA,MACP,MAAM,GAAG;AAAA,MACT,SAAS,GAAG;AAAA,MACZ,SAAS;AAAA,MACT,WAAW,GAAG;AAAA,IAChB,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,YAAqC;AAC9C,UAAM,SAAS,MAAM,KAAK,IAAI,WAAW,UAAU;AACnD,SAAK,MAAM,IAAI,OAAO,IAAI,MAAM;AAChC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,UAAiC;AAC3C,UAAM,KAAK,IAAI,YAAY,QAAQ;AACnC,SAAK,MAAM,OAAO,QAAQ;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAsC;AACxC,WAAO,KAAK,MAAM,IAAI,QAAQ;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAkC;AAC3C,WAAO,KAAK,MAAM,KAAK,CAAC,WAAW,OAAO,SAAS,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,SAAqC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsB;AACxB,SAAK,MAAM,IAAI,OAAO,IAAI,MAAM;AAChC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAA2B;AAChC,WAAO,KAAK,MAAM,OAAO,QAAQ;AAAA,EACnC;AACF;;;ACtHO,SAAS,SAAS,OAAuB;AAC9C,SAAO,MACJ,QAAQ,aAAa,SAAS,EAC9B,QAAQ,cAAc,UAAU;AACrC;AAKO,SAAS,SAAS,SAAyB;AAChD,SAAO,QACJ,QAAQ,eAAe,OAAO,EAC9B,QAAQ,gBAAgB,QAAQ;AACrC;AAMO,SAAS,UAAU,OAAyB;AACjD,QAAM,OAAiB,CAAC;AACxB,MAAI,UAAU;AACd,MAAI,WAAW;AAEf,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAEpB,QAAI,SAAS,OAAO,SAAS,KAAK;AAChC,iBAAW,CAAC;AAAA,IACd,WAAW,SAAS,OAAO,CAAC,UAAU;AACpC,UAAI,SAAS;AACX,aAAK,KAAK,OAAO;AACjB,kBAAU;AAAA,MACZ;AAAA,IACF,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,MAAI,SAAS;AACX,SAAK,KAAK,OAAO;AAAA,EACnB;AAEA,SAAO;AACT;AAKO,SAAS,cAAc,QAAwB;AACpD,SAAO,KAAK,MAAM;AACpB;AAKO,SAAS,qBAAqB,WAA2B;AAC9D,SAAO,KAAK,SAAS;AACvB;AAKO,SAAS,kBAAkB,SAA2B;AAC3D,QAAM,eAAe;AACrB,QAAM,MAAgB,CAAC;AACvB,MAAI;AAEJ,UAAQ,QAAQ,aAAa,KAAK,OAAO,OAAO,MAAM;AACpD,QAAI,KAAK,MAAM,CAAC,CAAC;AAAA,EACnB;AAEA,SAAO;AACT;AAKO,SAAS,MAAM,IAA2B;AAC/C,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAKA,eAAsB,MACpB,IACA,UAKI,CAAC,GACO;AACZ,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,WAAW;AAAA,IACX,SAAS;AAAA,EACX,IAAI;AAEJ,MAAI,YAAY;AAChB,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,OAAO;AACd,kBAAY;AAEZ,UAAI,YAAY,aAAa;AAC3B,cAAM;AAAA,MACR;AAEA,YAAM,MAAM,SAAS;AACrB,kBAAY,KAAK,IAAI,YAAY,QAAQ,QAAQ;AAAA,IACnD;AAAA,EACF;AAEA,QAAM;AACR;;;AC3HO,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,oBAAA,WAAQ,KAAR;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,WAAQ,KAAR;AAJU,SAAAA;AAAA,GAAA;AAOL,IAAM,SAAN,MAAM,QAAO;AAAA,EACV;AAAA,EACA;AAAA,EAER,YAAY,SAAiB,YAAY,QAAkB,cAAe;AACxE,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,OAAuB;AAC9B,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAO,OAAe,YAAoB,MAAqB;AACrE,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,WAAO,IAAI,SAAS,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAoB,MAAmB;AAC3C,QAAI,KAAK,SAAS,eAAgB;AAChC,cAAQ,MAAM,KAAK,OAAO,SAAS,OAAO,GAAG,GAAG,IAAI;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,YAAoB,MAAmB;AAC1C,QAAI,KAAK,SAAS,cAAe;AAC/B,cAAQ,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG,GAAG,IAAI;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,YAAoB,MAAmB;AAC1C,QAAI,KAAK,SAAS,cAAe;AAC/B,cAAQ,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG,GAAG,IAAI;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAoB,MAAmB;AAC3C,QAAI,KAAK,SAAS,eAAgB;AAChC,cAAQ,MAAM,KAAK,OAAO,SAAS,OAAO,GAAG,GAAG,IAAI;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAwB;AAC5B,WAAO,IAAI,QAAO,GAAG,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK,KAAK;AAAA,EAC1D;AACF;AAKO,IAAM,SAAS,IAAI,OAAO;;;ATpDjC,IAAI;AAEJ,SAAS,gBAAqB;AAC5B,MAAI,CAAC,iBAAiB;AAEpB,UAAM,SAAS;AACf,sBAAkB,OAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAKO,IAAK,mBAAL,kBAAKC,sBAAL;AACL,EAAAA,kBAAA,kBAAe;AACf,EAAAA,kBAAA,gBAAa;AACb,EAAAA,kBAAA,eAAY;AACZ,EAAAA,kBAAA,kBAAe;AAJL,SAAAA;AAAA,GAAA;AAUL,IAAM,cAAN,cAA0B,iBAA8B;AAAA;AAAA;AAAA;AAAA,EAK7C;AAAA,EACA;AAAA,EACT;AAAA,EAEA,OAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAMC,QAAuB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA2B;AAAA,EAC3B,oBAA4B;AAAA,EAC5B,iBAAwC;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAY,UAA8B,CAAC,GAAG;AAC5C,UAAM;AAGN,SAAK,UAAU;AAAA,MACb,OAAO,QAAQ,SAAS;AAAA,MACxB,SAAS,QAAQ,WAAW;AAAA,MAC5B,OAAO,QAAQ,SAAS;AAAA,MACxB,eAAe,QAAQ,iBAAiB;AAAA,MACxC,SAAS,QAAQ,WAAW,CAAC,YAAY,kBAAkB,cAAc,UAAU,SAAS;AAAA,MAC5F,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,gBAAgB,QAAQ,kBAAkB;AAAA,IAC5C;AAGA,QAAI,CAAC,KAAK,QAAQ,SAAS;AACzB,WAAK,UAAU,SAAS,KAAK,QAAQ,KAAK;AAAA,IAC5C,OAAO;AACL,WAAK,UAAU,KAAK,QAAQ;AAAA,IAC9B;AACA,SAAK,QAAQ,KAAK,QAAQ;AAG1B,SAAK,MAAM,IAAI,OAAO,aAAa;AAInC,SAAK,MAAM,IAAI,WAAW,KAAK,SAAS,EAAE;AAG1C,SAAK,WAAW,IAAI,eAAe,KAAK,QAAQ,aAAa;AAG7D,UAAMC,cAAa,cAAc;AACjC,SAAK,UAAU,IAAIA,YAAW;AAC9B,SAAK,WAAW,IAAIA,YAAW;AAG/B,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAM,OAA+B;AACzC,QAAI,KAAK,WAAW,mCAA+B;AACjD,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAEA,SAAK,QAAQ,SAAS,KAAK,QAAQ;AACnC,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,MAAM,4DAA4D;AAAA,IAC9E;AAEA,SAAK,SAAS;AACd,SAAK,IAAI,KAAK,iBAAiB,KAAK,KAAK;AAEzC,QAAI;AAEF,WAAK,MAAM,IAAI,WAAW,KAAK,SAAS,KAAK,KAAK;AAGlD,WAAK,OAAO,MAAM,KAAK,IAAI,WAAW;AACtC,WAAK,IAAI,KAAK,oBAAoB,KAAK,KAAK,QAAQ,EAAE;AAGtD,WAAK,kBAAkB,IAAI,eAAe,KAAK,GAAG;AAClD,WAAK,kBAAkB,IAAI,eAAe,KAAK,GAAG;AAClD,WAAK,iBAAiB,IAAI,cAAc,KAAK,GAAG;AAGhD,WAAK,SAAS,WAAW,IAAI;AAG7B,YAAM,KAAK,iBAAiB;AAG5B,YAAM,KAAK,iBAAiB;AAE5B,WAAK,SAAS;AACd,WAAK,KAAK,OAAO;AACjB,WAAK,IAAI,KAAK,cAAc;AAAA,IAE9B,SAAS,OAAO;AACd,WAAK,SAAS;AACd,WAAK,IAAI,MAAM,iBAAiB,KAAK;AACrC,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAwB;AAC5B,SAAK,oBAAoB;AACzB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,IAAI,KAAK,YAAY;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK,WAAW,+BAA8B,KAAK,QAAQ,cAAc;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAAkC;AAC9C,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,eAAe,MAAM;AAChD,WAAK,IAAI,MAAM,WAAW,QAAQ,MAAM,UAAU;AAGlD,iBAAW,CAAC,UAAU,MAAM,KAAK,KAAK,eAAe,OAAO;AAC1D,aAAK,QAAQ,IAAI,UAAU,MAAM;AAAA,MACnC;AAGA,iBAAW,UAAU,SAAS;AAC5B,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,gBAAgB,MAAM,OAAO,EAAE;AAC3D,eAAK,IAAI,MAAM,WAAW,SAAS,MAAM,iBAAiB,OAAO,IAAI,EAAE;AAGvE,qBAAW,CAAC,WAAW,OAAO,KAAK,KAAK,gBAAgB,OAAO;AAC7D,iBAAK,SAAS,IAAI,WAAW,OAAO;AAAA,UACtC;AAAA,QACF,SAAS,OAAO;AACd,eAAK,IAAI,KAAK,gCAAgC,OAAO,IAAI,KAAK,KAAK;AAAA,QACrE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,WAAK,IAAI,KAAK,iCAAiC,KAAK;AAAA,IACtD;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,UAAM,WAAW,YAAY;AAC3B,YAAM,KAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,GAAG,UAAU,QAAQ;AAC7B,YAAQ,GAAG,WAAW,QAAQ;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAAkC;AAC9C,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,gBAAqB;AAAA,QACzB,MAAM,EAAE,OAAO,OAAO,KAAK,KAAK,GAAG;AAAA,QACnC,cAAc;AAAA;AAAA,QACd,YAAY,CAAC,WAAW;AAAA,MAC1B;AAEA,WAAK,SAAS,GAAG,KAAK,OAAO,aAAa;AAC1C,WAAK,KAAK,KAAK;AAGf,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,aAAK,IAAI,MAAM,qBAAqB;AACpC,aAAK,oBAAoB;AACzB,gBAAQ;AAAA,MACV,CAAC;AAGD,WAAK,OAAO,GAAG,iBAAiB,CAAC,UAAU;AACzC,aAAK,IAAI,MAAM,+BAA+B,KAAK;AACnD,aAAK,SAAS;AACd,eAAO,KAAK;AAAA,MACd,CAAC;AAGD,WAAK,OAAO,GAAG,cAAc,CAAC,WAAW;AACvC,aAAK,IAAI,KAAK,2BAA2B,MAAM;AAC/C,aAAK,SAAS;AACd,aAAK,KAAK,gBAAgB,MAAM;AAGhC,YAAI,WAAW,wBAAwB;AACrC,eAAK,kBAAkB;AAAA,QACzB;AAAA,MACF,CAAC;AAGD,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,qBAAqB,KAAK,QAAQ,mBAAmB;AAC5D,WAAK,IAAI,MAAM,gCAAgC;AAC/C,WAAK,KAAK,SAAS,IAAI,MAAM,gCAAgC,CAAC;AAC9D;AAAA,IACF;AAEA,SAAK,SAAS;AACd,SAAK;AAEL,UAAMC,SAAQ,KAAK,QAAQ,iBAAiB,KAAK,IAAI,KAAK,mBAAmB,EAAE;AAE/E,SAAK,IAAI,KAAK,mBAAmBA,MAAK,eAAe,KAAK,iBAAiB,GAAG;AAC9E,SAAK,KAAK,gBAAgB,KAAK,iBAAiB;AAEhD,SAAK,iBAAiB,WAAW,YAAY;AAC3C,UAAI;AACF,cAAM,KAAK,iBAAiB;AAC5B,aAAK,SAAS;AACd,aAAK,KAAK,eAAe,KAAK,iBAAiB;AAC/C,aAAK,IAAI,KAAK,0BAA0B;AAAA,MAC1C,SAAS,OAAO;AACd,aAAK,IAAI,MAAM,qBAAqB,KAAK;AACzC,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF,GAAGA,MAAK;AAAA,EACV;AAAA,EAEQ,sBAA4B;AAClC,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAA2B;AAEjC,SAAK,OAAO,GAAG,eAAe,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAC9D,SAAK,OAAO,GAAG,mBAAmB,KAAK,qBAAqB,KAAK,IAAI,CAAC;AACtE,SAAK,OAAO,GAAG,mBAAmB,KAAK,qBAAqB,KAAK,IAAI,CAAC;AACtE,SAAK,OAAO,GAAG,UAAU,KAAK,YAAY,KAAK,IAAI,CAAC;AAGpD,SAAK,OAAO,GAAG,eAAe,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAC9D,SAAK,OAAO,GAAG,gBAAgB,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAGhE,QAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,WAAK,OAAO,GAAG,cAAc,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,IAC9D;AAGA,QAAI,KAAK,UAAU,SAAS,GAAG;AAC7B,WAAK,OAAO,GAAG,mBAAmB,KAAK,qBAAqB,KAAK,IAAI,CAAC;AACtE,WAAK,OAAO,GAAG,sBAAsB,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAC7E;AAGA,QAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,WAAK,OAAO,GAAG,gBAAgB,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAChE,WAAK,OAAO,GAAG,cAAc,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,IAC9D;AAGA,SAAK,OAAO,GAAG,qBAAqB,KAAK,sBAAsB,KAAK,IAAI,CAAC;AACzE,SAAK,OAAO,GAAG,mBAAmB,KAAK,oBAAoB,KAAK,IAAI,CAAC;AAGrE,SAAK,OAAO,GAAG,sBAAsB,KAAK,wBAAwB,KAAK,IAAI,CAAC;AAAA,EAC9E;AAAA,EAEQ,UAAU,QAAyB;AACzC,WAAO,KAAK,QAAQ,QAAQ,SAAS,MAAM;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iBAAiB,MAA0B;AAGvD,UAAM,UAAU;AAChB,UAAM,YAAY,QAAQ;AAI1B,QAAI,QAAQ,QAAQ;AAClB;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,WAAW,CAAC,QAAQ,QAAQ,KAAK,GAAG;AAC/C;AAAA,IACF;AAGA,SAAK,gBAAgB,IAAI,OAAO;AAGhC,UAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,QAAI,CAAC,QAAS;AAGd,UAAM,SAAS,KAAK,SAAS,MAAM,OAAO;AAC1C,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,KAAK,SAAS;AAAA,UAClB,OAAO;AAAA,UACP,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF,SAAS,OAAO;AACd,aAAK,IAAI,MAAM,iCAAiC,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1E;AACA;AAAA,IACF;AAGA,SAAK,KAAK,eAAe,SAAS,SAAS;AAAA,EAC7C;AAAA,EAEA,MAAc,YAAY,MAA0B;AAClD,UAAM,UAAU;AAGhB,QAAI,QAAQ,QAAQ;AAClB;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,WAAW,CAAC,QAAQ,QAAQ,KAAK,GAAG;AAC/C;AAAA,IACF;AAIA,UAAM,YAAY,QAAQ,cAAc,KAAK,MAAM,KAAK,QAAQ,cAAc,QAAQ;AAEtF,QAAI,CAAC,UAAW;AAEhB,UAAM,cAAc,MAAM,SAAS;AAGnC,UAAM,YAAiB;AAAA,MACrB,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM,QAAQ,mBAAmB;AAAA,MACjC,UAAU;AAAA,MACV,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,aAAa;AAAA,IACf;AAGA,UAAM,SAAS,KAAK,SAAS,MAAM,OAAO;AAC1C,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,KAAK,SAAS;AAAA,UAClB,OAAO;AAAA,UACP,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF,SAAS,OAAO;AACd,aAAK,IAAI,MAAM,iCAAiC,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1E;AACA;AAAA,IACF;AAGA,SAAK,KAAK,eAAe,SAAS,WAAW;AAAA,EAC/C;AAAA,EAEQ,qBAAqB,MAMpB;AACP,UAAM,EAAE,WAAW,WAAW,SAAS,QAAQ,UAAU,IAAI;AAE7D,UAAM,gBAAgB,KAAK,gBAAgB,IAAI,SAAS;AACxD,QAAI,eAAe;AACjB,YAAM,iBAAiB;AAAA,QACrB,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd;AACA,WAAK,gBAAgB,MAAM,IAAI,WAAW,cAAc;AAAA,IAC1D;AACA,SAAK,KAAK,mBAAmB,WAAW,WAAW,IAAI;AAAA,EACzD;AAAA,EAEQ,qBAAqB,MAAsD;AACjF,UAAM,EAAE,WAAW,UAAU,IAAI;AACjC,SAAK,gBAAgB,gBAAgB,SAAS;AAC9C,SAAK,KAAK,mBAAmB,WAAW,SAAS;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,MAIhB;AACP,UAAM,EAAE,QAAQ,QAAQ,KAAK,IAAI;AACjC,SAAK,KAAK,eAAe,QAAQ,QAAQ,IAAI;AAAA,EAC/C;AAAA,EAEQ,kBAAkB,MAAmD;AAC3E,UAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,SAAK,KAAK,gBAAgB,QAAQ,SAAS;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgB,MAAkE;AACxF,UAAM,EAAE,QAAQ,QAAQ,SAAS,IAAI;AACrC,SAAK,KAAK,cAAc,QAAQ,QAAQ,QAAQ;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAAqB,MAAqD;AAChF,UAAM,EAAE,UAAU,UAAU,IAAI;AAChC,SAAK,KAAK,mBAAmB,UAAU,SAAS;AAAA,EAClD;AAAA,EAEQ,uBAAuB,MAAkD;AAC/E,UAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,SAAK,KAAK,sBAAsB,UAAU,MAAM;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,MAIjB;AACP,UAAM,EAAE,QAAQ,WAAW,SAAS,IAAI;AACxC,SAAK,KAAK,gBAAgB,QAAQ,WAAW,QAAQ;AAAA,EACvD;AAAA,EAEQ,gBAAgB,MAIf;AACP,UAAM,EAAE,QAAQ,WAAW,SAAS,IAAI;AACxC,SAAK,KAAK,cAAc,QAAQ,WAAW,QAAQ;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAAsB,MAA+E;AAC3G,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,WAAW,OAAO;AACxB,UAAM,aAAa,OAAO;AAC1B,SAAK,IAAI,KAAK,kBAAkB,UAAU,EAAE;AAC5C,SAAK,KAAK,qBAAqB,UAAU,UAAU;AAInD,UAAM,aAAqB;AAAA,MACzB,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,SAAS,OAAO;AAAA,MAChB,SAAS;AAAA;AAAA,MACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA;AAAA,IACpC;AACA,SAAK,QAAQ,IAAI,UAAU,UAAU;AAGrC,SAAK,gBAAgB,MAAM,QAAQ,EAChC,KAAK,CAAC,aAAa;AAElB,iBAAW,CAAC,WAAW,OAAO,KAAK,KAAK,gBAAgB,OAAO;AAC7D,aAAK,SAAS,IAAI,WAAW,OAAO;AAAA,MACtC;AAAA,IACF,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,WAAK,IAAI,KAAK,gCAAgC,UAAU,KAAK,KAAK;AAAA,IACpE,CAAC;AAAA,EACL;AAAA,EAEQ,oBAAoB,MAAsD;AAChF,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,WAAW,OAAO;AACxB,UAAM,aAAa,OAAO;AAC1B,SAAK,IAAI,KAAK,gBAAgB,UAAU,EAAE;AAC1C,SAAK,KAAK,mBAAmB,UAAU,UAAU;AAGjD,SAAK,QAAQ,OAAO,QAAQ;AAG5B,eAAW,CAAC,WAAW,OAAO,KAAK,KAAK,UAAU;AAChD,UAAI,QAAQ,aAAa,UAAU;AACjC,aAAK,SAAS,OAAO,SAAS;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMQ,wBAAwB,MAKvB;AACP,SAAK,KAAK,sBAAsB,IAAI;AAAA,EACtC;AACF;;;AUrnBO,IAAM,iBAAN,MAAqB;AAAA,EAClB,OAAe;AAAA,EACf,cAAsB;AAAA,EACtB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAKR,QAAQ,MAAoB;AAC1B,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,aAA2B;AACxC,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,OAAqB;AAC5B,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,SAAkE;AAC3E,SAAK,UAAU;AACf,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAiB;AACf,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AAEA,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA;AAAA,IAChB;AAAA,EACF;AACF;;;AC3DO,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,UAAM,oBAAoB,MAAM,KAAK,WAAW;AAAA,EAClD;AACF;AAKO,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAClD,YAAY,UAAkB,yBAAyB;AACrD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAC7B;AAAA,EAEhB,YAAY,SAAiB,aAAqB,GAAG;AACnD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAKO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAC5C,YAAY,UAAkB,sBAAsB;AAClD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAC9C,YAAY,UAAkB,4BAA4B;AACxD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAC9C,YAAY,UAAkB,qBAAqB;AACjD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAC9C,YAAY,UAAkB,qBAAqB;AACjD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,eAAN,cAA2B,WAAW;AAAA,EAC3B;AAAA,EAEhB,YAAY,SAAiB,aAAqB;AAChD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,cAAc;AAAA,EACrB;AACF;","names":["Collection","Collection","Collection","LogLevel","ConnectionStatus","Collection","delay"]}
|