beniocord.js 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Client.js CHANGED
@@ -10,6 +10,7 @@ const User = require("./structures/User");
10
10
  const Channel = require("./structures/Channel");
11
11
  const Emoji = require("./structures/Emoji");
12
12
  const { MessageEmbed, MessageAttachment } = require("./structures/Util");
13
+ const { formatUrl } = require("./helpers");
13
14
 
14
15
  let global = {
15
16
  token: "",
@@ -18,6 +19,23 @@ let global = {
18
19
 
19
20
  class Client extends EventEmitter {
20
21
  /**
22
+ * @typedef {Object} ClientEvents
23
+ * @property {User} ready - Fired when the client finishes connecting
24
+ * @property {Message} messageCreate - Fired when a new message is created
25
+ * @property {Message} messageUpdate - Fired when a message is updated
26
+ * @property {Message} messageDelete - Fired when a message is deleted
27
+ * @property {Channel} channelCreate - Fired when a new channel is created
28
+ * @property {Channel} channelDelete - Fired when a channel is deleted
29
+ * @property {Channel} channelUpdate - Fired when a channel is updated
30
+ * @property {{channel: Channel, member: User}} channelMemberAdd - Fired when a member joins a channel
31
+ * @property {{channel: Channel, member: User}} channelMemberRemove - Fired when a member leaves a channel
32
+ * @property {User} channelMemberUpdate - Fired when a member updates their info in a channel
33
+ * @property {Emoji} emojiCreate - Fired when a new emoji is created
34
+ * @property {Emoji} emojiDelete - Fired when an emoji is deleted
35
+ * @property {Error} error - Fired when an error occurs
36
+ * @property {void} disconnect - Fired when disconnected from the gateway
37
+ * @property {void} reconnect - Fired when reconnecting to the gateway
38
+ *
21
39
  * @fires Client#ready
22
40
  * @fires Client#messageCreate
23
41
  * @fires Client#messageDelete
@@ -38,12 +56,13 @@ class Client extends EventEmitter {
38
56
  * @fires Client#typingStart
39
57
  * @fires Client#typingStop
40
58
  * @class Client
41
- * @description Classe principal do BenioCord.js - Gerencia a comunicação com a API e eventos do bot
59
+ * @description The main class of BenioCord.js, responsible for managing API communication and bot events.
42
60
  * @param {Object} options - Opções de configuração do cliente
43
61
  * @param {string} options.token - Token do bot para autenticação
44
62
  * @example
45
- * const { Client } = require('beniocord.js');
46
- * const client = new Client({ token: 'YOUR_BOT_TOKEN' });
63
+ * const Beniocord = require('beniocord.js');
64
+ * const client = new Beniocord({ token: 'YOUR_BOT_TOKEN' });
65
+ * client.login();
47
66
  */
48
67
  constructor({ token }) {
49
68
  super();
@@ -61,6 +80,7 @@ class Client extends EventEmitter {
61
80
  this.isConnected = false;
62
81
  this.isReady = false;
63
82
  this.status = 'online';
83
+ this.version = require('./package.json').version;
64
84
 
65
85
  // Configuration options
66
86
  this.config = {
@@ -174,7 +194,8 @@ class Client extends EventEmitter {
174
194
  }
175
195
 
176
196
  /**
177
- * Disconnects the bot from the server
197
+ * Kills the connection to the server
198
+ * @returns {void}
178
199
  */
179
200
  disconnect() {
180
201
  this._stopHeartbeat();
@@ -213,10 +234,14 @@ class Client extends EventEmitter {
213
234
  /**
214
235
  * Sets the bot's status
215
236
  * @param {string} status - Status: "online", "away", "dnd", "offline"
237
+ * @returns {Promise<Object>}
238
+ * @example
239
+ * client.setStatus("dnd").then((data) => {
240
+ * console.log("Status updated:", data);
241
+ * });
216
242
  */
217
243
  async setStatus(status) {
218
244
  const validStatuses = ["online", "offline", "away", "dnd"];
219
-
220
245
  if (!validStatuses.includes(status)) {
221
246
  throw new ClientError(
222
247
  `Invalid status. Valid statuses are: ${validStatuses.join(", ")}`,
@@ -226,7 +251,14 @@ class Client extends EventEmitter {
226
251
 
227
252
  this._ensureConnected();
228
253
  this.status = status;
229
- this.socket.emit('status:update', { status });
254
+
255
+ return new Promise((resolve) => {
256
+ this.socket.once('user:status-update', (data) => {
257
+ resolve(data);
258
+ });
259
+
260
+ this.socket.emit('status:update', { status });
261
+ });
230
262
  }
231
263
 
232
264
  /**
@@ -424,7 +456,7 @@ class Client extends EventEmitter {
424
456
  * Adds a member to a channel
425
457
  * @param {string} channelId - Channel ID
426
458
  * @param {string} userId - User ID to add
427
- * @param {string} role - Member role (default: 'member')
459
+ * @param {string} [role] - Member role (default: 'member')
428
460
  * @returns {Promise<Object>} Response data
429
461
  */
430
462
  async addChannelMember(channelId, userId, role = 'member') {
@@ -680,9 +712,43 @@ class Client extends EventEmitter {
680
712
  async fetchMessage(channelId, messageId) {
681
713
  try {
682
714
  const res = await this._axios.get(`/api/channels/${channelId}/messages/${messageId}`);
683
- return new Message(res.data, this);
715
+ const raw = res.data;
716
+
717
+ // --- USER ---
718
+ const userData = {
719
+ id: raw.user_id,
720
+ username: raw.username,
721
+ display_name: raw.display_name,
722
+ avatar_url: raw.avatar_url,
723
+ status: raw.status || 'online',
724
+ emblems: raw.emblems || [],
725
+ is_bot: raw.is_bot ?? false,
726
+ last_seen: raw.last_seen ?? raw.created_at,
727
+ created_at: raw.created_at,
728
+ };
729
+ const messageData = { ...raw, user: userData };
730
+
731
+ // Cria a mensagem
732
+ const message = new Message(messageData, this);
733
+
734
+ // Cache do author
735
+ if (message.author) this.cache.users.set(message.author.id, message.author);
736
+
737
+ // --- CHANNEL ---
738
+ if (!message.channel && raw.channel_id) {
739
+ // Tenta pegar da cache
740
+ let channel = this.cache.channels.get(raw.channel_id);
741
+ if (!channel) {
742
+ channel = await this.fetchChannel(raw.channel_id);
743
+ }
744
+ message.channel = channel;
745
+ }
746
+
747
+ return message;
684
748
  } catch (error) {
685
- throw error instanceof ClientError ? error : new ClientError(error.message, "FETCH_MESSAGE_ERROR");
749
+ throw error instanceof ClientError
750
+ ? error
751
+ : new ClientError(error.message, "FETCH_MESSAGE_ERROR");
686
752
  }
687
753
  }
688
754
 
@@ -693,6 +759,7 @@ class Client extends EventEmitter {
693
759
  /**
694
760
  * Starts typing indicator in a channel
695
761
  * @param {string} channelId - Channel ID
762
+ * @returns {void}
696
763
  */
697
764
  startTyping(channelId) {
698
765
  try {
@@ -706,6 +773,7 @@ class Client extends EventEmitter {
706
773
  /**
707
774
  * Stops typing indicator in a channel
708
775
  * @param {string} channelId - Channel ID
776
+ * @returns {void}
709
777
  */
710
778
  stopTyping(channelId) {
711
779
  try {
@@ -746,13 +814,12 @@ class Client extends EventEmitter {
746
814
  /**
747
815
  * Fetches all available emojis
748
816
  * @param {Object} options - Fetch options
749
- * @param {boolean} options.includeOthers - Include emojis from other users
750
817
  * @param {string} options.search - Search query
751
818
  * @returns {Promise<Emoji[]>} Array of emoji objects
752
819
  */
753
820
  async fetchAllEmojis(options = {}) {
754
821
  try {
755
- const endpoint = options.includeOthers ? '/api/emojis/all' : '/api/emojis';
822
+ const endpoint = '/api/emojis/all';
756
823
  const params = {};
757
824
 
758
825
  if (options.search) {
@@ -760,7 +827,9 @@ class Client extends EventEmitter {
760
827
  }
761
828
 
762
829
  const res = await this._axios.get(endpoint, { params });
830
+
763
831
  const emojis = res.data.map(e => {
832
+ if (!e.user_id) e.user_id = this.user.id;
764
833
  const emoji = new Emoji(e);
765
834
  this.cache.emojis.set(emoji.id, emoji);
766
835
  return emoji;
@@ -768,7 +837,9 @@ class Client extends EventEmitter {
768
837
 
769
838
  return emojis;
770
839
  } catch (error) {
771
- throw error instanceof ClientError ? error : new ClientError(error.message, "FETCH_EMOJIS_ERROR");
840
+ throw error instanceof ClientError
841
+ ? error
842
+ : new ClientError(error.message, "FETCH_EMOJIS_ERROR");
772
843
  }
773
844
  }
774
845
 
@@ -849,6 +920,7 @@ class Client extends EventEmitter {
849
920
 
850
921
  /**
851
922
  * Clears all cached data
923
+ * @returns {void}
852
924
  */
853
925
  clearCache() {
854
926
  this.cache.users.clear();
@@ -945,7 +1017,7 @@ class Client extends EventEmitter {
945
1017
  });
946
1018
 
947
1019
  this.socket.on("reconnect_error", (error) => {
948
- this.emit("reconnectError", error);
1020
+ this.emit("error", error);
949
1021
  });
950
1022
 
951
1023
  this.socket.on("reconnect_failed", () => {
@@ -1231,12 +1303,21 @@ class Client extends EventEmitter {
1231
1303
  const msg = new Message(data, this);
1232
1304
 
1233
1305
  if (!msg.author && data.user_id) {
1234
- msg.author = new User({
1235
- id: data.user_id,
1236
- username: data.username,
1237
- display_name: data.display_name,
1238
- avatar_url: data.avatar_url
1239
- }, this);
1306
+ const cachedUser = this.cache.users.get(data.user_id);
1307
+ if (cachedUser) {
1308
+ cachedUser.username = data.username || cachedUser.username;
1309
+ cachedUser.displayName = data.display_name || cachedUser.displayName;
1310
+ cachedUser.avatarUrl = formatUrl(data.avatar_url) || cachedUser.avatarUrl;
1311
+ msg.author = cachedUser;
1312
+ } else {
1313
+ msg.author = new User({
1314
+ id: data.user_id,
1315
+ username: data.username,
1316
+ display_name: data.display_name,
1317
+ avatar_url: data.avatar_url,
1318
+ }, this);
1319
+ this.cache.users.set(msg.author.id, msg.author);
1320
+ }
1240
1321
  }
1241
1322
 
1242
1323
  if (!msg.channel && data.channel_id) {
@@ -1435,11 +1516,41 @@ class Client extends EventEmitter {
1435
1516
  throw new ClientError(`File upload error: ${error.message}`, 'UPLOAD_FAILED');
1436
1517
  }
1437
1518
  }
1519
+
1520
+ // ============================================================================
1521
+ // EVENT EMITTER OVERRIDES
1522
+ // ============================================================================
1523
+
1524
+ /**
1525
+ * Attaches an event listener.
1526
+ * @superInternal
1527
+ * @template {keyof ClientEvents} K
1528
+ * @param {K} event The event name.
1529
+ * @param {(arg: ClientEvents[K]) => void} listener
1530
+ * @returns {this}
1531
+ */
1532
+ on(event, listener) {
1533
+ return super.on(event, listener);
1534
+ }
1535
+
1536
+ /**
1537
+ * Emits an event with typed arguments.
1538
+ * @internal
1539
+ * @template {keyof ClientEvents} K
1540
+ * @param {K} event
1541
+ * @param {ClientEvents[K]} payload
1542
+ * @returns {this}
1543
+ */
1544
+ emit(event, payload) {
1545
+ return super.emit(event, payload);
1546
+ }
1438
1547
  }
1439
1548
 
1549
+ /**
1550
+ * @internal
1551
+ */
1440
1552
  class ClientError extends Error {
1441
1553
  /**
1442
- * @private
1443
1554
  * @param {string} message - Error message
1444
1555
  * @param {string} code - Error code
1445
1556
  */
package/README.md CHANGED
@@ -1,29 +1,54 @@
1
- # Beniocord.js
1
+ # Getting Started
2
2
 
3
- **Beniocord.js** is a Node.js library for creating bots easily, with basic moderation features, automatic responses, and event handling.
3
+ ## Introduction <span style="font-size:0.8em;">Intro</span>
4
4
 
5
- > ⚠️ This is an early version — meant to give you a starting point for building your bot.
5
+ ### Beniocord.js
6
+
7
+ A powerful JavaScript library for building Beniocord bots with ease.
8
+
9
+ [![npm version](https://img.shields.io/npm/v/beniocord.js?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/beniocord.js)
10
+ [![npm downloads](https://img.shields.io/npm/dt/beniocord.js?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/beniocord.js)
11
+ [![GitHub stars](https://img.shields.io/github/stars/Junior37534/beniocord.js?color=yellow&logo=github&style=flat-square)](https://github.com/Junior37534/beniocord.js)
12
+ [![GitHub issues](https://img.shields.io/github/issues/Junior37534/beniocord.js?color=green&logo=github&style=flat-square)](https://github.com/Junior37534/beniocord.js/issues)
13
+ [![Join Beniocord](https://img.shields.io/badge/Join-Beniocord-5865F2?style=flat-square&logoColor=white)](https://beniocord.site/register)
14
+
15
+ ---
16
+
17
+ ### About
18
+
19
+ Beniocord.js is a powerful Node.js module that allows you to easily interact with the Beniocord API. It provides an intuitive and modern approach to bot development.
20
+
21
+ ### Features
22
+
23
+ - 🚀 Easy to use and beginner-friendly
24
+ - ⚡ Fast and efficient
25
+ - 📦 Object-oriented design
26
+ - 🔄 Promise-based architecture
27
+ - 🎯 Full Beniocord API coverage
28
+ - 💪 TypeScript support
29
+
30
+ ### Requirements
31
+
32
+ - Node.js >= 18
33
+ - NPM >= 9
6
34
 
7
35
  ---
8
36
 
9
37
  ## Installation
10
38
 
39
+ Install via NPM:
40
+
11
41
  ```bash
12
42
  npm install beniocord.js
13
- ```
14
-
15
- > Make sure you have Node.js >= 18 installed.
43
+ ````
16
44
 
17
45
  ---
18
46
 
19
- ## Basic Example
47
+ ## Quick Example
20
48
 
21
49
  ```js
22
- const Client = require("beniocord.js");
23
- const { MessageEmbed } = Client;
24
- require('dotenv').config();
25
-
26
- const client = new Client({ token: process.env.BOT_TOKEN });
50
+ const Beniocord = require("beniocord.js");
51
+ const client = new Beniocord({ token: 'YOUR_BOT_TOKEN' });
27
52
 
28
53
  client.on("ready", () => {
29
54
  console.log("🤖 Bot connected!");
@@ -31,20 +56,21 @@ client.on("ready", () => {
31
56
 
32
57
  client.on("messageCreate", async (msg) => {
33
58
  if (msg.author?.id === client.user?.id) return;
34
- if (!msg.content) return;
59
+ if (!msg.content.startsWith('!')) return;
35
60
 
36
- if (msg.content.toLowerCase() === "!ping") {
37
- await client.sendMessage(msg.channel.id, "🏓 Pong!");
38
- }
39
-
40
- if (msg.content.toLowerCase() === "!embed") {
41
- const embed = new MessageEmbed()
42
- .setTitle("Hello from Beniocord!")
43
- .setDescription("This is an example embed")
44
- .setColor("#147bba")
45
- .setFooter(msg.author.displayName, msg.author.avatarURL());
46
-
47
- await msg.reply(embed);
61
+ const comando = msg.content.slice('!'.length).split(' ')[0];
62
+ const args = msg.content.slice(comando.length + '!'.length + 1).trim().split(' ');
63
+
64
+ if (comando === "ping") {
65
+ const msgTimestamp = Date.now() - Date.parse(msg.createdAt);
66
+ const sent = await msg.channel.send("🏓 Pinging...");
67
+ const editTimestamp = Date.now() - Date.parse(sent.createdAt);
68
+
69
+ await sent.edit(
70
+ `🏓 **Pong!**\n` +
71
+ `📨 **Message → Bot:** ${msgTimestamp}ms\n` +
72
+ `✏️ **Send → Edit:** ${editTimestamp}ms`
73
+ );
48
74
  }
49
75
  });
50
76
 
@@ -53,24 +79,8 @@ client.login();
53
79
 
54
80
  ---
55
81
 
56
- ## Features
57
-
58
- * **Basic events**: `messageCreate`, `messageEdit`, `messageDelete`, `memberJoin`, `memberLeave`, `presenceUpdate`, `channelUpdate`, and more.
59
- * **Basic moderation**: delete messages, edit messages, etc.
60
- * **Embeds support**: create rich messages with `MessageEmbed`.
61
- * **Event-driven**: easy to handle events in real-time.
62
-
63
- ---
64
-
65
- ## Events
66
-
67
- ```js
68
- client.on("messageCreate", msg => {...});
69
- client.on("memberJoin", data => {...});
70
- client.on("channelUpdate", data => {...});
71
- // and many more...
72
- ```
73
-
74
- You can add custom events and interact with your bot in real-time.
82
+ ## Useful Links
75
83
 
76
- ---
84
+ * [Official Website](https://beniocord.site)
85
+ * [Documentation](https://docs.beniocord.site)
86
+ * [Join Beniocord](https://beniocord.site/register)
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "socket.io-client": "^4.8.1"
6
6
  },
7
7
  "name": "beniocord.js",
8
- "version": "2.1.0",
8
+ "version": "2.1.1",
9
9
  "description": "Uma biblioteca leve e intuitiva para integração com APIs de bots em plataformas de mensagens, como Discord. Facilita o envio de mensagens, gerenciamento de canais e interação com usuários, proporcionando uma experiência de desenvolvimento ágil e eficiente.",
10
10
  "main": "Client.js",
11
11
  "scripts": {
@@ -3,7 +3,45 @@ const MessageCollector = require('./MessageCollector');
3
3
  const Collection = require('@discordjs/collection').Collection;
4
4
 
5
5
  let client;
6
+
7
+ /**
8
+ * @internal
9
+ */
6
10
  class Channel {
11
+ /**
12
+ * Creates a new Channel instance.
13
+ * @param {Object} data - Raw channel data.
14
+ * @param {string|number} data.id - The unique ID of the channel.
15
+ * @param {string} data.name - The name of the channel.
16
+ * @param {string} [data.description] - The channel description.
17
+ * @param {string} [data.type="text"] - The type of the channel (text, voice, etc.).
18
+ * @param {string} [data.icon_url] - The URL of the channel icon.
19
+ * @param {string|number} data.created_by - ID of the channel owner.
20
+ * @param {boolean} [data.is_private=false] - Whether the channel is private.
21
+ * @param {boolean} [data.is_locked=false] - Whether the channel is locked.
22
+ * @param {number|string} [data.member_count=0] - Number of members in the channel.
23
+ * @param {string|Date} data.created_at - Creation timestamp.
24
+ * @param {string|Date} data.updated_at - Last update timestamp.
25
+ * @param {import('./Client')} clientInstance - The client instance.
26
+ * @returns {Channel} The created Channel instance.
27
+ * @example
28
+ * // msg.channel
29
+ * Channel {
30
+ * id: 2,
31
+ * name: 'Privado',
32
+ * description: 'DM Privada para conversar secretas!\n',
33
+ * type: 'text',
34
+ * iconUrl: 'https://api.beniocord.site/uploads/1762899895145-938680330.gif',
35
+ * ownerId: 1,
36
+ * isPrivate: true,
37
+ * isLocked: false,
38
+ * memberCount: 8,
39
+ * createdAt: '2025-09-21T15:28:43.610Z',
40
+ * updatedAt: '2025-11-11T23:49:54.906Z',
41
+ * members: Collection(0) [Map] { fetch: [AsyncFunction (anonymous)] },
42
+ * messages: Collection(0) [Map] { fetch: [AsyncFunction (anonymous)] }
43
+ * }
44
+ */
7
45
  constructor(data, clientInstance) {
8
46
  client = clientInstance;
9
47
 
@@ -19,6 +57,10 @@ class Channel {
19
57
  this.createdAt = data.created_at;
20
58
  this.updatedAt = data.updated_at;
21
59
 
60
+ /**
61
+ * Cached members of the channel.
62
+ * @type {Collection<string, import('./User')>}
63
+ */
22
64
  this.members = new Collection();
23
65
  this.members.fetch = async () => {
24
66
  const members = await client.fetchChannelMembers(this.id);
@@ -29,6 +71,10 @@ class Channel {
29
71
  return this.members;
30
72
  };
31
73
 
74
+ /**
75
+ * Cached messages of the channel.
76
+ * @type {Collection<string, import('./Message')>}
77
+ */
32
78
  this.messages = new Collection();
33
79
  this.messages.fetch = async (id) => {
34
80
  if (client.fetchMessage) {
@@ -46,22 +92,40 @@ class Channel {
46
92
  });
47
93
  }
48
94
 
95
+ /**
96
+ * Sends a message to the channel.
97
+ * @param {string|Object} content - The content of the message.
98
+ * @param {Object} [opts] - Optional message options.
99
+ * @returns {Promise<import('./Message')>} The sent message.
100
+ */
49
101
  async send(content, opts = {}) {
50
102
  return client.sendMessage(this.id, content, opts);
51
103
  }
52
104
 
105
+ /**
106
+ * Starts typing indicator in the channel.
107
+ * @returns {Promise<void>}
108
+ */
53
109
  startTyping() {
54
110
  return client.startTyping(this.id);
55
111
  }
56
112
 
113
+ /**
114
+ * Stops typing indicator in the channel.
115
+ * @returns {Promise<void>}
116
+ */
57
117
  stopTyping() {
58
118
  return client.stopTyping(this.id);
59
119
  }
60
120
 
121
+ /**
122
+ * Creates a new message collector in this channel.
123
+ * @param {Object} [options={}] - Collector options.
124
+ * @returns {MessageCollector} The created message collector.
125
+ */
61
126
  createMessageCollector(options = {}) {
62
127
  return new MessageCollector(this, options, client);
63
128
  }
64
-
65
129
  }
66
130
 
67
131
  module.exports = Channel;
@@ -1,14 +1,59 @@
1
1
  const { formatUrl } = require("../helpers");
2
2
 
3
+ /**
4
+ * @internal
5
+ */
3
6
  class Emoji {
7
+ /**
8
+ * Creates a new Emoji instance.
9
+ * @param {Object} data - Raw emoji data.
10
+ * @param {string|number} data.id - The unique ID of the emoji.
11
+ * @param {string|number} data.user_id - The ID of the user who uploaded the emoji.
12
+ * @param {string} data.name - The name of the emoji.
13
+ * @param {string} data.url - The URL of the emoji image.
14
+ * @param {string|number|Date} data.created_at - Timestamp when the emoji was created.
15
+ * @returns {Emoji} The created Emoji instance.
16
+ * @example
17
+ * Emoji {
18
+ * id: 1,
19
+ * userId: 1,
20
+ * name: 'shitcord',
21
+ * url: 'https://api.beniocord.site/uploads/emojis/1758982533925-364594757.png',
22
+ * createdAt: '2025-09-27T14:15:33.932Z'
23
+ * }
24
+ *
25
+ */
4
26
  constructor(data) {
27
+ /**
28
+ * The unique ID of the emoji.
29
+ * @type {string|number}
30
+ */
5
31
  this.id = data.id;
32
+
33
+ /**
34
+ * The ID of the user who uploaded the emoji.
35
+ * @type {string|number}
36
+ */
6
37
  this.userId = data.user_id;
38
+
39
+ /**
40
+ * The name of the emoji.
41
+ * @type {string}
42
+ */
7
43
  this.name = data.name;
44
+
45
+ /**
46
+ * The URL of the emoji image.
47
+ * @type {string}
48
+ */
8
49
  this.url = formatUrl(data.url);
50
+
51
+ /**
52
+ * Timestamp when the emoji was created.
53
+ * @type {string|number|Date}
54
+ */
9
55
  this.createdAt = data.created_at;
10
- this.updatedAt = data.updated_at;
11
56
  }
12
57
  }
13
58
 
14
- module.exports = Emoji;
59
+ module.exports = Emoji;
@@ -5,7 +5,7 @@ const { formatUrl } = require('../helpers/index');
5
5
  let client;
6
6
 
7
7
  /**
8
- * Represents a message in a channel.
8
+ * @internal
9
9
  */
10
10
  class Message {
11
11
  /**
@@ -23,11 +23,48 @@ class Message {
23
23
  * @param {string|number} [data.sticker_id] - ID of a sticker attached to the message.
24
24
  * @param {string|number|Date} [data.edited_at] - Timestamp when the message was edited.
25
25
  * @param {string|number|Date} [data.created_at] - Timestamp when the message was created.
26
- * @param {Object} clientInstance - The client instance to send/edit/delete messages.
26
+ * @param {Object} clientInstance - The client instance.
27
+ * @returns {Message} The created Message instance.
27
28
  * @example
28
- * // Creating a message instance
29
- * const msg = new Message({ id: 1, content: "Hello!" }, client);
30
- *
29
+ * Message {
30
+ * id: 20711,
31
+ * content: 'Hello World!',
32
+ * messageType: 'text',
33
+ * fileUrl: null,
34
+ * fileName: null,
35
+ * fileSize: null,
36
+ * attachments: [],
37
+ * replyTo: 20709,
38
+ * stickerId: null,
39
+ * editedAt: null,
40
+ * createdAt: '2025-11-16T14:29:40.598Z',
41
+ * author: User {
42
+ * id: 1,
43
+ * username: 'junior9244',
44
+ * displayName: 'Junior',
45
+ * avatarUrl: 'https://api.beniocord.site/uploads/avatars/1760736025811-629632107.png',
46
+ * status: 'online',
47
+ * emblems: [],
48
+ * isBot: false,
49
+ * lastSeen: '2025-11-16T14:29:40.598Z',
50
+ * createdAt: '2025-11-16T14:29:40.598Z'
51
+ * },
52
+ * channel: Channel {
53
+ * id: 2,
54
+ * name: 'Privado',
55
+ * description: 'DM Privada para conversar secretas!\n',
56
+ * type: 'text',
57
+ * iconUrl: 'https://api.beniocord.site/uploads/1762899895145-938680330.gif',
58
+ * ownerId: 1,
59
+ * isPrivate: true,
60
+ * isLocked: false,
61
+ * memberCount: 8,
62
+ * createdAt: '2025-09-21T15:28:43.610Z',
63
+ * updatedAt: '2025-11-11T23:49:54.906Z',
64
+ * members: Collection(0) [Map] { fetch: [AsyncFunction (anonymous)] },
65
+ * messages: Collection(0) [Map] { fetch: [AsyncFunction (anonymous)] }
66
+ * }
67
+ * }
31
68
  */
32
69
  constructor(data, clientInstance) {
33
70
  this.id = data.id;
@@ -1,45 +1,68 @@
1
1
  const EventEmitter = require('events');
2
2
 
3
3
  class MessageCollector extends EventEmitter {
4
+ /**
5
+ * Creates a new MessageCollector.
6
+ *
7
+ * @param {Channel} channel - The channel to listen for messages.
8
+ * @param {Object} [options={}] - Options for the collector.
9
+ * @param {function(Message): boolean|Promise<boolean>} [options.filter] - Filter function to determine which messages are collected.
10
+ * @param {number} [options.time=60000] - Time in milliseconds before the collector stops automatically.
11
+ * @param {number} [options.max=Infinity] - Maximum number of messages to collect before stopping.
12
+ * @param {Client} client - The client instance to listen for events.
13
+ *
14
+ * @example
15
+ * const collector = new MessageCollector(channel, { filter: msg => msg.content.includes('hello'), time: 30000 }, client);
16
+ * collector.on('collect', msg => console.log(`Collected message: ${msg.content}`));
17
+ * collector.on('end', (collected, reason) => console.log(`Collector ended: ${reason}, collected ${collected.length} messages`));
18
+ */
4
19
  constructor(channel, options = {}, client) {
5
20
  super();
6
-
21
+
7
22
  this.channel = channel;
8
23
  this.client = client;
9
- // this.client = channel.client;
10
24
  this.filter = options.filter || (() => true);
11
25
  this.time = options.time || 60000;
12
26
  this.max = options.max || Infinity;
13
27
  this.collected = [];
14
28
  this.ended = false;
15
-
29
+
16
30
  this._timeout = null;
17
31
  this._handleMessage = this._handleMessage.bind(this);
18
-
32
+
19
33
  this._setup();
20
34
  }
21
-
35
+
36
+ /**
37
+ * Initializes event listeners and timeout for automatic stop.
38
+ * @private
39
+ */
22
40
  _setup() {
23
41
  this.client.on('messageCreate', this._handleMessage);
24
-
42
+
25
43
  if (this.time) {
26
44
  this._timeout = setTimeout(() => {
27
45
  this.stop('time');
28
46
  }, this.time);
29
47
  }
30
48
  }
31
-
49
+
50
+ /**
51
+ * Internal handler for incoming messages.
52
+ * @param {Message} message - The message received.
53
+ * @private
54
+ */
32
55
  async _handleMessage(message) {
33
56
  if (this.ended) return;
34
57
  if (message.channel.id !== this.channel.id) return;
35
-
58
+
36
59
  try {
37
60
  const filterResult = await this.filter(message);
38
61
  if (!filterResult) return;
39
-
62
+
40
63
  this.collected.push(message);
41
64
  this.emit('collect', message);
42
-
65
+
43
66
  if (this.collected.length >= this.max) {
44
67
  this.stop('limit');
45
68
  }
@@ -47,28 +70,40 @@ class MessageCollector extends EventEmitter {
47
70
  this.emit('error', error);
48
71
  }
49
72
  }
50
-
51
- stop(reason = 'user', ) {
73
+
74
+ /**
75
+ * Stops the collector manually or automatically.
76
+ *
77
+ * @param {string} [reason='user'] - Reason for stopping ('user', 'time', 'limit', etc.).
78
+ * @fires MessageCollector#end
79
+ */
80
+ stop(reason = 'user') {
52
81
  if (this.ended) return;
53
-
82
+
54
83
  this.ended = true;
55
-
84
+
56
85
  if (this._timeout) {
57
86
  clearTimeout(this._timeout);
58
87
  this._timeout = null;
59
88
  }
60
-
89
+
61
90
  this.client.removeListener('messageCreate', this._handleMessage);
62
91
  this.emit('end', this.collected, reason);
63
92
  }
64
-
93
+
94
+ /**
95
+ * Resets the timer for the collector.
96
+ *
97
+ * @param {Object} [options={}] - Options to override current timer.
98
+ * @param {number} [options.time] - New time in milliseconds to set.
99
+ */
65
100
  resetTimer(options = {}) {
66
101
  if (this._timeout) {
67
102
  clearTimeout(this._timeout);
68
103
  }
69
-
104
+
70
105
  const time = options.time || this.time;
71
-
106
+
72
107
  if (time) {
73
108
  this._timeout = setTimeout(() => {
74
109
  this.stop('time');
@@ -77,4 +112,23 @@ class MessageCollector extends EventEmitter {
77
112
  }
78
113
  }
79
114
 
80
- module.exports = MessageCollector;
115
+ /**
116
+ * Emitted when a message is successfully collected.
117
+ * @event MessageCollector#collect
118
+ * @param {Message} message - The collected message.
119
+ */
120
+
121
+ /**
122
+ * Emitted when the collector ends.
123
+ * @event MessageCollector#end
124
+ * @param {Message[]} collected - Array of collected messages.
125
+ * @param {string} reason - Reason the collector ended.
126
+ */
127
+
128
+ /**
129
+ * Emitted when an error occurs inside the collector.
130
+ * @event MessageCollector#error
131
+ * @param {Error} error - The error encountered.
132
+ */
133
+
134
+ module.exports = MessageCollector;
@@ -1,5 +1,8 @@
1
+ const { formatUrl } = require("../helpers");
2
+ let client;
3
+
1
4
  /**
2
- * Represents a user.
5
+ * @internal
3
6
  */
4
7
  class User {
5
8
  /**
@@ -10,13 +13,28 @@ class User {
10
13
  * @param {string} data.display_name - The display name of the user.
11
14
  * @param {string} data.avatar_url - The URL of the user's avatar.
12
15
  * @param {string} [data.status='offline'] - The user's status.
13
- * @param {Array<string>} [data.emblems=[]] - Array of user emblems.
16
+ * @param {Array<Object>} [data.emblems=[]] - Array of user emblems.
14
17
  * @param {boolean} data.is_bot - Whether the user is a bot.
15
18
  * @param {string|number|Date} data.last_seen - Last seen timestamp.
16
19
  * @param {string|number|Date} data.created_at - Account creation timestamp.
17
- * @param {Object} client - The client instance (optional, internal use).
20
+ * @param {import('./Client')} clientInstance - The client instance.
21
+ * @returns {User} The created User instance.
22
+ * @example
23
+ * User {
24
+ * id: 1,
25
+ * username: 'junior9244',
26
+ * displayName: 'Junior',
27
+ * avatarUrl: 'https://api.beniocord.site/uploads/avatars/1760736025811-629632107.png',
28
+ * status: 'online',
29
+ * emblems: [ [Object], [Object] ],
30
+ * isBot: false,
31
+ * lastSeen: '2025-11-16T14:44:19.394Z',
32
+ * createdAt: '2025-09-21T15:00:07.753Z'
33
+ * }
18
34
  */
19
- constructor(data, client) {
35
+ constructor(data, clientInstance) {
36
+ client = clientInstance;
37
+
20
38
  this.id = data.id;
21
39
  this.username = data.username;
22
40
  this.displayName = data.display_name;
@@ -31,10 +49,26 @@ class User {
31
49
  /**
32
50
  * Returns the avatar URL of the user.
33
51
  * @returns {string} The avatar URL.
52
+ * @example
53
+ * https://api.beniocord.site/uploads/avatars/1760736025811-629632107.png
34
54
  */
35
55
  avatarURL() {
36
56
  return this.avatarUrl;
37
57
  }
58
+
59
+ /**
60
+ * Fetches or refreshes this user from the API.
61
+ * @param {boolean} [force=false] - Whether to force fetch even if cached.
62
+ * @returns {Promise<User>} The updated User instance.
63
+ * @example
64
+ * const freshUser = await user.fetch();
65
+ */
66
+ async fetch(force = false) {
67
+ if (!client) throw new Error("Client instance not available.");
68
+ const updatedUser = await client.fetchUser(this.id, force);
69
+ Object.assign(this, updatedUser);
70
+ return this;
71
+ }
38
72
  }
39
73
 
40
- module.exports = User;
74
+ module.exports = User;
@@ -562,10 +562,21 @@ MessageEmbed.Colors = {
562
562
  };
563
563
 
564
564
  /**
565
- * MessageAttachment - Para anexos
566
565
  * @class
567
566
  */
568
567
  class MessageAttachment {
568
+ /**
569
+ * Creates a new MessageAttachment instance.
570
+ *
571
+ * @param {Buffer|Uint8Array|string} buffer - The data of the attachment. Can be a Buffer, Uint8Array, or base64 string.
572
+ * @param {string} name - The name of the attachment file (e.g., "image.png").
573
+ *
574
+ * @throws {Error} If the buffer is not provided.
575
+ * @throws {Error} If the name is not a valid string.
576
+ *
577
+ * @example
578
+ * const attachment = new MessageAttachment(fileBuffer, "photo.png");
579
+ */
569
580
  constructor(buffer, name) {
570
581
  if (!buffer) {
571
582
  throw new Error('Attachment buffer is required');