@chirp-dev/chirp-sdk 1.3.0 → 1.4.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/README.md CHANGED
File without changes
package/dist/index.d.ts CHANGED
@@ -183,9 +183,7 @@ interface RESTClient$1 {
183
183
  page?: number;
184
184
  limit?: number;
185
185
  }): Promise<PaginatedResponse<Message>>;
186
- sendMessage(channelId: string, content: string, options?: {
187
- replyTo?: string;
188
- }): Promise<Message>;
186
+ sendMessage(channelId: string, content: string, options?: MessageOptions): Promise<Message>;
189
187
  reply(channelId: string, messageId: string, content: string, author: string, originalContent: string): Promise<Message>;
190
188
  editMessage(messageId: string, content: string): Promise<Message>;
191
189
  deleteMessage(messageId: string): Promise<void>;
@@ -703,11 +701,11 @@ declare class CommandContext implements CommandContext$1 {
703
701
  /**
704
702
  * Reply to the command message
705
703
  */
706
- reply(content: string): Promise<Message>;
704
+ reply(content: string, options?: Omit<MessageOptions, 'replyTo'>): Promise<Message>;
707
705
  /**
708
706
  * Send a message to the same channel
709
707
  */
710
- send(content: string): Promise<Message>;
708
+ send(content: string, options?: MessageOptions): Promise<Message>;
711
709
  /**
712
710
  * Edit the bot's response message
713
711
  */
package/dist/index.js CHANGED
@@ -103,9 +103,11 @@ var RESTClient = class {
103
103
  */
104
104
  async request(endpoint, options = {}) {
105
105
  const url = `${this.baseUrl}${endpoint}`;
106
+ const isFormData = options.body instanceof FormData;
106
107
  const headers = {
107
108
  "Authorization": `Bot ${this.token}`,
108
- "Content-Type": "application/json",
109
+ // Let the browser/runtime set Content-Type for FormData (includes boundary)
110
+ ...isFormData ? {} : { "Content-Type": "application/json" },
109
111
  ...options.headers
110
112
  };
111
113
  const response = await fetch(url, {
@@ -224,6 +226,23 @@ var RESTClient = class {
224
226
  * Send a message to a channel
225
227
  */
226
228
  async sendMessage(channelId, content, options = {}) {
229
+ const endpoint = channelId.startsWith("dm-") ? `/api/dms/${channelId.substring(3)}/messages` : `/api/channels/${channelId}/messages`;
230
+ if (options.attachments?.length) {
231
+ const formData = new FormData();
232
+ formData.append("content", content);
233
+ if (options.replyTo) {
234
+ formData.append("replyTo", options.replyTo);
235
+ }
236
+ if (options.pollData) {
237
+ formData.append("poll_data", JSON.stringify(options.pollData));
238
+ }
239
+ for (let i = 0; i < options.attachments.length; i++) {
240
+ const att = options.attachments[i];
241
+ const blob = att.file instanceof Blob ? att.file : new Blob([new Uint8Array(att.file)], { type: att.mimeType || "application/octet-stream" });
242
+ formData.append(`attachment${i}`, blob, att.fileName);
243
+ }
244
+ return this.request(endpoint, { method: "POST", body: formData });
245
+ }
227
246
  const body = {
228
247
  content,
229
248
  replyTo: options.replyTo
@@ -231,20 +250,18 @@ var RESTClient = class {
231
250
  if (options.pollData) {
232
251
  body.poll_data = options.pollData;
233
252
  }
234
- if (channelId.startsWith("dm-")) {
235
- const receiverId = channelId.substring(3);
236
- return this.post(`/api/dms/${receiverId}/messages`, body);
237
- }
238
- return this.post(`/api/channels/${channelId}/messages`, body);
253
+ return this.post(endpoint, body);
239
254
  }
240
255
  /**
241
256
  * Reply to a specific message
242
257
  */
243
258
  async reply(channelId, messageId, content, author, originalContent) {
244
- return this.post(`/api/channels/${channelId}/messages`, {
245
- content,
246
- replyTo: messageId
247
- });
259
+ const body = { content, replyTo: messageId };
260
+ if (channelId.startsWith("dm-")) {
261
+ const receiverId = channelId.substring(3);
262
+ return this.post(`/api/dms/${receiverId}/messages`, body);
263
+ }
264
+ return this.post(`/api/channels/${channelId}/messages`, body);
248
265
  }
249
266
  /**
250
267
  * Edit a message (only works for bot's own messages)
@@ -346,16 +363,17 @@ var CommandContext = class {
346
363
  /**
347
364
  * Reply to the command message
348
365
  */
349
- async reply(content) {
366
+ async reply(content, options) {
350
367
  return this.api.sendMessage(this.channel.id, content, {
368
+ ...options,
351
369
  replyTo: this.message.id
352
370
  });
353
371
  }
354
372
  /**
355
373
  * Send a message to the same channel
356
374
  */
357
- async send(content) {
358
- return this.api.sendMessage(this.channel.id, content);
375
+ async send(content, options) {
376
+ return this.api.sendMessage(this.channel.id, content, options);
359
377
  }
360
378
  /**
361
379
  * Edit the bot's response message
@@ -1172,20 +1190,28 @@ var ChirpClient = class extends SafeEventEmitter {
1172
1190
  this.emit("message:new", message, channelId);
1173
1191
  }
1174
1192
  async handleDMNew(data) {
1175
- const message = data;
1176
- if (message.bot_id) {
1193
+ const raw = data;
1194
+ if (raw.bot_id || raw.is_bot) {
1177
1195
  return;
1178
1196
  }
1179
- if (!message.content || !message.content.trim()) {
1197
+ if (!raw.content || !raw.content.trim()) {
1180
1198
  return;
1181
1199
  }
1182
- const partnerId = message.sender_id === this.user?.id ? message.receiver_id : message.sender_id;
1200
+ const partnerId = raw.sender_id === this.user?.id ? raw.receiver_id : raw.sender_id;
1183
1201
  if (!partnerId) return;
1184
1202
  const dmChannelId = `dm-${partnerId}`;
1203
+ const message = {
1204
+ ...raw,
1205
+ channel_id: dmChannelId,
1206
+ author: raw.sender_username || "Unknown",
1207
+ username: raw.sender_username || "Unknown",
1208
+ user_id: raw.sender_id,
1209
+ avatar_url: raw.sender_avatar_url || null
1210
+ };
1185
1211
  const dmChannel = {
1186
1212
  id: dmChannelId,
1187
1213
  type: "dm",
1188
- name: message.sender_username || "DM",
1214
+ name: raw.sender_username || "DM",
1189
1215
  serverId: null,
1190
1216
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1191
1217
  recipientId: partnerId
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/types.ts","../src/client/ChirpClient.ts","../src/api/REST.ts","../src/client/events/EventEmitter.ts","../src/commands/CommandContext.ts","../src/commands/CommandManager.ts","../src/client/managers/ChannelManager.ts","../src/client/managers/MessageManager.ts","../src/client/managers/ServerManager.ts","../src/util/helpers.ts","../src/util/logger.ts","../src/commands/CommandBuilder.ts","../src/errors/index.ts"],"sourcesContent":["/**\r\n * Core API types for the Chirp Bot SDK\r\n * Based on the Chirp REST API and WebSocket events\r\n */\r\n\r\n// ============================================================================\r\n// User Types\r\n// ============================================================================\r\n\r\nexport interface User {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n isBot: true;\r\n botTokenId: string;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialUser {\r\n id: string;\r\n username: string;\r\n displayName: string;\r\n avatarUrl: string | null;\r\n status?: string;\r\n isBot?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// Server Types\r\n// ============================================================================\r\n\r\nexport interface Server {\r\n id: string;\r\n name: string;\r\n iconUrl: string | null;\r\n ownerId: string;\r\n createdAt: string;\r\n memberCount?: number;\r\n}\r\n\r\nexport interface ServerMember {\r\n serverId: string;\r\n userId: string;\r\n roles: string[];\r\n joinedAt: string;\r\n user: PartialUser;\r\n}\r\n\r\n// ============================================================================\r\n// Channel Types\r\n// ============================================================================\r\n\r\nexport interface Channel {\r\n id: string;\r\n serverId: string;\r\n name: string;\r\n type: 'text' | 'voice' | 'media' | 'forum';\r\n parentId: string | null;\r\n position: number;\r\n permissions?: Record<string, boolean>;\r\n createdAt: string;\r\n}\r\n\r\nexport interface PartialChannel {\r\n id: string;\r\n name: string;\r\n type: string;\r\n serverId?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Message Types\r\n// ============================================================================\r\n\r\nexport interface Message {\r\n id: string;\r\n // Server uses snake_case for channel_id\r\n channel_id: string;\r\n // Server sends author as string (username) for backward compatibility\r\n // Also sends username as the same value\r\n author: string;\r\n username: string;\r\n avatar_url: string | null;\r\n // User info for bots\r\n bot_id?: string;\r\n user_id?: string;\r\n content: string;\r\n // Server uses snake_case for these fields\r\n created_at: string;\r\n updated_at?: string;\r\n edited?: boolean;\r\n edited_at?: string;\r\n // Reply info (server uses snake_case)\r\n replying_to_id?: string;\r\n replying_to_author?: string;\r\n replying_to_content?: string;\r\n replyingTo?: MessageReply;\r\n reactions?: Reaction[];\r\n attachments?: Attachment[];\r\n // Server compatibility fields\r\n is_bot?: boolean;\r\n authorAvatar?: string | null;\r\n server_id?: string;\r\n everyone_ping?: boolean;\r\n // CamelCase aliases (added by SDK for convenience)\r\n channelId?: string; // Alias for channel_id\r\n createdAt?: string; // Alias for created_at\r\n updatedAt?: string; // Alias for updated_at\r\n isEdited?: boolean; // Alias for edited\r\n}\r\n\r\nexport interface MessageReply {\r\n id: string;\r\n content: string;\r\n author: string; // Server sends author as string (username), not object\r\n}\r\n\r\nexport interface Reaction {\r\n id: string;\r\n messageId: string;\r\n userId: string;\r\n emoji: string;\r\n customEmojiId: string | null;\r\n createdAt: string;\r\n}\r\n\r\nexport interface Attachment {\r\n id: string;\r\n messageId: string;\r\n fileName: string;\r\n fileSize: number;\r\n mimeType: string;\r\n url: string;\r\n thumbnailUrl?: string;\r\n width?: number;\r\n height?: number;\r\n}\r\n\r\nexport interface PollData {\r\n question: string;\r\n options: string[];\r\n allowMultipleVotes?: boolean;\r\n expiresAt?: string | null;\r\n}\r\n\r\nexport interface MessageOptions {\r\n replyTo?: string;\r\n pollData?: PollData;\r\n attachments?: Array<{\r\n fileName: string;\r\n file: Blob | Buffer;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\n// ============================================================================\r\n// Bot Token Types\r\n// ============================================================================\r\n\r\nexport interface BotTokenInfo {\r\n id: string;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n userId: string;\r\n createdAt: string;\r\n lastUsedAt: string | null;\r\n}\r\n\r\nexport interface BotServerInfo {\r\n serverId: string;\r\n serverName: string;\r\n serverIconUrl: string | null;\r\n botUsername: string;\r\n botAvatarUrl: string | null;\r\n joinedAt: string;\r\n}\r\n\r\n// ============================================================================\r\n// API Response Types\r\n// ============================================================================\r\n\r\nexport interface PaginatedResponse<T> {\r\n data: T[];\r\n pagination: {\r\n page: number;\r\n limit: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n}\r\n\r\nexport interface APIError {\r\n message: string;\r\n statusCode: number;\r\n code?: string;\r\n}\r\n\r\n// ============================================================================\r\n// WebSocket Event Types\r\n// ============================================================================\r\n\r\nexport interface MessageNewEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageUpdatedEvent {\r\n message: Message;\r\n channelId: string;\r\n}\r\n\r\nexport interface MessageDeletedEvent {\r\n messageId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface UserStatusEvent {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n}\r\n\r\nexport interface TypingStartEvent {\r\n userId: string;\r\n channelId: string;\r\n}\r\n\r\nexport interface PollVotedEvent {\r\n pollId: string;\r\n userId: string;\r\n optionId: string;\r\n}\r\n\r\nexport interface VoiceEvent {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n}\r\n\r\nexport interface BotServerJoinedEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\nexport interface BotServerLeftEvent {\r\n serverId: string;\r\n serverName: string;\r\n}\r\n\r\n// ============================================================================\r\n// Client Options Types\r\n// ============================================================================\r\n\r\nexport interface ChirpClientOptions {\r\n token?: string;\r\n baseUrl?: string;\r\n wsUrl?: string;\r\n commandPrefix?: string;\r\n intents?: Intent[];\r\n reconnectAttempts?: number;\r\n reconnectDelay?: number;\r\n}\r\n\r\nexport type Intent =\r\n | 'messages'\r\n | 'messageUpdates'\r\n | 'userStatus'\r\n | 'typing'\r\n | 'voice'\r\n | 'polls'\r\n | 'threads'\r\n | 'servers';\r\n\r\nexport const DEFAULT_INTENTS: Intent[] = [\r\n 'messages',\r\n 'messageUpdates',\r\n 'userStatus',\r\n 'typing',\r\n 'servers',\r\n];\r\n\r\n// ============================================================================\r\n// Command Types\r\n// ============================================================================\r\n\r\nexport interface Command {\r\n name: string;\r\n description: string;\r\n usage?: string;\r\n handler: (context: CommandContext) => void | Promise<void>;\r\n}\r\n\r\nexport interface CommandContext {\r\n command: string;\r\n args: string[];\r\n message: Message;\r\n channel: Channel;\r\n client: any; // ChirpClient - avoid circular reference\r\n api: any; // RESTClient - avoid circular reference\r\n}\r\n\r\n// ============================================================================\r\n// REST Client Type (forward declaration)\r\n// ============================================================================\r\n\r\nexport interface RESTClient {\r\n getBotInfo(): Promise<User>;\r\n getServers(): Promise<Server[]>;\r\n getBotServers(): Promise<BotServerInfo[]>;\r\n getChannels(serverId: string): Promise<Channel[]>;\r\n getMessages(channelId: string, options?: { page?: number; limit?: number }): Promise<PaginatedResponse<Message>>;\r\n sendMessage(channelId: string, content: string, options?: { replyTo?: string }): Promise<Message>;\r\n reply(channelId: string, messageId: string, content: string, author: string, originalContent: string): Promise<Message>;\r\n editMessage(messageId: string, content: string): Promise<Message>;\r\n deleteMessage(messageId: string): Promise<void>;\r\n joinServer(inviteCode: string): Promise<Server>;\r\n leaveServer(serverId: string): Promise<void>;\r\n}\r\n\r\n// ============================================================================\r\n// Collection Type (for managers)\r\n// ============================================================================\r\n\r\nexport class Collection<K, V> extends Map<K, V> {\r\n constructor(entries?: readonly (readonly [K, V])[] | null) {\r\n super(entries);\r\n }\r\n\r\n public get(key: K): V | undefined {\r\n return super.get(key);\r\n }\r\n\r\n public set(key: K, value: V): this {\r\n return super.set(key, value);\r\n }\r\n\r\n public find(predicate: (value: V, key: K) => boolean): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n return value;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n public filter(predicate: (value: V, key: K) => boolean): V[] {\r\n const result: V[] = [];\r\n for (const [key, value] of this) {\r\n if (predicate(value, key)) {\r\n result.push(value);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n public first(): V | undefined {\r\n return this.values().next().value;\r\n }\r\n\r\n public last(): V | undefined {\r\n let last: V | undefined;\r\n for (const value of this.values()) {\r\n last = value;\r\n }\r\n return last;\r\n }\r\n}\r\n","/**\r\n * Main ChirpClient class\r\n * The primary entry point for the Chirp Bot SDK\r\n */\r\n\r\nimport { io, Socket } from 'socket.io-client';\r\nimport type { SocketOptions } from 'socket.io-client';\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n PartialUser,\r\n Collection,\r\n ChirpClientOptions,\r\n Intent,\r\n Command,\r\n} from '../api/types.js';\r\nimport { RESTClient, APIError } from '../api/REST.js';\r\nimport { SafeEventEmitter } from './events/EventEmitter.js';\r\nimport type { ChirpEvents } from './events/Events.js';\r\nimport { CommandManager } from '../commands/CommandManager.js';\r\nimport { ChannelManager } from './managers/ChannelManager.js';\r\nimport { MessageManager } from './managers/MessageManager.js';\r\nimport { ServerManager } from './managers/ServerManager.js';\r\nimport { wsToHttp, delay } from '../util/helpers.js';\r\nimport { Logger } from '../util/logger.js';\r\n\r\n// Import Collection at runtime\r\nlet CollectionClass: any;\r\n\r\nfunction getCollection(): any {\r\n if (!CollectionClass) {\r\n // Dynamic import to avoid circular dependency\r\n const module = require('../api/types.js');\r\n CollectionClass = module.Collection;\r\n }\r\n return CollectionClass;\r\n}\r\n\r\n/**\r\n * Connection status enum\r\n */\r\nexport enum ConnectionStatus {\r\n Disconnected = 'disconnected',\r\n Connecting = 'connecting',\r\n Connected = 'connected',\r\n Reconnecting = 'reconnecting',\r\n}\r\n\r\n/**\r\n * Main Chirp Bot SDK client\r\n */\r\nexport class ChirpClient extends SafeEventEmitter<ChirpEvents> {\r\n // ========================================================================\r\n // Public Properties\r\n // ========================================================================\r\n\r\n public readonly options: Required<ChirpClientOptions>;\r\n public readonly commands: CommandManager;\r\n public api!: RESTClient;\r\n\r\n public user: User | null = null;\r\n public servers: Collection<string, Server>;\r\n public channels: Collection<string, Channel>;\r\n public ws!: Socket;\r\n\r\n public channelsManager!: ChannelManager;\r\n public messagesManager!: MessageManager;\r\n public serversManager!: ServerManager;\r\n\r\n // ========================================================================\r\n // Private Properties\r\n // ========================================================================\r\n\r\n private token: string | null = null;\r\n private baseUrl!: string;\r\n private wsUrl!: string;\r\n private socket!: Socket;\r\n private status: ConnectionStatus = ConnectionStatus.Disconnected;\r\n private reconnectAttempts: number = 0;\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n private readonly log: Logger;\r\n\r\n // ========================================================================\r\n // Constructor\r\n // ========================================================================\r\n\r\n constructor(options: ChirpClientOptions = {}) {\r\n super();\r\n\r\n // Set up options with defaults\r\n this.options = {\r\n token: options.token ?? '',\r\n baseUrl: options.baseUrl ?? '',\r\n wsUrl: options.wsUrl ?? 'ws://localhost:3001',\r\n commandPrefix: options.commandPrefix ?? '/',\r\n intents: options.intents ?? ['messages', 'messageUpdates', 'userStatus', 'typing', 'servers'],\r\n reconnectAttempts: options.reconnectAttempts ?? Infinity,\r\n reconnectDelay: options.reconnectDelay ?? 1000,\r\n };\r\n\r\n // Derive baseUrl from wsUrl if not provided\r\n if (!this.options.baseUrl) {\r\n this.baseUrl = wsToHttp(this.options.wsUrl);\r\n } else {\r\n this.baseUrl = this.options.baseUrl;\r\n }\r\n this.wsUrl = this.options.wsUrl;\r\n\r\n // Initialize logger\r\n this.log = new Logger('ChirpClient');\r\n\r\n // Initialize managers with temporary API client\r\n // Will be replaced after login with proper token\r\n this.api = new RESTClient(this.baseUrl, '');\r\n\r\n // Initialize command manager\r\n this.commands = new CommandManager(this.options.commandPrefix);\r\n\r\n // Initialize collections\r\n const Collection = getCollection();\r\n this.servers = new Collection();\r\n this.channels = new Collection();\r\n\r\n // Set up process handlers\r\n this.setupProcessHandlers();\r\n }\r\n\r\n // ========================================================================\r\n // Public Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Connect and authenticate the bot\r\n */\r\n async login(token?: string): Promise<void> {\r\n if (this.status !== ConnectionStatus.Disconnected) {\r\n throw new Error('Client is already connected or connecting');\r\n }\r\n\r\n this.token = token || this.options.token;\r\n if (!this.token) {\r\n throw new Error('No token provided. Set token in options or pass to login()');\r\n }\r\n\r\n this.status = ConnectionStatus.Connecting;\r\n this.log.info('Connecting to', this.wsUrl);\r\n\r\n try {\r\n // Initialize API client with token\r\n this.api = new RESTClient(this.baseUrl, this.token);\r\n\r\n // Fetch bot info to validate token\r\n this.user = await this.api.getBotInfo();\r\n this.log.info(`Authenticated as ${this.user.username}`);\r\n\r\n // Initialize managers with proper API client\r\n this.channelsManager = new ChannelManager(this.api);\r\n this.messagesManager = new MessageManager(this.api);\r\n this.serversManager = new ServerManager(this.api);\r\n\r\n // Set up command manager client reference\r\n this.commands._setClient(this);\r\n\r\n // Fetch initial data\r\n await this.fetchInitialData();\r\n\r\n // Connect WebSocket\r\n await this.connectWebSocket();\r\n\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('ready');\r\n this.log.info('Bot is ready');\r\n\r\n } catch (error) {\r\n this.status = ConnectionStatus.Disconnected;\r\n this.log.error('Login failed:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect the bot\r\n */\r\n async logout(): Promise<void> {\r\n this.clearReconnectTimer();\r\n this.socket?.disconnect();\r\n this.status = ConnectionStatus.Disconnected;\r\n this.user = null;\r\n this.log.info('Logged out');\r\n }\r\n\r\n /**\r\n * Get current connection status\r\n */\r\n getStatus(): ConnectionStatus {\r\n return this.status;\r\n }\r\n\r\n /**\r\n * Check if the client is connected\r\n */\r\n isConnected(): boolean {\r\n return this.status === ConnectionStatus.Connected && this.socket?.connected === true;\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Initialization\r\n // ========================================================================\r\n\r\n private async fetchInitialData(): Promise<void> {\r\n try {\r\n const servers = await this.serversManager.fetch();\r\n this.log.debug(`Fetched ${servers.length} servers`);\r\n\r\n // Populate client's servers collection from manager's cache\r\n for (const [serverId, server] of this.serversManager.cache) {\r\n this.servers.set(serverId, server);\r\n }\r\n\r\n // Fetch channels for each server\r\n for (const server of servers) {\r\n try {\r\n const channels = await this.channelsManager.fetch(server.id);\r\n this.log.debug(`Fetched ${channels.length} channels for ${server.name}`);\r\n\r\n // Populate client's channels collection from manager's cache\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n } catch (error) {\r\n this.log.warn(`Failed to fetch channels for ${server.name}:`, error);\r\n }\r\n }\r\n } catch (error) {\r\n this.log.warn('Failed to fetch initial data:', error);\r\n }\r\n }\r\n\r\n private setupProcessHandlers(): void {\r\n const shutdown = async () => {\r\n await this.logout();\r\n process.exit(0);\r\n };\r\n\r\n process.on('SIGINT', shutdown);\r\n process.on('SIGTERM', shutdown);\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - WebSocket Connection\r\n // ========================================================================\r\n\r\n private async connectWebSocket(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const socketOptions: any = {\r\n auth: { token: `Bot ${this.token}` },\r\n reconnection: false, // We handle reconnection ourselves\r\n transports: ['websocket'],\r\n };\r\n\r\n this.socket = io(this.wsUrl, socketOptions);\r\n this.ws = this.socket;\r\n\r\n // Connection successful\r\n this.socket.on('connect', () => {\r\n this.log.debug('WebSocket connected');\r\n this.reconnectAttempts = 0;\r\n resolve();\r\n });\r\n\r\n // Connection error\r\n this.socket.on('connect_error', (error) => {\r\n this.log.error('WebSocket connection error:', error);\r\n this.status = ConnectionStatus.Disconnected;\r\n reject(error);\r\n });\r\n\r\n // Handle disconnect\r\n this.socket.on('disconnect', (reason) => {\r\n this.log.warn('WebSocket disconnected:', reason);\r\n this.status = ConnectionStatus.Disconnected;\r\n this.emit('disconnected', reason);\r\n\r\n // Attempt to reconnect if not intentionally disconnected\r\n if (reason !== 'io client disconnect') {\r\n this.scheduleReconnect();\r\n }\r\n });\r\n\r\n // Set up event handlers\r\n this.setupEventHandlers();\r\n });\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectAttempts >= this.options.reconnectAttempts) {\r\n this.log.error('Max reconnect attempts reached');\r\n this.emit('error', new Error('Max reconnect attempts reached'));\r\n return;\r\n }\r\n\r\n this.status = ConnectionStatus.Reconnecting;\r\n this.reconnectAttempts++;\r\n\r\n const delay = this.options.reconnectDelay * Math.min(this.reconnectAttempts, 10);\r\n\r\n this.log.info(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);\r\n this.emit('reconnecting', this.reconnectAttempts);\r\n\r\n this.reconnectTimer = setTimeout(async () => {\r\n try {\r\n await this.connectWebSocket();\r\n this.status = ConnectionStatus.Connected;\r\n this.emit('reconnected', this.reconnectAttempts);\r\n this.log.info('Reconnected successfully');\r\n } catch (error) {\r\n this.log.error('Reconnect failed:', error);\r\n this.scheduleReconnect();\r\n }\r\n }, delay);\r\n }\r\n\r\n private clearReconnectTimer(): void {\r\n if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods - Event Handlers\r\n // ========================================================================\r\n\r\n private setupEventHandlers(): void {\r\n // Message events\r\n this.socket.on('message:new', this.handleMessageNew.bind(this));\r\n this.socket.on('message:updated', this.handleMessageUpdated.bind(this));\r\n this.socket.on('message:deleted', this.handleMessageDeleted.bind(this));\r\n this.socket.on('dm:new', this.handleDMNew.bind(this));\r\n\r\n // User events\r\n this.socket.on('user:status', this.handleUserStatus.bind(this));\r\n this.socket.on('typing:start', this.handleTypingStart.bind(this));\r\n\r\n // Poll events\r\n if (this.hasIntent('polls')) {\r\n this.socket.on('poll:voted', this.handlePollVoted.bind(this));\r\n }\r\n\r\n // Thread events\r\n if (this.hasIntent('threads')) {\r\n this.socket.on('thread:reopened', this.handleThreadReopened.bind(this));\r\n this.socket.on('user_joined_thread', this.handleUserJoinedThread.bind(this));\r\n }\r\n\r\n // Voice events\r\n if (this.hasIntent('voice')) {\r\n this.socket.on('voice:joined', this.handleVoiceJoined.bind(this));\r\n this.socket.on('voice:left', this.handleVoiceLeft.bind(this));\r\n }\r\n\r\n // Bot events\r\n this.socket.on('bot:server_joined', this.handleBotServerJoined.bind(this));\r\n this.socket.on('bot:server_left', this.handleBotServerLeft.bind(this));\r\n\r\n // Subscription events\r\n this.socket.on('subscription:added', this.handleSubscriptionAdded.bind(this));\r\n }\r\n\r\n private hasIntent(intent: Intent): boolean {\r\n return this.options.intents.includes(intent);\r\n }\r\n\r\n // ========================================================================\r\n // Message Event Handlers\r\n // ========================================================================\r\n\r\n private async handleMessageNew(data: any): Promise<void> {\r\n // Server sends message object directly, not wrapped\r\n // The message has channel_id property and author as string\r\n const message = data as Message;\r\n const channelId = message.channel_id;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n // message.bot_id is set for all bot messages\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Update cache\r\n this.messagesManager.set(message);\r\n\r\n // Get channel\r\n const channel = this.channels.get(channelId);\r\n if (!channel) return;\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n channel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event\r\n this.emit('message:new', message, channelId);\r\n }\r\n\r\n private async handleDMNew(data: any): Promise<void> {\r\n const message = data;\r\n\r\n // Skip messages from bots (including our own bot messages)\r\n if (message.bot_id) {\r\n return;\r\n }\r\n\r\n // Skip empty messages\r\n if (!message.content || !message.content.trim()) {\r\n return;\r\n }\r\n\r\n // Determine the \"partner\" ID to construct the DM channel ID\r\n // If I am the sender, partner is receiver. If I am receiver, partner is sender.\r\n const partnerId = message.sender_id === this.user?.id ? message.receiver_id : message.sender_id;\r\n\r\n if (!partnerId) return;\r\n\r\n const dmChannelId = `dm-${partnerId}`;\r\n\r\n // Construct a fake channel object for DM\r\n const dmChannel: any = {\r\n id: dmChannelId,\r\n type: 'dm',\r\n name: message.sender_username || 'DM',\r\n serverId: null,\r\n createdAt: new Date().toISOString(),\r\n recipientId: partnerId\r\n };\r\n\r\n // Check for command\r\n const parsed = this.commands.parse(message);\r\n if (parsed) {\r\n try {\r\n await this.commands.execute(\r\n parsed.command,\r\n parsed.args,\r\n message,\r\n dmChannel,\r\n this,\r\n this.api\r\n );\r\n } catch (error) {\r\n this.log.error(`Command execution failed for /${parsed.command}:`, error);\r\n }\r\n return;\r\n }\r\n\r\n // Emit message:new event so bot code sees it\r\n this.emit('message:new', message, dmChannelId);\r\n }\r\n\r\n private handleMessageUpdated(data: {\r\n channelId: string;\r\n messageId: string;\r\n content: string;\r\n edited: boolean;\r\n edited_at: string;\r\n }): void {\r\n const { channelId, messageId, content, edited, edited_at } = data;\r\n // Update the message in cache if it exists\r\n const cachedMessage = this.messagesManager.get(messageId);\r\n if (cachedMessage) {\r\n const updatedMessage = {\r\n ...cachedMessage,\r\n content,\r\n edited,\r\n edited_at: edited_at,\r\n updated_at: edited_at,\r\n };\r\n this.messagesManager.cache.set(messageId, updatedMessage);\r\n }\r\n this.emit('message:updated', messageId, channelId, data);\r\n }\r\n\r\n private handleMessageDeleted(data: { messageId: string; channelId: string }): void {\r\n const { messageId, channelId } = data;\r\n this.messagesManager.deleteFromCache(messageId);\r\n this.emit('message:deleted', messageId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // User Event Handlers\r\n // ========================================================================\r\n\r\n private handleUserStatus(data: {\r\n userId: string;\r\n status: 'online' | 'idle' | 'dnd' | 'offline';\r\n user: PartialUser;\r\n }): void {\r\n const { userId, status, user } = data;\r\n this.emit('user:status', userId, status, user);\r\n }\r\n\r\n private handleTypingStart(data: { userId: string; channelId: string }): void {\r\n const { userId, channelId } = data;\r\n this.emit('typing:start', userId, channelId);\r\n }\r\n\r\n // ========================================================================\r\n // Poll Event Handlers\r\n // ========================================================================\r\n\r\n private handlePollVoted(data: { pollId: string; userId: string; optionId: string }): void {\r\n const { pollId, userId, optionId } = data;\r\n this.emit('poll:voted', pollId, userId, optionId);\r\n }\r\n\r\n // ========================================================================\r\n // Thread Event Handlers\r\n // ========================================================================\r\n\r\n private handleThreadReopened(data: { threadId: string; channelId: string }): void {\r\n const { threadId, channelId } = data;\r\n this.emit('thread:reopened', threadId, channelId);\r\n }\r\n\r\n private handleUserJoinedThread(data: { threadId: string; userId: string }): void {\r\n const { threadId, userId } = data;\r\n this.emit('user_joined_thread', threadId, userId);\r\n }\r\n\r\n // ========================================================================\r\n // Voice Event Handlers\r\n // ========================================================================\r\n\r\n private handleVoiceJoined(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:joined', userId, channelId, serverId);\r\n }\r\n\r\n private handleVoiceLeft(data: {\r\n userId: string;\r\n channelId: string;\r\n serverId: string;\r\n }): void {\r\n const { userId, channelId, serverId } = data;\r\n this.emit('voice:left', userId, channelId, serverId);\r\n }\r\n\r\n // ========================================================================\r\n // Bot Event Handlers\r\n // ========================================================================\r\n\r\n private handleBotServerJoined(data: { server: { id: string; name: string; icon_url: string | null } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Joined server: ${serverName}`);\r\n this.emit('bot:server_joined', serverId, serverName);\r\n\r\n // Add to servers collection with minimal server info\r\n // We'll fetch full server info later if needed\r\n const serverInfo: Server = {\r\n id: serverId,\r\n name: serverName,\r\n iconUrl: server.icon_url,\r\n ownerId: '', // Unknown at this point\r\n createdAt: new Date().toISOString(), // Approximate\r\n };\r\n this.servers.set(serverId, serverInfo);\r\n\r\n // Fetch channels for the new server\r\n this.channelsManager.fetch(serverId)\r\n .then((channels) => {\r\n // Populate channels collection\r\n for (const [channelId, channel] of this.channelsManager.cache) {\r\n this.channels.set(channelId, channel);\r\n }\r\n })\r\n .catch((error) => {\r\n this.log.warn(`Failed to fetch channels for ${serverName}:`, error);\r\n });\r\n }\r\n\r\n private handleBotServerLeft(data: { server: { id: string; name: string } }): void {\r\n const { server } = data;\r\n const serverId = server.id;\r\n const serverName = server.name;\r\n this.log.info(`Left server: ${serverName}`);\r\n this.emit('bot:server_left', serverId, serverName);\r\n\r\n // Remove from cache\r\n this.servers.delete(serverId);\r\n\r\n // Remove channels for this server\r\n for (const [channelId, channel] of this.channels) {\r\n if (channel.serverId === serverId) {\r\n this.channels.delete(channelId);\r\n }\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Subscription Event Handlers\r\n // ========================================================================\r\n\r\n private handleSubscriptionAdded(data: {\r\n subscriptionId: string;\r\n channelId: string;\r\n userId: string;\r\n tier: string;\r\n }): void {\r\n this.emit('subscription:added', data);\r\n }\r\n}\r\n\r\n// Export types\r\nexport * from './events/Events.js';\r\nexport * from './managers/index.js';\r\n","/**\r\n * REST API Client for Chirp Bot SDK\r\n * Extracted and refactored from examples/demo-bot/src/api.js\r\n */\r\n\r\nimport type {\r\n User,\r\n Server,\r\n Channel,\r\n Message,\r\n BotTokenInfo,\r\n BotServerInfo,\r\n MessageOptions,\r\n PaginatedResponse,\r\n} from './types.js';\r\n\r\nexport class APIError extends Error {\r\n public statusCode: number;\r\n public code?: string;\r\n\r\n constructor(message: string, statusCode: number, code?: string) {\r\n super(message);\r\n this.name = 'APIError';\r\n this.statusCode = statusCode;\r\n this.code = code;\r\n }\r\n}\r\n\r\nexport class RESTClient {\r\n private readonly baseUrl: string;\r\n private readonly token: string;\r\n\r\n constructor(baseUrl: string, token: string) {\r\n this.baseUrl = baseUrl;\r\n this.token = token;\r\n }\r\n\r\n /**\r\n * Make an authenticated API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n const headers: HeadersInit = {\r\n 'Authorization': `Bot ${this.token}`,\r\n 'Content-Type': 'application/json',\r\n ...options.headers,\r\n };\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n headers,\r\n });\r\n\r\n const contentType = response.headers.get('content-type');\r\n const isJson = contentType?.includes('application/json');\r\n\r\n if (!response.ok) {\r\n let errorMessage = `HTTP ${response.status}`;\r\n if (isJson) {\r\n try {\r\n const errorData = await response.json();\r\n errorMessage = errorData.message || errorData.error || errorMessage;\r\n } catch {\r\n // Use default error message\r\n }\r\n }\r\n throw new APIError(errorMessage, response.status);\r\n }\r\n\r\n if (isJson && response.status !== 204) {\r\n return response.json();\r\n }\r\n\r\n return undefined as T;\r\n }\r\n\r\n /**\r\n * GET request\r\n */\r\n private async get<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'GET' });\r\n }\r\n\r\n /**\r\n * POST request\r\n */\r\n private async post<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'POST',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PATCH request\r\n */\r\n private async patch<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PATCH',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * PUT request\r\n */\r\n private async put<T>(endpoint: string, body?: unknown): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n method: 'PUT',\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * DELETE request\r\n */\r\n private async delete<T>(endpoint: string): Promise<T> {\r\n return this.request<T>(endpoint, { method: 'DELETE' });\r\n }\r\n\r\n // ========================================================================\r\n // Bot API Methods\r\n // ========================================================================\r\n\r\n /**\r\n * Get the bot's user information\r\n */\r\n async getBotInfo(): Promise<User> {\r\n return this.get<User>('/api/auth/me');\r\n }\r\n\r\n /**\r\n * Get the bot's token information\r\n */\r\n async getTokenInfo(): Promise<BotTokenInfo> {\r\n return this.get<BotTokenInfo>('/api/bot-tokens');\r\n }\r\n\r\n /**\r\n * List all servers the bot has access to\r\n */\r\n async getServers(): Promise<Server[]> {\r\n return this.get<Server[]>('/api/servers');\r\n }\r\n\r\n /**\r\n * List the bot's server memberships with details\r\n */\r\n async getBotServers(): Promise<BotServerInfo[]> {\r\n return this.get<BotServerInfo[]>('/api/bot-tokens/servers');\r\n }\r\n\r\n /**\r\n * Get channels in a server\r\n */\r\n async getChannels(serverId: string): Promise<Channel[]> {\r\n return this.get<Channel[]>(`/api/servers/${serverId}/channels`);\r\n }\r\n\r\n /**\r\n * Get messages in a channel\r\n */\r\n async getMessages(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const params = new URLSearchParams();\r\n if (options.page) params.append('page', String(options.page));\r\n if (options.limit) params.append('limit', String(options.limit));\r\n const query = params.toString();\r\n\r\n if (channelId.startsWith('dm-')) {\r\n const receiverId = channelId.substring(3);\r\n return this.get<PaginatedResponse<Message>>(\r\n `/api/dms/${receiverId}/messages${query ? `?${query}` : ''}`\r\n );\r\n }\r\n\r\n return this.get<PaginatedResponse<Message>>(\r\n `/api/channels/${channelId}/messages${query ? `?${query}` : ''}`\r\n );\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async sendMessage(\r\n channelId: string,\r\n content: string,\r\n options: MessageOptions = {}\r\n ): Promise<Message> {\r\n const body: Record<string, any> = {\r\n content,\r\n replyTo: options.replyTo,\r\n };\r\n if (options.pollData) {\r\n body.poll_data = options.pollData;\r\n }\r\n\r\n if (channelId.startsWith('dm-')) {\r\n const receiverId = channelId.substring(3);\r\n return this.post<Message>(`/api/dms/${receiverId}/messages`, body);\r\n }\r\n\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, body);\r\n }\r\n\r\n /**\r\n * Reply to a specific message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n return this.post<Message>(`/api/channels/${channelId}/messages`, {\r\n content,\r\n replyTo: messageId,\r\n });\r\n }\r\n\r\n /**\r\n * Edit a message (only works for bot's own messages)\r\n */\r\n async editMessage(messageId: string, content: string, channelId?: string): Promise<Message> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.patch<Message>(`/api/direct-messages/${messageId}`, { content });\r\n }\r\n return this.patch<Message>(`/api/messages/${messageId}`, { content });\r\n }\r\n\r\n /**\r\n * Delete a message (only works for bot's own messages)\r\n */\r\n async deleteMessage(messageId: string, channelId?: string): Promise<void> {\r\n if (channelId?.startsWith('dm-')) {\r\n return this.delete<void>(`/api/direct-messages/${messageId}`);\r\n }\r\n return this.delete<void>(`/api/messages/${messageId}`);\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async joinServer(inviteCode: string): Promise<Server> {\r\n return this.post<Server>('/api/bot-tokens/servers/join', { inviteCode });\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leaveServer(serverId: string): Promise<void> {\r\n return this.delete<void>(`/api/bot-tokens/servers/${serverId}/leave`);\r\n }\r\n}\r\n","/**\r\n * Type-safe EventEmitter wrapper around EventEmitter3\r\n */\r\n\r\nimport EventEmitter from 'eventemitter3';\r\n\r\n// Extract event names from their signature\r\ntype EventNames<T> = T extends any ? (keyof T & string) : never;\r\ntype EventListener<T, K extends keyof T & string> = T[K] extends (\r\n ...args: any[]\r\n) => any\r\n ? T[K]\r\n : (...args: any[]) => void;\r\n\r\n/**\r\n * Type-safe event emitter\r\n */\r\nexport class SafeEventEmitter<TEvents extends Record<string, any>> {\r\n private readonly emitter: EventEmitter;\r\n\r\n constructor() {\r\n this.emitter = new EventEmitter();\r\n }\r\n\r\n /**\r\n * Register an event listener\r\n */\r\n public on<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.on(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register a one-time event listener\r\n */\r\n public once<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.once(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an event listener\r\n */\r\n public off<K extends EventNames<TEvents>>(\r\n event: K,\r\n listener: EventListener<TEvents, K>\r\n ): this {\r\n this.emitter.off(event, listener as any);\r\n return this;\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n public emit<K extends EventNames<TEvents>>(\r\n event: K,\r\n ...args: any[]\r\n ): boolean {\r\n return this.emitter.emit(event, ...args);\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event or all events\r\n */\r\n public removeAllListeners<K extends EventNames<TEvents>>(event?: K): this {\r\n this.emitter.removeAllListeners(event);\r\n return this;\r\n }\r\n\r\n /**\r\n * Get the count of listeners for an event\r\n */\r\n public listenerCount<K extends EventNames<TEvents>>(event: K): number {\r\n return this.emitter.listenerCount(event);\r\n }\r\n}\r\n\r\n/**\r\n * Event listener types\r\n */\r\nexport type EventHandler<T = any> = (...args: T[]) => void;\r\n","/**\r\n * Command Context - provides context for command execution\r\n */\r\n\r\nimport type { Message, Channel, CommandContext as ICommandContext } from '../api/types.js';\r\n\r\n// Import types dynamically to avoid circular dependency\r\ntype ChirpClientType = any;\r\ntype RESTClientType = any;\r\n\r\n/**\r\n * Command execution context\r\n */\r\nexport class CommandContext implements ICommandContext {\r\n public readonly command: string;\r\n public readonly args: string[];\r\n public readonly message: Message;\r\n public readonly channel: Channel;\r\n public readonly client: ChirpClientType;\r\n public readonly api: RESTClientType;\r\n\r\n constructor(\r\n command: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientType,\r\n api: RESTClientType\r\n ) {\r\n this.command = command;\r\n this.args = args;\r\n this.message = message;\r\n this.channel = channel;\r\n this.client = client;\r\n this.api = api;\r\n }\r\n\r\n /**\r\n * Reply to the command message\r\n */\r\n async reply(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content, {\r\n replyTo: this.message.id,\r\n });\r\n }\r\n\r\n /**\r\n * Send a message to the same channel\r\n */\r\n async send(content: string): Promise<Message> {\r\n return this.api.sendMessage(this.channel.id, content);\r\n }\r\n\r\n /**\r\n * Edit the bot's response message\r\n */\r\n /**\r\n * Edit the bot's response message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n return this.api.editMessage(messageId, content, this.channel.id);\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n return this.api.deleteMessage(messageId, this.channel.id);\r\n }\r\n\r\n /**\r\n * Get the raw command string\r\n */\r\n get rawCommand(): string {\r\n return `${this.command}${this.args.length ? ' ' + this.args.join(' ') : ''}`;\r\n }\r\n}\r\n","/**\r\n * Command Manager - handles command registration and execution\r\n */\r\n\r\nimport type { Command, Message, Channel, RESTClient } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\nimport type { ChirpClient } from '../client/ChirpClient.js';\r\n\r\ntype ChirpClientInstance = ChirpClient;\r\n\r\n/**\r\n * Command Manager class\r\n */\r\nexport class CommandManager {\r\n private readonly commands: Map<string, Command>;\r\n private readonly prefix: string;\r\n private client?: ChirpClientInstance;\r\n\r\n constructor(prefix: string = '/') {\r\n this.commands = new Map();\r\n this.prefix = prefix;\r\n }\r\n\r\n /**\r\n * Set the client reference (called by ChirpClient)\r\n * @internal\r\n */\r\n _setClient(client: ChirpClientInstance): void {\r\n this.client = client;\r\n }\r\n\r\n /**\r\n * Register a command\r\n */\r\n register(command: Command): this;\r\n register(builder: { build(): Command }): this;\r\n register(commandOrBuilder: Command | { build(): Command }): this {\r\n const command =\r\n 'build' in commandOrBuilder ? commandOrBuilder.build() : commandOrBuilder;\r\n\r\n this.commands.set(command.name, command);\r\n return this;\r\n }\r\n\r\n /**\r\n * Register multiple commands\r\n */\r\n registerMany(commands: (Command | { build(): Command })[]): this {\r\n for (const commandOrBuilder of commands) {\r\n if ('build' in commandOrBuilder) {\r\n this.register(commandOrBuilder);\r\n } else {\r\n this.register(commandOrBuilder);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Unregister a command\r\n */\r\n unregister(name: string): boolean {\r\n return this.commands.delete(name);\r\n }\r\n\r\n /**\r\n * Get a command by name\r\n */\r\n get(name: string): Command | undefined {\r\n return this.commands.get(name);\r\n }\r\n\r\n /**\r\n * Check if a command exists\r\n */\r\n has(name: string): boolean {\r\n return this.commands.has(name);\r\n }\r\n\r\n /**\r\n * Get all registered commands\r\n */\r\n getAll(): Map<string, Command> {\r\n return new Map(this.commands);\r\n }\r\n\r\n /**\r\n * Clear all commands\r\n */\r\n clear(): void {\r\n this.commands.clear();\r\n }\r\n\r\n /**\r\n * Parse a message to check if it's a command\r\n * Returns { command, args } if it's a command, null otherwise\r\n */\r\n parse(message: Message): { command: string; args: string[] } | null {\r\n const content = message.content.trim();\r\n\r\n if (!content.startsWith(this.prefix)) {\r\n return null;\r\n }\r\n\r\n const parts = content.slice(this.prefix.length).trim().split(/\\s+/);\r\n const command = parts[0];\r\n const args = parts.slice(1);\r\n\r\n return { command, args };\r\n }\r\n\r\n /**\r\n * Execute a command\r\n * @internal\r\n */\r\n async execute(\r\n commandName: string,\r\n args: string[],\r\n message: Message,\r\n channel: Channel,\r\n client: ChirpClientInstance,\r\n api: RESTClient\r\n ): Promise<void> {\r\n const command = this.commands.get(commandName);\r\n\r\n if (!command) {\r\n return;\r\n }\r\n\r\n const context = new CommandContext(\r\n commandName,\r\n args,\r\n message,\r\n channel,\r\n client,\r\n api\r\n );\r\n\r\n try {\r\n await command.handler(context);\r\n } catch (error) {\r\n // Emit error event through client if available\r\n if (this.client) {\r\n this.client.emit('error', error);\r\n }\r\n throw error;\r\n }\r\n }\r\n}\r\n","/**\r\n * Channel Manager - manages channel caching and operations\r\n */\r\n\r\nimport type { Channel, Collection, RESTClient } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for channel operations\r\n */\r\nexport class ChannelManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Channel>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ChannelManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch channels for a server\r\n */\r\n async fetch(serverId: string): Promise<Channel[]> {\r\n const channels = await this.api.getChannels(serverId);\r\n\r\n // Update cache\r\n for (const channel of channels) {\r\n this.cache.set(channel.id, channel);\r\n }\r\n\r\n return channels;\r\n }\r\n\r\n /**\r\n * Get a channel from cache by ID\r\n */\r\n get(channelId: string): Channel | undefined {\r\n return this.cache.get(channelId);\r\n }\r\n\r\n /**\r\n * Find a channel by name in a server\r\n */\r\n findByName(serverId: string, name: string): Channel | undefined {\r\n return this.cache.find(\r\n (channel) => channel.serverId === serverId && channel.name === name\r\n );\r\n }\r\n\r\n /**\r\n * Get all channels from cache\r\n */\r\n getAll(): Collection<string, Channel> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the channel cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a channel in cache\r\n */\r\n set(channel: Channel): this {\r\n this.cache.set(channel.id, channel);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a channel from cache\r\n */\r\n delete(channelId: string): boolean {\r\n return this.cache.delete(channelId);\r\n }\r\n}\r\n","/**\r\n * Message Manager - manages message operations\r\n */\r\n\r\nimport type {\r\n Message,\r\n MessageOptions,\r\n PaginatedResponse,\r\n RESTClient,\r\n Collection,\r\n} from '../../api/types.js';\r\n\r\n/**\r\n * Manager for message operations\r\n */\r\nexport class MessageManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Message>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof MessageManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch messages for a channel\r\n */\r\n async fetch(\r\n channelId: string,\r\n options: { page?: number; limit?: number } = {}\r\n ): Promise<PaginatedResponse<Message>> {\r\n const response = await this.api.getMessages(channelId, options);\r\n\r\n // Update cache\r\n for (const message of response.data) {\r\n this.cache.set(message.id, message);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send a message to a channel\r\n */\r\n async send(channelId: string, content: string, options?: MessageOptions): Promise<Message> {\r\n const message = await this.api.sendMessage(channelId, content, options);\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Reply to a message\r\n */\r\n async reply(\r\n channelId: string,\r\n messageId: string,\r\n content: string,\r\n author: string,\r\n originalContent: string\r\n ): Promise<Message> {\r\n const message = await this.api.reply(\r\n channelId,\r\n messageId,\r\n content,\r\n author,\r\n originalContent\r\n );\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n\r\n /**\r\n * Edit a message\r\n */\r\n async edit(messageId: string, content: string): Promise<Message> {\r\n const message = await this.api.editMessage(messageId, content);\r\n\r\n // Update cache\r\n this.cache.set(messageId, message);\r\n\r\n return message;\r\n }\r\n\r\n /**\r\n * Delete a message\r\n */\r\n async delete(messageId: string): Promise<void> {\r\n await this.api.deleteMessage(messageId);\r\n this.cache.delete(messageId);\r\n }\r\n\r\n /**\r\n * Get a message from cache by ID\r\n */\r\n get(messageId: string): Message | undefined {\r\n return this.cache.get(messageId);\r\n }\r\n\r\n /**\r\n * Get all messages from cache\r\n */\r\n getAll(): Collection<string, Message> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the message cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a message in cache\r\n */\r\n set(message: Message): this {\r\n this.cache.set(message.id, message);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a message from cache\r\n */\r\n deleteFromCache(messageId: string): boolean {\r\n return this.cache.delete(messageId);\r\n }\r\n}\r\n","/**\r\n * Server Manager - manages server caching and operations\r\n */\r\n\r\nimport type { Server, RESTClient, Collection } from '../../api/types.js';\r\n\r\n/**\r\n * Manager for server operations\r\n */\r\nexport class ServerManager {\r\n private readonly api: RESTClient;\r\n public readonly cache: Collection<string, Server>;\r\n\r\n constructor(api: RESTClient) {\r\n this.api = api;\r\n this.cache = (this.constructor as typeof ServerManager).createCollection();\r\n }\r\n\r\n /**\r\n * Create a Collection instance (avoiding circular dependency)\r\n */\r\n private static createCollection(): any {\r\n const { Collection } = require('../../api/types.js');\r\n return new Collection();\r\n }\r\n\r\n /**\r\n * Fetch all servers the bot has access to\r\n */\r\n async fetch(): Promise<Server[]> {\r\n const servers = await this.api.getServers();\r\n\r\n // Update cache\r\n for (const server of servers) {\r\n this.cache.set(server.id, server);\r\n }\r\n\r\n return servers;\r\n }\r\n\r\n /**\r\n * Fetch the bot's server memberships with details\r\n */\r\n async fetchBotServers(): Promise<Server[]> {\r\n const botServers = await this.api.getBotServers();\r\n\r\n // Update cache with server info\r\n for (const botServer of botServers) {\r\n this.cache.set(botServer.serverId, {\r\n id: botServer.serverId,\r\n name: botServer.serverName,\r\n iconUrl: botServer.serverIconUrl,\r\n ownerId: '',\r\n createdAt: botServer.joinedAt,\r\n });\r\n }\r\n\r\n return botServers.map((bs: any) => ({\r\n id: bs.serverId,\r\n name: bs.serverName,\r\n iconUrl: bs.serverIconUrl,\r\n ownerId: '',\r\n createdAt: bs.joinedAt,\r\n }));\r\n }\r\n\r\n /**\r\n * Join a server via invite code\r\n */\r\n async join(inviteCode: string): Promise<Server> {\r\n const server = await this.api.joinServer(inviteCode);\r\n this.cache.set(server.id, server);\r\n return server;\r\n }\r\n\r\n /**\r\n * Leave a server\r\n */\r\n async leave(serverId: string): Promise<void> {\r\n await this.api.leaveServer(serverId);\r\n this.cache.delete(serverId);\r\n }\r\n\r\n /**\r\n * Get a server from cache by ID\r\n */\r\n get(serverId: string): Server | undefined {\r\n return this.cache.get(serverId);\r\n }\r\n\r\n /**\r\n * Find a server by name\r\n */\r\n findByName(name: string): Server | undefined {\r\n return this.cache.find((server) => server.name === name);\r\n }\r\n\r\n /**\r\n * Get all servers from cache\r\n */\r\n getAll(): Collection<string, Server> {\r\n return this.cache;\r\n }\r\n\r\n /**\r\n * Clear the server cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n /**\r\n * Add or update a server in cache\r\n */\r\n set(server: Server): this {\r\n this.cache.set(server.id, server);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove a server from cache\r\n */\r\n delete(serverId: string): boolean {\r\n return this.cache.delete(serverId);\r\n }\r\n}\r\n","/**\r\n * Utility helper functions\r\n */\r\n\r\n/**\r\n * Convert a WebSocket URL to HTTP URL\r\n */\r\nexport function wsToHttp(wsUrl: string): string {\r\n return wsUrl\r\n .replace(/^ws:\\/\\//i, 'http://')\r\n .replace(/^wss:\\/\\//i, 'https://');\r\n}\r\n\r\n/**\r\n * Convert an HTTP URL to WebSocket URL\r\n */\r\nexport function httpToWs(httpUrl: string): string {\r\n return httpUrl\r\n .replace(/^http:\\/\\//i, 'ws://')\r\n .replace(/^https:\\/\\//i, 'wss://');\r\n}\r\n\r\n/**\r\n * Parse command arguments from a string\r\n * Handles quoted strings as single arguments\r\n */\r\nexport function parseArgs(input: string): string[] {\r\n const args: string[] = [];\r\n let current = '';\r\n let inQuotes = false;\r\n\r\n for (let i = 0; i < input.length; i++) {\r\n const char = input[i];\r\n\r\n if (char === '\"' || char === \"'\") {\r\n inQuotes = !inQuotes;\r\n } else if (char === ' ' && !inQuotes) {\r\n if (current) {\r\n args.push(current);\r\n current = '';\r\n }\r\n } else {\r\n current += char;\r\n }\r\n }\r\n\r\n if (current) {\r\n args.push(current);\r\n }\r\n\r\n return args;\r\n}\r\n\r\n/**\r\n * Format a user mention\r\n */\r\nexport function formatMention(userId: string): string {\r\n return `<@${userId}>`;\r\n}\r\n\r\n/**\r\n * Format a channel mention\r\n */\r\nexport function formatChannelMention(channelId: string): string {\r\n return `<#${channelId}>`;\r\n}\r\n\r\n/**\r\n * Extract user IDs from mentions in a message\r\n */\r\nexport function extractMentionIds(content: string): string[] {\r\n const mentionRegex = /<@([^>]+)>/g;\r\n const ids: string[] = [];\r\n let match;\r\n\r\n while ((match = mentionRegex.exec(content)) !== null) {\r\n ids.push(match[1]);\r\n }\r\n\r\n return ids;\r\n}\r\n\r\n/**\r\n * Delay execution for a specified time\r\n */\r\nexport function delay(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Retry a function with exponential backoff\r\n */\r\nexport async function retry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts?: number;\r\n initialDelay?: number;\r\n maxDelay?: number;\r\n factor?: number;\r\n } = {}\r\n): Promise<T> {\r\n const {\r\n maxAttempts = 3,\r\n initialDelay = 1000,\r\n maxDelay = 10000,\r\n factor = 2,\r\n } = options;\r\n\r\n let delayTime = initialDelay;\r\n let lastError: Error | undefined;\r\n\r\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error as Error;\r\n\r\n if (attempt === maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n await delay(delayTime);\r\n delayTime = Math.min(delayTime * factor, maxDelay);\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n","/**\r\n * Logger utility for the SDK\r\n */\r\n\r\nexport enum LogLevel {\r\n DEBUG = 0,\r\n INFO = 1,\r\n WARN = 2,\r\n ERROR = 3,\r\n}\r\n\r\nexport class Logger {\r\n private level: LogLevel;\r\n private prefix: string;\r\n\r\n constructor(prefix: string = 'ChirpSDK', level: LogLevel = LogLevel.INFO) {\r\n this.prefix = prefix;\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Set the log level\r\n */\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n /**\r\n * Format a log message\r\n */\r\n private format(level: string, message: string, ...args: any[]): string {\r\n const timestamp = new Date().toISOString();\r\n return `[${timestamp}] [${level}] [${this.prefix}] ${message}`;\r\n }\r\n\r\n /**\r\n * Log a debug message\r\n */\r\n debug(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.DEBUG) {\r\n console.debug(this.format('DEBUG', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an info message\r\n */\r\n info(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.INFO) {\r\n console.info(this.format('INFO', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log a warning message\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.WARN) {\r\n console.warn(this.format('WARN', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Log an error message\r\n */\r\n error(message: string, ...args: any[]): void {\r\n if (this.level <= LogLevel.ERROR) {\r\n console.error(this.format('ERROR', message), ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Create a child logger with a different prefix\r\n */\r\n child(prefix: string): Logger {\r\n return new Logger(`${this.prefix}:${prefix}`, this.level);\r\n }\r\n}\r\n\r\n/**\r\n * Default logger instance\r\n */\r\nexport const logger = new Logger();\r\n","/**\r\n * Command Builder - fluent API for building commands\r\n */\r\n\r\nimport type { Command } from '../api/types.js';\r\nimport { CommandContext } from './CommandContext.js';\r\n\r\nexport class CommandBuilder {\r\n private name: string = '';\r\n private description: string = '';\r\n private usage?: string;\r\n private handler?: (context: CommandContext) => void | Promise<void>;\r\n\r\n /**\r\n * Set the command name\r\n */\r\n setName(name: string): this {\r\n this.name = name;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command description\r\n */\r\n setDescription(description: string): this {\r\n this.description = description;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command usage example\r\n */\r\n setUsage(usage: string): this {\r\n this.usage = usage;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the command handler\r\n */\r\n setHandler(handler: (context: CommandContext) => void | Promise<void>): this {\r\n this.handler = handler;\r\n return this;\r\n }\r\n\r\n /**\r\n * Build the command object\r\n */\r\n build(): Command {\r\n if (!this.name) {\r\n throw new Error('Command name is required');\r\n }\r\n if (!this.description) {\r\n throw new Error('Command description is required');\r\n }\r\n if (!this.handler) {\r\n throw new Error('Command handler is required');\r\n }\r\n\r\n return {\r\n name: this.name,\r\n description: this.description,\r\n usage: this.usage,\r\n handler: this.handler as any, // Cast to satisfy Command type\r\n };\r\n }\r\n}\r\n","/**\r\n * Custom error classes for the Chirp Bot SDK\r\n */\r\n\r\n/**\r\n * Base error class for all SDK errors\r\n */\r\nexport class ChirpError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'ChirpError';\r\n Error.captureStackTrace?.(this, this.constructor);\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends ChirpError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a rate limit is hit\r\n */\r\nexport class RateLimitError extends ChirpError {\r\n public readonly retryAfter: number;\r\n\r\n constructor(message: string, retryAfter: number = 0) {\r\n super(message);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a requested resource is not found\r\n */\r\nexport class NotFoundError extends ChirpError {\r\n constructor(message: string = 'Resource not found') {\r\n super(message);\r\n this.name = 'NotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the client lacks permission for an action\r\n */\r\nexport class PermissionError extends ChirpError {\r\n constructor(message: string = 'Insufficient permissions') {\r\n super(message);\r\n this.name = 'PermissionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a request is invalid\r\n */\r\nexport class ValidationError extends ChirpError {\r\n constructor(message: string = 'Validation failed') {\r\n super(message);\r\n this.name = 'ValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when the WebSocket connection fails\r\n */\r\nexport class ConnectionError extends ChirpError {\r\n constructor(message: string = 'Connection failed') {\r\n super(message);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when command execution fails\r\n */\r\nexport class CommandError extends ChirpError {\r\n public readonly commandName: string;\r\n\r\n constructor(message: string, commandName: string) {\r\n super(message);\r\n this.name = 'CommandError';\r\n this.commandName = commandName;\r\n }\r\n}\r\n"],"mappings":"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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 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chirp-dev/chirp-sdk",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Official SDK for building Chirp bots",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",