discord-self-lite 0.1.5 → 0.1.6
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/package.json
CHANGED
package/src/classes/BitField.js
CHANGED
|
@@ -90,7 +90,13 @@ class BitField {
|
|
|
90
90
|
return bit
|
|
91
91
|
.map((p) => this.resolve(p))
|
|
92
92
|
.reduce((prev, p) => prev | p, BitField.defaultBit);
|
|
93
|
-
if (typeof bit === "string")
|
|
93
|
+
if (typeof bit === "string") {
|
|
94
|
+
// Check if it's a numeric string (permission bitfield from API)
|
|
95
|
+
if (/^\d+$/.test(bit)) return BigInt(bit);
|
|
96
|
+
// Otherwise treat as flag name
|
|
97
|
+
return this.FLAGS[bit];
|
|
98
|
+
}
|
|
99
|
+
if (typeof bit === "number") return BigInt(bit);
|
|
94
100
|
throw new TypeError("BitField.resolve: Invalid bitfield");
|
|
95
101
|
}
|
|
96
102
|
}
|
package/src/classes/Channel.js
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const Permissions = require("./Permissions");
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Safe BigInt conversion
|
|
8
|
+
* @param {*} value - Value to convert to BigInt
|
|
9
|
+
* @returns {bigint} BigInt representation
|
|
10
|
+
*/
|
|
11
|
+
function toBigInt(value) {
|
|
12
|
+
if (typeof value === "bigint") return value;
|
|
13
|
+
if (typeof value === "string") return BigInt(value);
|
|
14
|
+
if (typeof value === "number") return BigInt(value);
|
|
15
|
+
return 0n;
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
class Channel {
|
|
7
19
|
/**
|
|
8
20
|
* Create a new Channel instance
|
|
@@ -170,7 +182,7 @@ class Channel {
|
|
|
170
182
|
* @returns {Permissions} Permissions bitfield for this member in this channel
|
|
171
183
|
*/
|
|
172
184
|
permissionsFor(member) {
|
|
173
|
-
if (!member) return new Permissions(
|
|
185
|
+
if (!member?.permissions) return new Permissions(toBigInt(0));
|
|
174
186
|
|
|
175
187
|
// Start with the member's base guild permissions
|
|
176
188
|
let permissions = member.permissions.bitfield;
|
|
@@ -193,8 +205,8 @@ class Channel {
|
|
|
193
205
|
memberRoles.includes(overwrite.id) ||
|
|
194
206
|
overwrite.id === this.data.guild_id
|
|
195
207
|
) {
|
|
196
|
-
permissions &= ~
|
|
197
|
-
permissions |=
|
|
208
|
+
permissions &= ~toBigInt(overwrite.deny || 0);
|
|
209
|
+
permissions |= toBigInt(overwrite.allow || 0);
|
|
198
210
|
}
|
|
199
211
|
}
|
|
200
212
|
}
|
|
@@ -204,13 +216,63 @@ class Channel {
|
|
|
204
216
|
(ow) => ow.type === 1 && ow.id === member.id,
|
|
205
217
|
);
|
|
206
218
|
if (memberOverwrite) {
|
|
207
|
-
permissions &= ~
|
|
208
|
-
permissions |=
|
|
219
|
+
permissions &= ~toBigInt(memberOverwrite.deny || 0);
|
|
220
|
+
permissions |= toBigInt(memberOverwrite.allow || 0);
|
|
209
221
|
}
|
|
210
222
|
}
|
|
211
223
|
|
|
212
224
|
return new Permissions(permissions);
|
|
213
225
|
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Wait for a message in this channel
|
|
229
|
+
* @param {object} [options={}] - Options for awaiting messages
|
|
230
|
+
* @param {Function} [options.filter] - Filter function for messages (must return true/false)
|
|
231
|
+
* @param {number} [options.time=30000] - Timeout in milliseconds
|
|
232
|
+
* @param {boolean} [options.errors=true] - Whether to reject on timeout
|
|
233
|
+
* @returns {Promise<Message>} The matching message
|
|
234
|
+
* @throws {Error} If timeout is reached and errors is true
|
|
235
|
+
* @example
|
|
236
|
+
* // Wait for any message
|
|
237
|
+
* const msg = await channel.awaitMessage();
|
|
238
|
+
*
|
|
239
|
+
* // Wait for a message from specific user
|
|
240
|
+
* const msg = await channel.awaitMessage({
|
|
241
|
+
* filter: (m) => m.author.id === '123456789',
|
|
242
|
+
* time: 60000
|
|
243
|
+
* });
|
|
244
|
+
*
|
|
245
|
+
* // Wait for message with specific content patterns
|
|
246
|
+
* const msg = await channel.awaitMessage({
|
|
247
|
+
* filter: (m) => m.author.id === userId &&
|
|
248
|
+
* (m.content.includes('yes') || m.content.includes('confirm')),
|
|
249
|
+
* time: 30000
|
|
250
|
+
* });
|
|
251
|
+
*/
|
|
252
|
+
async awaitMessage(options = {}) {
|
|
253
|
+
const { filter = () => true, time = 30000, errors = true } = options;
|
|
254
|
+
|
|
255
|
+
return new Promise((resolve, reject) => {
|
|
256
|
+
const listener = (message) => {
|
|
257
|
+
if (message.channelId === this.id && filter(message)) {
|
|
258
|
+
this.client.removeListener("messageCreate", listener);
|
|
259
|
+
clearTimeout(timeout);
|
|
260
|
+
resolve(message);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const timeout = setTimeout(() => {
|
|
265
|
+
this.client.removeListener("messageCreate", listener);
|
|
266
|
+
if (errors) {
|
|
267
|
+
reject(new Error("Message await timed out"));
|
|
268
|
+
} else {
|
|
269
|
+
resolve(null);
|
|
270
|
+
}
|
|
271
|
+
}, time);
|
|
272
|
+
|
|
273
|
+
this.client.on("messageCreate", listener);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
214
276
|
}
|
|
215
277
|
|
|
216
278
|
module.exports = Channel;
|
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const Permissions = require("./Permissions");
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Safe BigInt conversion
|
|
8
|
+
* @param {*} value - Value to convert to BigInt
|
|
9
|
+
* @returns {bigint} BigInt representation
|
|
10
|
+
*/
|
|
11
|
+
function toBigInt(value) {
|
|
12
|
+
if (typeof value === "bigint") return value;
|
|
13
|
+
if (typeof value === "string") return BigInt(value);
|
|
14
|
+
if (typeof value === "number") return BigInt(value);
|
|
15
|
+
return 0n;
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
class GuildMember {
|
|
7
19
|
/**
|
|
8
20
|
* Create a new GuildMember instance
|
|
@@ -58,7 +70,7 @@ class GuildMember {
|
|
|
58
70
|
if (this._permissions) return this._permissions;
|
|
59
71
|
|
|
60
72
|
// Calculate permissions based on roles
|
|
61
|
-
let permissions =
|
|
73
|
+
let permissions = 0n;
|
|
62
74
|
|
|
63
75
|
// If member is the guild owner, they have all permissions
|
|
64
76
|
if (this.id === this.guild.ownerId) {
|
|
@@ -68,15 +80,15 @@ class GuildMember {
|
|
|
68
80
|
const everyoneRole = this.guild.roles?.find(
|
|
69
81
|
(role) => role.id === this.guild.id,
|
|
70
82
|
);
|
|
71
|
-
if (everyoneRole) {
|
|
72
|
-
permissions |=
|
|
83
|
+
if (everyoneRole && everyoneRole.permissions != null) {
|
|
84
|
+
permissions |= toBigInt(everyoneRole.permissions);
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
// Add permissions from member's roles
|
|
76
88
|
for (const roleId of this.roles || []) {
|
|
77
89
|
const role = this.guild.roles?.find((r) => r.id === roleId);
|
|
78
|
-
if (role) {
|
|
79
|
-
permissions |=
|
|
90
|
+
if (role && role.permissions != null) {
|
|
91
|
+
permissions |= toBigInt(role.permissions);
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
94
|
}
|
|
@@ -81,7 +81,7 @@ class RestManager {
|
|
|
81
81
|
) {
|
|
82
82
|
const delay = rateLimit.reset - Date.now();
|
|
83
83
|
console.log(
|
|
84
|
-
`⏳ Route rate limit for ${routeKey}, waiting ${delay}ms`,
|
|
84
|
+
`⏳ Route rate limit for ${routeKey} (${endpoint}), waiting ${delay}ms`,
|
|
85
85
|
);
|
|
86
86
|
await this.sleep(delay);
|
|
87
87
|
}
|
|
@@ -129,14 +129,15 @@ class RestManager {
|
|
|
129
129
|
// Handle rate limiting
|
|
130
130
|
if (response.status === 429) {
|
|
131
131
|
const retryAfter =
|
|
132
|
-
parseInt(response.headers.get("retry-after")) * 1000;
|
|
132
|
+
parseInt(response.headers.get("retry-after")) * 1000 + 1000;
|
|
133
133
|
const isGlobal =
|
|
134
134
|
response.headers.get("x-ratelimit-global") === "true";
|
|
135
|
+
const routeKey = this.getRouteKey(endpoint, options.method || "GET");
|
|
135
136
|
|
|
136
137
|
console.log(
|
|
137
138
|
`🚫 Rate limited! ${
|
|
138
|
-
isGlobal ? "Global" :
|
|
139
|
-
} limit, retry after ${retryAfter}ms`,
|
|
139
|
+
isGlobal ? "Global" : `Route (${routeKey})`
|
|
140
|
+
} limit for ${endpoint}, retry after ${retryAfter}ms`,
|
|
140
141
|
);
|
|
141
142
|
|
|
142
143
|
if (isGlobal) {
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
const DiscordAPIError = require("../../classes/DiscordAPIError");
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Convert a color value to Discord's expected integer format
|
|
5
|
+
* @param {*} color - Color value (hex string, number, etc.)
|
|
6
|
+
* @returns {number|null} Integer color value or null
|
|
7
|
+
*/
|
|
8
|
+
function resolveColor(color) {
|
|
9
|
+
if (color === null || color === undefined) return null;
|
|
10
|
+
if (typeof color === "number") return color;
|
|
11
|
+
if (typeof color === "string") {
|
|
12
|
+
// Handle hex colors
|
|
13
|
+
if (color.startsWith("#")) {
|
|
14
|
+
return parseInt(color.slice(1), 16);
|
|
15
|
+
}
|
|
16
|
+
// Handle other string formats if needed
|
|
17
|
+
return parseInt(color, 16);
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
3
22
|
class WebhookClient {
|
|
4
23
|
/**
|
|
5
24
|
* Create a new WebhookClient
|
|
@@ -186,7 +205,10 @@ class WebhookClient {
|
|
|
186
205
|
payload.avatar_url = options.avatarURL;
|
|
187
206
|
}
|
|
188
207
|
if (options.embeds) {
|
|
189
|
-
payload.embeds = options.embeds
|
|
208
|
+
payload.embeds = options.embeds.map((embed) => ({
|
|
209
|
+
...embed,
|
|
210
|
+
color: resolveColor(embed.color),
|
|
211
|
+
}));
|
|
190
212
|
}
|
|
191
213
|
if (options.tts !== undefined) {
|
|
192
214
|
payload.tts = options.tts;
|
|
@@ -212,11 +234,11 @@ class WebhookClient {
|
|
|
212
234
|
description: data.description || null,
|
|
213
235
|
url: data.url || null,
|
|
214
236
|
timestamp: data.timestamp || null,
|
|
215
|
-
color: data.color
|
|
237
|
+
color: resolveColor(data.color),
|
|
216
238
|
footer: data.footer
|
|
217
239
|
? {
|
|
218
240
|
text: data.footer.text,
|
|
219
|
-
icon_url: data.footer.iconURL,
|
|
241
|
+
icon_url: data.footer.iconURL || data.footer.icon_url,
|
|
220
242
|
}
|
|
221
243
|
: null,
|
|
222
244
|
image: data.image ? { url: data.image } : null,
|
|
@@ -225,7 +247,7 @@ class WebhookClient {
|
|
|
225
247
|
? {
|
|
226
248
|
name: data.author.name,
|
|
227
249
|
url: data.author.url,
|
|
228
|
-
icon_url: data.author.iconURL,
|
|
250
|
+
icon_url: data.author.iconURL || data.author.icon_url,
|
|
229
251
|
}
|
|
230
252
|
: null,
|
|
231
253
|
fields: data.fields || [],
|