@chirp-dev/chirp-sdk 1.4.0 → 1.5.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.d.ts CHANGED
@@ -187,6 +187,11 @@ interface RESTClient$1 {
187
187
  reply(channelId: string, messageId: string, content: string, author: string, originalContent: string): Promise<Message>;
188
188
  editMessage(messageId: string, content: string): Promise<Message>;
189
189
  deleteMessage(messageId: string): Promise<void>;
190
+ bulkDelete(channelId: string, messageId: string, count: number): Promise<{
191
+ success: boolean;
192
+ deletedCount: number;
193
+ deletedIds: string[];
194
+ }>;
190
195
  joinServer(inviteCode: string): Promise<Server>;
191
196
  leaveServer(serverId: string): Promise<void>;
192
197
  }
@@ -281,6 +286,15 @@ declare class RESTClient {
281
286
  * Delete a message (only works for bot's own messages)
282
287
  */
283
288
  deleteMessage(messageId: string, channelId?: string): Promise<void>;
289
+ /**
290
+ * Bulk delete messages in a channel (bot-only, max 100).
291
+ * Deletes the anchor message and up to count-1 messages before it.
292
+ */
293
+ bulkDelete(channelId: string, messageId: string, count: number): Promise<{
294
+ success: boolean;
295
+ deletedCount: number;
296
+ deletedIds: string[];
297
+ }>;
284
298
  /**
285
299
  * Join a server via invite code
286
300
  */
@@ -526,6 +540,14 @@ declare class MessageManager {
526
540
  * Delete a message
527
541
  */
528
542
  delete(messageId: string): Promise<void>;
543
+ /**
544
+ * Bulk delete messages in a channel (bot-only, max 100).
545
+ * Deletes the anchor message and up to count-1 messages before it.
546
+ */
547
+ bulkDelete(channelId: string, messageId: string, count: number): Promise<{
548
+ deletedCount: number;
549
+ deletedIds: string[];
550
+ }>;
529
551
  /**
530
552
  * Get a message from cache by ID
531
553
  */
@@ -717,6 +739,14 @@ declare class CommandContext implements CommandContext$1 {
717
739
  * Delete a message
718
740
  */
719
741
  delete(messageId: string): Promise<void>;
742
+ /**
743
+ * Bulk delete messages (bot-only, server channels only, max 100).
744
+ * Deletes the anchor message and up to count-1 messages before it.
745
+ */
746
+ bulkDelete(messageId: string, count: number): Promise<{
747
+ deletedCount: number;
748
+ deletedIds: string[];
749
+ }>;
720
750
  /**
721
751
  * Get the raw command string
722
752
  */
package/dist/index.js CHANGED
@@ -101,7 +101,7 @@ var RESTClient = class {
101
101
  /**
102
102
  * Make an authenticated API request
103
103
  */
104
- async request(endpoint, options = {}) {
104
+ async request(endpoint, options = {}, _retried = false) {
105
105
  const url = `${this.baseUrl}${endpoint}`;
106
106
  const isFormData = options.body instanceof FormData;
107
107
  const headers = {
@@ -118,14 +118,22 @@ var RESTClient = class {
118
118
  const isJson = contentType?.includes("application/json");
119
119
  if (!response.ok) {
120
120
  let errorMessage = `HTTP ${response.status}`;
121
+ let errorCode;
122
+ let retryAfter = 0;
121
123
  if (isJson) {
122
124
  try {
123
125
  const errorData = await response.json();
124
126
  errorMessage = errorData.message || errorData.error || errorMessage;
127
+ errorCode = errorData.code;
128
+ retryAfter = errorData.retryAfter || 0;
125
129
  } catch {
126
130
  }
127
131
  }
128
- throw new APIError(errorMessage, response.status);
132
+ if (response.status === 429 && errorCode === "BOT_RATE_LIMITED" && !_retried && retryAfter > 0) {
133
+ await new Promise((resolve) => setTimeout(resolve, retryAfter));
134
+ return this.request(endpoint, options, true);
135
+ }
136
+ throw new APIError(errorMessage, response.status, errorCode);
129
137
  }
130
138
  if (isJson && response.status !== 204) {
131
139
  return response.json();
@@ -281,6 +289,13 @@ var RESTClient = class {
281
289
  }
282
290
  return this.delete(`/api/messages/${messageId}`);
283
291
  }
292
+ /**
293
+ * Bulk delete messages in a channel (bot-only, max 100).
294
+ * Deletes the anchor message and up to count-1 messages before it.
295
+ */
296
+ async bulkDelete(channelId, messageId, count) {
297
+ return this.post(`/api/channels/${channelId}/messages/bulk-delete`, { messageId, count });
298
+ }
284
299
  /**
285
300
  * Join a server via invite code
286
301
  */
@@ -390,6 +405,13 @@ var CommandContext = class {
390
405
  async delete(messageId) {
391
406
  return this.api.deleteMessage(messageId, this.channel.id);
392
407
  }
408
+ /**
409
+ * Bulk delete messages (bot-only, server channels only, max 100).
410
+ * Deletes the anchor message and up to count-1 messages before it.
411
+ */
412
+ async bulkDelete(messageId, count) {
413
+ return this.api.bulkDelete(this.channel.id, messageId, count);
414
+ }
393
415
  /**
394
416
  * Get the raw command string
395
417
  */
@@ -632,6 +654,17 @@ var MessageManager = class {
632
654
  await this.api.deleteMessage(messageId);
633
655
  this.cache.delete(messageId);
634
656
  }
657
+ /**
658
+ * Bulk delete messages in a channel (bot-only, max 100).
659
+ * Deletes the anchor message and up to count-1 messages before it.
660
+ */
661
+ async bulkDelete(channelId, messageId, count) {
662
+ const result = await this.api.bulkDelete(channelId, messageId, count);
663
+ for (const id of result.deletedIds) {
664
+ this.cache.delete(id);
665
+ }
666
+ return result;
667
+ }
635
668
  /**
636
669
  * Get a message from cache by ID
637
670
  */
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?: MessageOptions): 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 raw = data;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n if (raw.bot_id || raw.is_bot) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!raw.content || !raw.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 = raw.sender_id === this.user?.id ? raw.receiver_id : raw.sender_id;\r\n\r\n if (!partnerId) return;\r\n\r\n const dmChannelId = `dm-${partnerId}`;\r\n\r\n // Normalize DM fields to match the Message interface\r\n const message = {\r\n ...raw,\r\n channel_id: dmChannelId,\r\n author: raw.sender_username || 'Unknown',\r\n username: raw.sender_username || 'Unknown',\r\n user_id: raw.sender_id,\r\n avatar_url: raw.sender_avatar_url || null,\r\n };\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: raw.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 isFormData = options.body instanceof FormData;\r\n const headers: HeadersInit = {\r\n 'Authorization': `Bot ${this.token}`,\r\n // Let the browser/runtime set Content-Type for FormData (includes boundary)\r\n ...(isFormData ? {} : { '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 endpoint = channelId.startsWith('dm-')\r\n ? `/api/dms/${channelId.substring(3)}/messages`\r\n : `/api/channels/${channelId}/messages`;\r\n\r\n // Use FormData when attachments are present\r\n if (options.attachments?.length) {\r\n const formData = new FormData();\r\n formData.append('content', content);\r\n if (options.replyTo) {\r\n formData.append('replyTo', options.replyTo);\r\n }\r\n if (options.pollData) {\r\n formData.append('poll_data', JSON.stringify(options.pollData));\r\n }\r\n for (let i = 0; i < options.attachments.length; i++) {\r\n const att = options.attachments[i];\r\n const blob = att.file instanceof Blob\r\n ? att.file\r\n : new Blob([new Uint8Array(att.file)], { type: att.mimeType || 'application/octet-stream' });\r\n formData.append(`attachment${i}`, blob, att.fileName);\r\n }\r\n return this.request<Message>(endpoint, { method: 'POST', body: formData });\r\n }\r\n\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 return this.post<Message>(endpoint, 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 const body = { content, replyTo: messageId };\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 * 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, MessageOptions, 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, options?: Omit<MessageOptions, 'replyTo'>): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, {\r\n ...options,\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, options?: MessageOptions): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, options);\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?: MessageOptions): 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 bulkDelete(channelId: string, messageId: string, count: number): Promise<{ success: boolean; deletedCount: number; deletedIds: string[] }>;\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 raw = data;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n if (raw.bot_id || raw.is_bot) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!raw.content || !raw.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 = raw.sender_id === this.user?.id ? raw.receiver_id : raw.sender_id;\r\n\r\n if (!partnerId) return;\r\n\r\n const dmChannelId = `dm-${partnerId}`;\r\n\r\n // Normalize DM fields to match the Message interface\r\n const message = {\r\n ...raw,\r\n channel_id: dmChannelId,\r\n author: raw.sender_username || 'Unknown',\r\n username: raw.sender_username || 'Unknown',\r\n user_id: raw.sender_id,\r\n avatar_url: raw.sender_avatar_url || null,\r\n };\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: raw.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 _retried = false\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n const isFormData = options.body instanceof FormData;\r\n const headers: HeadersInit = {\r\n 'Authorization': `Bot ${this.token}`,\r\n // Let the browser/runtime set Content-Type for FormData (includes boundary)\r\n ...(isFormData ? {} : { '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 let errorCode: string | undefined;\r\n let retryAfter = 0;\r\n\r\n if (isJson) {\r\n try {\r\n const errorData = await response.json();\r\n errorMessage = errorData.message || errorData.error || errorMessage;\r\n errorCode = errorData.code;\r\n retryAfter = errorData.retryAfter || 0;\r\n } catch {\r\n // Use default error message\r\n }\r\n }\r\n\r\n // Auto-retry once on bot rate limit\r\n if (response.status === 429 && errorCode === 'BOT_RATE_LIMITED' && !_retried && retryAfter > 0) {\r\n await new Promise((resolve) => setTimeout(resolve, retryAfter));\r\n return this.request<T>(endpoint, options, true);\r\n }\r\n\r\n throw new APIError(errorMessage, response.status, errorCode);\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 endpoint = channelId.startsWith('dm-')\r\n ? `/api/dms/${channelId.substring(3)}/messages`\r\n : `/api/channels/${channelId}/messages`;\r\n\r\n // Use FormData when attachments are present\r\n if (options.attachments?.length) {\r\n const formData = new FormData();\r\n formData.append('content', content);\r\n if (options.replyTo) {\r\n formData.append('replyTo', options.replyTo);\r\n }\r\n if (options.pollData) {\r\n formData.append('poll_data', JSON.stringify(options.pollData));\r\n }\r\n for (let i = 0; i < options.attachments.length; i++) {\r\n const att = options.attachments[i];\r\n const blob = att.file instanceof Blob\r\n ? att.file\r\n : new Blob([new Uint8Array(att.file)], { type: att.mimeType || 'application/octet-stream' });\r\n formData.append(`attachment${i}`, blob, att.fileName);\r\n }\r\n return this.request<Message>(endpoint, { method: 'POST', body: formData });\r\n }\r\n\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 return this.post<Message>(endpoint, 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 const body = { content, replyTo: messageId };\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 * 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 * Bulk delete messages in a channel (bot-only, max 100).\r\n * Deletes the anchor message and up to count-1 messages before it.\r\n */\r\n async bulkDelete(\r\n channelId: string,\r\n messageId: string,\r\n count: number\r\n ): Promise<{ success: boolean; deletedCount: number; deletedIds: string[] }> {\r\n return this.post(`/api/channels/${channelId}/messages/bulk-delete`, { messageId, count });\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, MessageOptions, 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, options?: Omit<MessageOptions, 'replyTo'>): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, {\r\n ...options,\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, options?: MessageOptions): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, options);\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 * Bulk delete messages (bot-only, server channels only, max 100).\r\n * Deletes the anchor message and up to count-1 messages before it.\r\n */\r\n async bulkDelete(messageId: string, count: number): Promise<{ deletedCount: number; deletedIds: string[] }> {\r\n return this.api.bulkDelete(this.channel.id, messageId, count);\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 * Bulk delete messages in a channel (bot-only, max 100).\r\n * Deletes the anchor message and up to count-1 messages before it.\r\n */\r\n async bulkDelete(\r\n channelId: string,\r\n messageId: string,\r\n count: number\r\n ): Promise<{ deletedCount: number; deletedIds: string[] }> {\r\n const result = await this.api.bulkDelete(channelId, messageId, count);\r\n for (const id of result.deletedIds) {\r\n this.cache.delete(id);\r\n }\r\n return result;\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chirp-dev/chirp-sdk",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Official SDK for building Chirp bots",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",