discord-sb.js 1.0.1 → 1.0.3

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-sb.js",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "An unofficial discord.js fork for creating selfbots",
5
5
  "main": "./src/index.js",
6
6
  "types": "./typings/index.d.ts",
package/src/WebSocket.js CHANGED
@@ -8,7 +8,7 @@ try {
8
8
  if (!erlpack.pack) erlpack = null;
9
9
  } catch {} // eslint-disable-line no-empty
10
10
 
11
- exports.WebSocket = WebSocket;
11
+ exports.WebSocket = WebSocket; // eslint-disable-line
12
12
 
13
13
  const ab = new TextDecoder();
14
14
 
@@ -457,6 +457,31 @@ class Client extends BaseClient {
457
457
  return regions;
458
458
  }
459
459
 
460
+ /**
461
+ * Requests a sync of guild data with Discord. Only works for user accounts.
462
+ * @param {Guild[]|Collection<Snowflake, Guild>} [guilds=this.guilds] Guilds to sync
463
+ * @returns {void}
464
+ */
465
+ syncGuilds(guilds = this.guilds) {
466
+ if (this.user?.bot) return;
467
+ // Avoid rebuilding arrays if already mapped once
468
+ const ids = guilds instanceof Collection ? guilds.map((_, id) => id) : guilds.map(g => g.id);
469
+ this.ws.send({
470
+ op: 12,
471
+ d: ids,
472
+ });
473
+ }
474
+
475
+ /**
476
+ * Obtains a user from Discord, or the user cache if it's already available.
477
+ * @param {UserResolvable} user The user to fetch
478
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
479
+ * @returns {Promise<User>}
480
+ */
481
+ fetchUser(user, options = {}) {
482
+ return this.users.fetch(user, options);
483
+ }
484
+
460
485
  /**
461
486
  * Obtains a sticker from Discord.
462
487
  * @param {Snowflake} id The sticker's id
@@ -812,34 +837,37 @@ class Client extends BaseClient {
812
837
  /**
813
838
  * Install User Apps
814
839
  * @param {Snowflake} applicationId Discord Application id
815
- * @returns {Promise<void>}
816
- */
817
- installUserApps(applicationId) {
818
- return this.api
819
- .applications(applicationId)
820
- .public.get({
821
- query: {
822
- with_guild: false,
840
+ * @param {string[]|string} [scopes=['applications.commands']] OAuth scopes to request when installing
841
+ * @returns {Promise<boolean>}
842
+ */
843
+ async installUserApps(applicationId, scopes = ['applications.commands']) {
844
+ const scope = Array.isArray(scopes) ? scopes.join(' ') : scopes;
845
+ await this.api.oauth2.authorize.post({
846
+ query: {
847
+ client_id: applicationId,
848
+ scope,
849
+ },
850
+ data: {
851
+ permissions: '0',
852
+ authorize: true,
853
+ integration_type: 1,
854
+ dm_settings: {
855
+ allow_mobile_push: false,
823
856
  },
824
- })
825
- .then(rawData => {
826
- const installTypes = rawData.integration_types_config['1'];
827
- if (installTypes) {
828
- return this.api.oauth2.authorize.post({
829
- query: {
830
- client_id: applicationId,
831
- scope: installTypes.oauth2_install_params.scopes.join(' '),
832
- },
833
- data: {
834
- permissions: '0',
835
- authorize: true,
836
- integration_type: 1,
837
- },
838
- });
839
- } else {
840
- return false;
841
- }
842
- });
857
+ },
858
+ });
859
+
860
+ return true;
861
+ }
862
+
863
+ /**
864
+ * Uninstall a previously authorized user application.
865
+ * @param {Snowflake} applicationId Discord Application id
866
+ * @returns {Promise<boolean>}
867
+ */
868
+ async unInstallUserApp(applicationId) {
869
+ await this.api.oauth2.tokens(applicationId).delete();
870
+ return true;
843
871
  }
844
872
 
845
873
  /**
@@ -10,10 +10,6 @@ const DataResolver = require('../util/DataResolver');
10
10
  * @extends {BaseManager}
11
11
  */
12
12
  class DeveloperManager extends BaseManager {
13
- constructor(client) {
14
- super(client);
15
- }
16
-
17
13
  /**
18
14
  * Fetches all applications owned by the current user
19
15
  * @param {boolean} [withTeamApplications=true] Whether to include team applications
@@ -81,15 +77,30 @@ class DeveloperManager extends BaseManager {
81
77
  async edit(applicationId, data) {
82
78
  const _data = {};
83
79
 
84
- if (data.name) _data.name = data.name;
85
- if (data.description !== undefined) _data.description = data.description;
86
- if (data.icon !== undefined) _data.icon = await DataResolver.resolveImage(data.icon);
87
- if (data.tags) _data.tags = data.tags;
88
- if (data.interactionsEndpointUrl !== undefined) _data.interactions_endpoint_url = data.interactionsEndpointUrl;
89
- if (data.roleConnectionsVerificationUrl !== undefined)
80
+ if (data.name) {
81
+ _data.name = data.name;
82
+ }
83
+ if (data.description !== undefined) {
84
+ _data.description = data.description;
85
+ }
86
+ if (data.icon !== undefined) {
87
+ _data.icon = await DataResolver.resolveImage(data.icon);
88
+ }
89
+ if (data.tags) {
90
+ _data.tags = data.tags;
91
+ }
92
+ if (data.interactionsEndpointUrl !== undefined) {
93
+ _data.interactions_endpoint_url = data.interactionsEndpointUrl;
94
+ }
95
+ if (data.roleConnectionsVerificationUrl !== undefined) {
90
96
  _data.role_connections_verification_url = data.roleConnectionsVerificationUrl;
91
- if (data.termsOfServiceUrl !== undefined) _data.terms_of_service_url = data.termsOfServiceUrl;
92
- if (data.privacyPolicyUrl !== undefined) _data.privacy_policy_url = data.privacyPolicyUrl;
97
+ }
98
+ if (data.termsOfServiceUrl !== undefined) {
99
+ _data.terms_of_service_url = data.termsOfServiceUrl;
100
+ }
101
+ if (data.privacyPolicyUrl !== undefined) {
102
+ _data.privacy_policy_url = data.privacyPolicyUrl;
103
+ }
93
104
 
94
105
  const result = await this.client.api.applications(applicationId).patch({ data: _data });
95
106
  return new Application(this.client, result);
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const { setTimeout } = require('node:timers');
3
4
  const { Collection } = require('@discordjs/collection');
4
5
  const BaseManager = require('./BaseManager');
5
6
 
@@ -90,6 +91,14 @@ class QuestManager extends BaseManager {
90
91
  return data;
91
92
  }
92
93
 
94
+ /**
95
+ * Refresh the quest cache from the API
96
+ * @returns {Promise<Object>} Latest quest data
97
+ */
98
+ async refreshCache() {
99
+ return this.get();
100
+ }
101
+
93
102
  /**
94
103
  * Get user's orb balance (virtual currency)
95
104
  * @returns {Promise<Object>} Balance data
@@ -197,19 +206,22 @@ class QuestManager extends BaseManager {
197
206
  quest.updateUserStatus(data);
198
207
  }
199
208
 
200
- return quest;
209
+ await this.refreshCache();
210
+ return this.getQuest(questId);
201
211
  }
202
212
 
203
213
  /**
204
214
  * Update progress for a video quest
205
215
  * @param {string} questId The quest ID
206
216
  * @param {number} timestamp Current progress timestamp
217
+ * @param {boolean} [refresh=true] Whether to refresh the quest cache after the update
207
218
  * @returns {Promise<Object>} Progress update result
208
219
  */
209
- async videoProgress(questId, timestamp) {
220
+ async videoProgress(questId, timestamp, refresh = true) {
210
221
  const data = await this.client.api.quests(questId)['video-progress'].post({
211
222
  data: { timestamp },
212
223
  });
224
+ if (refresh) await this.refreshCache();
213
225
  return data;
214
226
  }
215
227
 
@@ -218,15 +230,17 @@ class QuestManager extends BaseManager {
218
230
  * @param {string} questId The quest ID
219
231
  * @param {string} applicationId Application ID
220
232
  * @param {boolean} [terminal=false] Whether this is a terminal heartbeat
233
+ * @param {boolean} [refresh=true] Whether to refresh the quest cache after the update
221
234
  * @returns {Promise<Object>} Heartbeat result
222
235
  */
223
- async heartbeat(questId, applicationId, terminal = false) {
236
+ async heartbeat(questId, applicationId, terminal = false, refresh = true) {
224
237
  const data = await this.client.api.quests(questId).heartbeat.post({
225
238
  data: {
226
239
  application_id: applicationId,
227
240
  terminal,
228
241
  },
229
242
  });
243
+ if (refresh) await this.refreshCache();
230
244
  return data;
231
245
  }
232
246
 
@@ -260,25 +274,28 @@ class QuestManager extends BaseManager {
260
274
  'WATCH_VIDEO_ON_MOBILE',
261
275
  ].find(x => taskConfig.tasks?.[x] != null);
262
276
 
263
- if (!taskName) return console.log(`Unknown task type for quest "${questName}"`);
277
+ if (!taskName) {
278
+ console.log(`Unknown task type for quest "${questName}"`);
279
+ return;
280
+ }
264
281
 
265
282
  const secondsNeeded = taskConfig.tasks[taskName].target;
266
- let secondsDone = quest.userStatus?.progress?.[taskName]?.value ?? 0;
267
283
 
268
284
  if (taskName === 'WATCH_VIDEO' || taskName === 'WATCH_VIDEO_ON_MOBILE') {
285
+ let secondsDone = quest.userStatus?.progress?.[taskName]?.value ?? 0;
269
286
  const maxFuture = 10;
270
287
  const speed = 7;
271
288
  const interval = 1;
272
289
  const enrolledAt = new Date(quest.userStatus?.enrolled_at).getTime();
273
290
  let completed = false;
274
291
 
275
- while (true) {
292
+ while (!completed && secondsDone < secondsNeeded) {
276
293
  const maxAllowed = Math.floor((Date.now() - enrolledAt) / 1000) + maxFuture;
277
294
  const diff = maxAllowed - secondsDone;
278
295
  const timestamp = secondsDone + speed;
279
296
 
280
297
  if (diff >= speed) {
281
- const res = await this.videoProgress(quest.id, Math.min(secondsNeeded, timestamp + Math.random()));
298
+ const res = await this.videoProgress(quest.id, Math.min(secondsNeeded, timestamp + Math.random()), false);
282
299
  completed = res.completed_at != null;
283
300
  secondsDone = Math.min(secondsNeeded, timestamp);
284
301
  }
@@ -291,22 +308,23 @@ class QuestManager extends BaseManager {
291
308
  }
292
309
 
293
310
  if (!completed) {
294
- await this.videoProgress(quest.id, secondsNeeded);
311
+ await this.videoProgress(quest.id, secondsNeeded, false);
295
312
  }
296
313
  } else if (taskName === 'PLAY_ON_DESKTOP') {
297
314
  const interval = 60;
298
315
 
299
316
  while (!quest.isCompleted()) {
300
- const secondsDone = quest.userStatus?.progress?.[taskName]?.value || 0;
301
- const res = await this.heartbeat(quest.id, quest.config.application.id, false);
317
+ const res = await this.heartbeat(quest.id, quest.config.application.id, false, false);
302
318
  quest.updateUserStatus(res);
303
319
 
304
320
  await this.timeout(interval * 1000);
305
321
  }
306
322
 
307
- const res = await this.heartbeat(quest.id, quest.config.application.id, true);
323
+ const res = await this.heartbeat(quest.id, quest.config.application.id, true, false);
308
324
  quest.updateUserStatus(res);
309
325
  }
326
+
327
+ await this.refreshCache();
310
328
  }
311
329
 
312
330
  /**
@@ -14,6 +14,10 @@ const { RelationshipTypes } = require('../util/Constants');
14
14
  class RelationshipManager extends BaseManager {
15
15
  constructor(client, users) {
16
16
  super(client);
17
+ this._friendCache = new Collection();
18
+ this._blockedCache = new Collection();
19
+ this._incomingCache = new Collection();
20
+ this._outgoingCache = new Collection();
17
21
  /**
18
22
  * A collection of users this manager is caching. (Type: Number)
19
23
  * @type {Collection<Snowflake, RelationshipType>}
@@ -36,10 +40,7 @@ class RelationshipManager extends BaseManager {
36
40
  * @readonly
37
41
  */
38
42
  get friendCache() {
39
- const users = this.cache
40
- .filter(value => value === RelationshipTypes.FRIEND)
41
- .map((_, key) => [key, this.client.users.cache.get(key)]);
42
- return new Collection(users);
43
+ return this._friendCache;
43
44
  }
44
45
 
45
46
  /**
@@ -48,10 +49,7 @@ class RelationshipManager extends BaseManager {
48
49
  * @readonly
49
50
  */
50
51
  get blockedCache() {
51
- const users = this.cache
52
- .filter(value => value === RelationshipTypes.BLOCKED)
53
- .map((_, key) => [key, this.client.users.cache.get(key)]);
54
- return new Collection(users);
52
+ return this._blockedCache;
55
53
  }
56
54
 
57
55
  /**
@@ -60,10 +58,7 @@ class RelationshipManager extends BaseManager {
60
58
  * @readonly
61
59
  */
62
60
  get incomingCache() {
63
- const users = this.cache
64
- .filter(value => value === RelationshipTypes.PENDING_INCOMING)
65
- .map((_, key) => [key, this.client.users.cache.get(key)]);
66
- return new Collection(users);
61
+ return this._incomingCache;
67
62
  }
68
63
 
69
64
  /**
@@ -72,10 +67,7 @@ class RelationshipManager extends BaseManager {
72
67
  * @readonly
73
68
  */
74
69
  get outgoingCache() {
75
- const users = this.cache
76
- .filter(value => value === RelationshipTypes.PENDING_OUTGOING)
77
- .map((_, key) => [key, this.client.users.cache.get(key)]);
78
- return new Collection(users);
70
+ return this._outgoingCache;
79
71
  }
80
72
 
81
73
  /**
@@ -106,10 +98,20 @@ class RelationshipManager extends BaseManager {
106
98
  */
107
99
  _setup(users) {
108
100
  if (!Array.isArray(users)) return;
101
+ // Reset caches so full fetches don't leave stale relationships behind
102
+ this.cache.clear();
103
+ this.friendNicknames.clear();
104
+ this.sinceCache.clear();
105
+ this._friendCache.clear();
106
+ this._blockedCache.clear();
107
+ this._incomingCache.clear();
108
+ this._outgoingCache.clear();
109
109
  for (const relationShip of users) {
110
+ if (relationShip.user) this.client.users._add(relationShip.user);
110
111
  this.friendNicknames.set(relationShip.id, relationShip.nickname);
111
112
  this.cache.set(relationShip.id, relationShip.type);
112
113
  this.sinceCache.set(relationShip.id, new Date(relationShip.since || 0));
114
+ this._updateRelationshipCaches(relationShip.id, relationShip.type);
113
115
  }
114
116
  }
115
117
 
@@ -123,7 +125,8 @@ class RelationshipManager extends BaseManager {
123
125
  if (user instanceof GuildMember) return user.user.id;
124
126
  if (user instanceof Message) return user.author.id;
125
127
  if (user instanceof User) return user.id;
126
- return user.match(/\d{17,19}/)?.[0] || null;
128
+ if (typeof user === 'string') return user.match(/\d{17,19}/)?.[0] || null;
129
+ return null;
127
130
  }
128
131
 
129
132
  /**
@@ -152,12 +155,28 @@ class RelationshipManager extends BaseManager {
152
155
  const existing = this.cache.get(id);
153
156
  if (existing && !existing.partial) return existing;
154
157
  }
155
- const data = await this.client.api.users['@me'].relationships.get();
156
- await this._setup(data);
157
- return this.cache.get(id);
158
+ // Try incremental hydrate: if user already cached, avoid full sync
159
+ if (this.cache.has(id)) return this.cache.get(id);
160
+ const data = await this.client.api.users['@me']
161
+ .relationships(id)
162
+ .get()
163
+ .catch(() => null);
164
+ if (data) {
165
+ const type = data.type ?? RelationshipTypes.NONE;
166
+ this.cache.set(id, type);
167
+ this.friendNicknames.set(id, data.nickname);
168
+ this.sinceCache.set(id, new Date(data.since || 0));
169
+ this._updateRelationshipCaches(id, type);
170
+ if (data.user) this.client.users._add(data.user);
171
+ return type;
172
+ }
173
+ // Fallback: full refresh
174
+ const list = await this.client.api.users['@me'].relationships.get();
175
+ this._setup(list);
176
+ return this.cache.get(id) ?? null;
158
177
  } else {
159
178
  const data = await this.client.api.users['@me'].relationships.get();
160
- await this._setup(data);
179
+ this._setup(data);
161
180
  return this;
162
181
  }
163
182
  }
@@ -168,19 +187,25 @@ class RelationshipManager extends BaseManager {
168
187
  * @returns {Promise<boolean>}
169
188
  */
170
189
  async deleteRelationship(user) {
171
- throw new Error('Risky action, not finished yet.');
172
- // eslint-disable-next-line no-unreachable
173
190
  const id = this.resolveId(user);
191
+ if (!id) return false;
174
192
  if (
175
- ![RelationshipTypes.FRIEND, RelationshipTypes.BLOCKED, RelationshipTypes.PENDING_OUTGOING].includes(
176
- this.cache.get(id),
177
- )
193
+ ![
194
+ RelationshipTypes.FRIEND,
195
+ RelationshipTypes.BLOCKED,
196
+ RelationshipTypes.PENDING_OUTGOING,
197
+ RelationshipTypes.PENDING_INCOMING,
198
+ ].includes(this.cache.get(id))
178
199
  ) {
179
200
  return Promise.resolve(false);
180
201
  }
181
202
  await this.client.api.users['@me'].relationships[id].delete({
182
203
  DiscordContext: { location: 'ContextMenu' },
183
204
  });
205
+ this.cache.delete(id);
206
+ this.friendNicknames.delete(id);
207
+ this.sinceCache.delete(id);
208
+ this._updateRelationshipCaches(id, RelationshipTypes.NONE);
184
209
  return true;
185
210
  }
186
211
 
@@ -190,16 +215,21 @@ class RelationshipManager extends BaseManager {
190
215
  * @returns {Promise<boolean>}
191
216
  */
192
217
  async sendFriendRequest(options) {
193
- throw new Error('Risky action, not finished yet.');
194
- // eslint-disable-next-line no-unreachable
195
218
  const id = this.resolveId(options);
196
219
  if (id) {
220
+ if ([RelationshipTypes.FRIEND, RelationshipTypes.PENDING_OUTGOING].includes(this.cache.get(id))) {
221
+ return Promise.resolve(false);
222
+ }
197
223
  await this.client.api.users['@me'].relationships[id].put({
198
224
  data: {},
199
225
  DiscordContext: { location: 'ContextMenu' },
200
226
  });
227
+ this.cache.set(id, RelationshipTypes.PENDING_OUTGOING);
228
+ this.sinceCache.set(id, new Date());
229
+ this._updateRelationshipCaches(id, RelationshipTypes.PENDING_OUTGOING);
201
230
  } else {
202
231
  const username = this.resolveUsername(options);
232
+ if (typeof username !== 'string') return false;
203
233
  await this.client.api.users['@me'].relationships.post({
204
234
  versioned: true,
205
235
  data: {
@@ -218,9 +248,8 @@ class RelationshipManager extends BaseManager {
218
248
  * @returns {Promise<boolean>}
219
249
  */
220
250
  async addFriend(user) {
221
- throw new Error('Risky action, not finished yet.');
222
- // eslint-disable-next-line no-unreachable
223
251
  const id = this.resolveId(user);
252
+ if (!id) return false;
224
253
  // Check if already friends
225
254
  if (this.cache.get(id) === RelationshipTypes.FRIEND) return Promise.resolve(false);
226
255
  // Check if outgoing request
@@ -229,6 +258,9 @@ class RelationshipManager extends BaseManager {
229
258
  data: { confirm_stranger_request: true },
230
259
  DiscordContext: { location: 'Friends' },
231
260
  });
261
+ this.cache.set(id, RelationshipTypes.FRIEND);
262
+ this.sinceCache.set(id, new Date());
263
+ this._updateRelationshipCaches(id, RelationshipTypes.FRIEND);
232
264
  return true;
233
265
  }
234
266
 
@@ -260,9 +292,8 @@ class RelationshipManager extends BaseManager {
260
292
  * @returns {Promise<boolean>}
261
293
  */
262
294
  async addBlocked(user) {
263
- throw new Error('Risky action, not finished yet.');
264
- // eslint-disable-next-line no-unreachable
265
295
  const id = this.resolveId(user);
296
+ if (!id) return false;
266
297
  // Check
267
298
  if (this.cache.get(id) === RelationshipTypes.BLOCKED) return Promise.resolve(false);
268
299
  await this.client.api.users['@me'].relationships[id].put({
@@ -271,8 +302,30 @@ class RelationshipManager extends BaseManager {
271
302
  },
272
303
  DiscordContext: { location: 'ContextMenu' },
273
304
  });
305
+ this.cache.set(id, RelationshipTypes.BLOCKED);
306
+ this.friendNicknames.delete(id);
307
+ this.sinceCache.set(id, new Date());
308
+ this._updateRelationshipCaches(id, RelationshipTypes.BLOCKED);
274
309
  return true;
275
310
  }
311
+
312
+ _updateRelationshipCaches(id, type) {
313
+ this._friendCache.delete(id);
314
+ this._blockedCache.delete(id);
315
+ this._incomingCache.delete(id);
316
+ this._outgoingCache.delete(id);
317
+ const user = this.client.users.cache.get(id);
318
+ if (!user) return;
319
+ if (type === RelationshipTypes.FRIEND) {
320
+ this._friendCache.set(id, user);
321
+ } else if (type === RelationshipTypes.BLOCKED) {
322
+ this._blockedCache.set(id, user);
323
+ } else if (type === RelationshipTypes.PENDING_INCOMING) {
324
+ this._incomingCache.set(id, user);
325
+ } else if (type === RelationshipTypes.PENDING_OUTGOING) {
326
+ this._outgoingCache.set(id, user);
327
+ }
328
+ }
276
329
  }
277
330
 
278
331
  module.exports = RelationshipManager;
@@ -4,10 +4,10 @@ const { setInterval } = require('node:timers');
4
4
  const { Collection } = require('@discordjs/collection');
5
5
  const Invite = require('./Invite');
6
6
  const User = require('./User');
7
+ const { Error, TypeError } = require('../errors');
7
8
  const DataResolver = require('../util/DataResolver');
8
9
  const PremiumUsageFlags = require('../util/PremiumUsageFlags');
9
10
  const PurchasedFlags = require('../util/PurchasedFlags');
10
- const { Error, TypeError } = require('../errors');
11
11
  const Util = require('../util/Util');
12
12
 
13
13
  /**
@@ -117,6 +117,46 @@ class ClientUser extends User {
117
117
  }
118
118
  }
119
119
 
120
+ /**
121
+ * A collection of friends for the logged in user (user accounts only).
122
+ * @type {Collection<Snowflake, User>}
123
+ * @readonly
124
+ * @deprecated Use {@link Client#relationships} for the full API surface.
125
+ */
126
+ get friends() {
127
+ return this.client.relationships.friendCache;
128
+ }
129
+
130
+ /**
131
+ * A collection of blocked users for the logged in user (user accounts only).
132
+ * @type {Collection<Snowflake, User>}
133
+ * @readonly
134
+ * @deprecated Use {@link Client#relationships} for the full API surface.
135
+ */
136
+ get blocked() {
137
+ return this.client.relationships.blockedCache;
138
+ }
139
+
140
+ /**
141
+ * A collection of pending incoming friend requests for the logged in user (user accounts only).
142
+ * @type {Collection<Snowflake, User>}
143
+ * @readonly
144
+ * @deprecated Use {@link Client#relationships} for the full API surface.
145
+ */
146
+ get pending() {
147
+ return this.client.relationships.incomingCache;
148
+ }
149
+
150
+ /**
151
+ * A collection of outgoing friend requests for the logged in user (user accounts only).
152
+ * @type {Collection<Snowflake, User>}
153
+ * @readonly
154
+ * @deprecated Use {@link Client#relationships} for the full API surface.
155
+ */
156
+ get outgoing() {
157
+ return this.client.relationships.outgoingCache;
158
+ }
159
+
120
160
  /**
121
161
  * Represents the client user's presence
122
162
  * @type {ClientPresence}
@@ -1746,7 +1746,7 @@ class Guild extends AnonymousGuild {
1746
1746
  const data = await this.client.api.guilds(this.id).messages.search.get({ query });
1747
1747
 
1748
1748
  if (limit && data.messages) {
1749
- // data.messages est souvent un tableau de tableaux dans l'API search
1749
+ // Data.messages est souvent un tableau de tableaux dans l'API search
1750
1750
  data.messages = data.messages.flat().slice(0, limit);
1751
1751
  }
1752
1752
 
@@ -333,8 +333,6 @@ export enum NameplatePalette {
333
333
  White = 'white',
334
334
  }
335
335
 
336
-
337
-
338
336
  export const enum OverwriteTypes {
339
337
  role = 0,
340
338
  member = 1,
@@ -437,3 +435,103 @@ export const enum ApplicationType {
437
435
  */
438
436
  CREATOR_MONETIZATION = 4,
439
437
  }
438
+
439
+ export enum ClientEvents {
440
+ RateLimit = 'rateLimit',
441
+ InvalidRequestWarning = 'invalidRequestWarning',
442
+ ApiResponse = 'apiResponse',
443
+ ApiRequest = 'apiRequest',
444
+ ClientReady = 'ready',
445
+ ApplicationCommandCreate = 'applicationCommandCreate',
446
+ ApplicationCommandDelete = 'applicationCommandDelete',
447
+ ApplicationCommandUpdate = 'applicationCommandUpdate',
448
+ ApplicationCommandPermissionsUpdate = 'applicationCommandPermissionsUpdate',
449
+ AutoModerationActionExecution = 'autoModerationActionExecution',
450
+ AutoModerationRuleCreate = 'autoModerationRuleCreate',
451
+ AutoModerationRuleDelete = 'autoModerationRuleDelete',
452
+ AutoModerationRuleUpdate = 'autoModerationRuleUpdate',
453
+ GuildAvailable = 'guildAvailable',
454
+ GuildCreate = 'guildCreate',
455
+ GuildDelete = 'guildDelete',
456
+ GuildUpdate = 'guildUpdate',
457
+ GuildUnavailable = 'guildUnavailable',
458
+ GuildMemberAdd = 'guildMemberAdd',
459
+ GuildMemberRemove = 'guildMemberRemove',
460
+ GuildMemberUpdate = 'guildMemberUpdate',
461
+ GuildMemberAvailable = 'guildMemberAvailable',
462
+ GuildMembersChunk = 'guildMembersChunk',
463
+ GuildIntegrationsUpdate = 'guildIntegrationsUpdate',
464
+ GuildRoleCreate = 'roleCreate',
465
+ GuildRoleDelete = 'roleDelete',
466
+ InviteCreate = 'inviteCreate',
467
+ InviteDelete = 'inviteDelete',
468
+ GuildRoleUpdate = 'roleUpdate',
469
+ GuildEmojiCreate = 'emojiCreate',
470
+ GuildEmojiDelete = 'emojiDelete',
471
+ GuildEmojiUpdate = 'emojiUpdate',
472
+ GuildBanAdd = 'guildBanAdd',
473
+ GuildBanRemove = 'guildBanRemove',
474
+ ChannelCreate = 'channelCreate',
475
+ ChannelDelete = 'channelDelete',
476
+ ChannelUpdate = 'channelUpdate',
477
+ ChannelPinsUpdate = 'channelPinsUpdate',
478
+ MessageCreate = 'messageCreate',
479
+ MessageDelete = 'messageDelete',
480
+ MessageUpdate = 'messageUpdate',
481
+ MessageBulkDelete = 'messageDeleteBulk',
482
+ MessageReactionAdd = 'messageReactionAdd',
483
+ MessageReactionRemove = 'messageReactionRemove',
484
+ MessageReactionRemoveAll = 'messageReactionRemoveAll',
485
+ MessageReactionRemoveEmoji = 'messageReactionRemoveEmoji',
486
+ ThreadCreate = 'threadCreate',
487
+ ThreadDelete = 'threadDelete',
488
+ ThreadUpdate = 'threadUpdate',
489
+ ThreadListSync = 'threadListSync',
490
+ ThreadMemberUpdate = 'threadMemberUpdate',
491
+ ThreadMembersUpdate = 'threadMembersUpdate',
492
+ UserUpdate = 'userUpdate',
493
+ PresenceUpdate = 'presenceUpdate',
494
+ VoiceServerUpdate = 'voiceServerUpdate',
495
+ VoiceStateUpdate = 'voiceStateUpdate',
496
+ TypingStart = 'typingStart',
497
+ WebhooksUpdate = 'webhookUpdate',
498
+ Error = 'error',
499
+ Warn = 'warn',
500
+ Debug = 'debug',
501
+ CacheSweep = 'cacheSweep',
502
+ ShardDisconnect = 'shardDisconnect',
503
+ ShardError = 'shardError',
504
+ ShardReconnecting = 'shardReconnecting',
505
+ ShardReady = 'shardReady',
506
+ ShardResume = 'shardResume',
507
+ Invalidated = 'invalidated',
508
+ Raw = 'raw',
509
+ StageInstanceCreate = 'stageInstanceCreate',
510
+ StageInstanceUpdate = 'stageInstanceUpdate',
511
+ StageInstanceDelete = 'stageInstanceDelete',
512
+ GuildStickerCreate = 'stickerCreate',
513
+ GuildStickerDelete = 'stickerDelete',
514
+ GuildStickerUpdate = 'stickerUpdate',
515
+ GuildScheduledEventCreate = 'guildScheduledEventCreate',
516
+ GuildScheduledEventUpdate = 'guildScheduledEventUpdate',
517
+ GuildScheduledEventDelete = 'guildScheduledEventDelete',
518
+ GuildScheduledEventUserAdd = 'guildScheduledEventUserAdd',
519
+ GuildScheduledEventUserRemove = 'guildScheduledEventUserRemove',
520
+ GuildAuditLogEntryCreate = 'guildAuditLogEntryCreate',
521
+ UnhandledPacket = 'unhandledPacket',
522
+ RelationshipAdd = 'relationshipAdd',
523
+ RelationshipUpdate = 'relationshipUpdate',
524
+ RelationshipRemove = 'relationshipRemove',
525
+ ChannelRecipientAdd = 'channelRecipientAdd',
526
+ ChannelRecipientRemove = 'channelRecipientRemove',
527
+ InteractionCreate = 'interactionCreate',
528
+ InteractionModalCreate = 'interactionModalCreate',
529
+ CallCreate = 'callCreate',
530
+ CallUpdate = 'callUpdate',
531
+ CallDelete = 'callDelete',
532
+ MessagePollVoteAdd = 'messagePollVoteAdd',
533
+ MessagePollVoteRemove = 'messagePollVoteRemove',
534
+ VoiceChannelEffectSend = 'voiceChannelEffectSend',
535
+ VoiceBroadcastSubscribe = 'subscribe',
536
+ VoiceBroadcastUnsubscribe = 'unsubscribe',
537
+ }
@@ -889,6 +889,9 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
889
889
  public fetchGuildWidget(guild: GuildResolvable): Promise<Widget>;
890
890
  public refreshAttachmentURL(...urls: string[]): Promise<{ original: string; refreshed: string }[]>;
891
891
  public sleep(timeout: number): Promise<void>;
892
+ /** @deprecated User accounts only */
893
+ public syncGuilds(guilds?: Guild[] | Collection<Snowflake, Guild>): void;
894
+ public fetchUser(user: UserResolvable, options?: BaseFetchOptions): Promise<User>;
892
895
  public login(token?: string): Promise<string>;
893
896
  /** @deprecated This method will not be updated until I find the most convenient way to implement MFA. */
894
897
  public passLogin(email: string, password: string): Promise<string | null>;
@@ -904,7 +907,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
904
907
  ): Promise<Guild | DMChannel | GroupDMChannel>;
905
908
  public redeemNitro(nitro: string, channel?: TextChannelResolvable, paymentSourceId?: Snowflake): Promise<any>;
906
909
  public authorizeURL(urlOAuth2: string, options?: OAuth2AuthorizeOptions): Promise<{ location: string }>;
907
- public installUserApps(applicationId: Snowflake): Promise<void>;
910
+ public installUserApps(applicationId: Snowflake, scopes?: string[] | string): Promise<boolean>;
911
+ public unInstallUserApp(applicationId: Snowflake): Promise<boolean>;
908
912
  public deauthorize(id: Snowflake, type?: 'application' | 'token'): Promise<void>;
909
913
  public authorizedApplications(): Promise<
910
914
  Collection<
@@ -1003,6 +1007,10 @@ export class ClientUser extends User {
1003
1007
  public setActivity(name: string, options?: Omit<ActivityOptions, 'name'>): ClientPresence;
1004
1008
  public setAFK(afk?: boolean, shardId?: number | number[]): ClientPresence;
1005
1009
  public setAvatar(avatar: BufferResolvable | Base64Resolvable | null): Promise<this>;
1010
+ public readonly friends: Collection<Snowflake, User>;
1011
+ public readonly blocked: Collection<Snowflake, User>;
1012
+ public readonly pending: Collection<Snowflake, User>;
1013
+ public readonly outgoing: Collection<Snowflake, User>;
1006
1014
  public setPresence(data: PresenceData): ClientPresence;
1007
1015
  public setStatus(status: PresenceStatusData, shardId?: number | number[]): ClientPresence;
1008
1016
  public setUsername(username: string, password: string): Promise<this>;
@@ -1033,7 +1041,12 @@ export class ClientUser extends User {
1033
1041
  public addWidget(type: WidgetType, gameId: string, comment?: string | null, tags?: string[]): Promise<any>;
1034
1042
  public delWidget(type: WidgetType, gameId?: string): Promise<any>;
1035
1043
  public widgetsList(): Promise<WidgetsResponse>;
1036
- public setNameStyle(fontName: FontName | number, effectName: EffectName | number, color1: number | string, color2?: number | string | null): Promise<this>;
1044
+ public setNameStyle(
1045
+ fontName: FontName | number,
1046
+ effectName: EffectName | number,
1047
+ color1: number | string,
1048
+ color2?: number | string | null,
1049
+ ): Promise<this>;
1037
1050
  }
1038
1051
 
1039
1052
  export class Options extends null {