@discordeno/rest 19.0.0-next.fc13bdf → 19.0.0-next.fd357ae

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/manager.js CHANGED
@@ -1,17 +1,21 @@
1
1
  /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable no-const-assign */ import { InteractionResponseTypes } from '@discordeno/types';
2
- import { calculateBits, camelize, camelToSnakeCase, delay, findFiles, getBotIdFromToken, isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit, logger, processReactionString, urlToBase64 } from '@discordeno/utils';
2
+ import { calculateBits, camelize, camelToSnakeCase, delay, getBotIdFromToken, logger, processReactionString, urlToBase64 } from '@discordeno/utils';
3
+ import fetch from 'node-fetch';
3
4
  import { createInvalidRequestBucket } from './invalidBucket.js';
4
5
  import { Queue } from './queue.js';
6
+ import { createRoutes } from './routes.js';
5
7
  // TODO: make dynamic based on package.json file
6
8
  const version = '19.0.0-alpha.1';
7
9
  export function createRestManager(options) {
8
- // Falsy token string check
9
- if (!options.token) throw new Error('You must provide a valid token.');
10
+ const applicationId = options.applicationId ? BigInt(options.applicationId) : options.token ? getBotIdFromToken(options.token) : undefined;
11
+ if (!applicationId) {
12
+ throw new Error('`applicationId` was not provided and was not able to extract the id from the bots token. Please explicitly pass `applicationId` to the rest manager.');
13
+ }
10
14
  const rest = {
11
15
  token: options.token,
12
- applicationId: options.applicationId ? BigInt(options.applicationId) : getBotIdFromToken(options.token),
16
+ applicationId,
13
17
  version: options.version ?? 10,
14
- baseUrl: options.baseUrl ?? 'https://discord.com/api',
18
+ baseUrl: options.proxy?.baseUrl ?? 'https://discord.com/api',
15
19
  maxRetryCount: Infinity,
16
20
  globallyRateLimited: false,
17
21
  processingRateLimitedPaths: false,
@@ -19,488 +23,8 @@ export function createRestManager(options) {
19
23
  queues: new Map(),
20
24
  rateLimitedPaths: new Map(),
21
25
  invalidBucket: createInvalidRequestBucket({}),
22
- routes: {
23
- webhooks: {
24
- id: (webhookId)=>{
25
- return `/webhooks/${webhookId}`;
26
- },
27
- message: (webhookId, token, messageId, options)=>{
28
- let url = `/webhooks/${webhookId}/${token}/messages/${messageId}?`;
29
- if (options) {
30
- if (options.threadId) url += `thread_id=${options.threadId}`;
31
- }
32
- return url;
33
- },
34
- original: (webhookId, token, options)=>{
35
- let url = `/webhooks/${webhookId}/${token}/messages/@original?`;
36
- if (options) {
37
- if (options.threadId) url += `thread_id=${options.threadId}`;
38
- }
39
- return url;
40
- },
41
- webhook: (webhookId, token, options)=>{
42
- let url = `/webhooks/${webhookId}/${token}?`;
43
- if (options) {
44
- if (options?.wait !== undefined) url += `wait=${options.wait.toString()}`;
45
- if (options.threadId) url += `thread_id=${options.threadId}`;
46
- }
47
- return url;
48
- }
49
- },
50
- // Miscellaneous Endpoints
51
- sessionInfo: ()=>rest.routes.gatewayBot(),
52
- // Channel Endpoints
53
- channels: {
54
- bulk: (channelId)=>{
55
- return `/channels/${channelId}/messages/bulk-delete`;
56
- },
57
- dm: ()=>{
58
- return '/users/@me/channels';
59
- },
60
- pin: (channelId, messageId)=>{
61
- return `/channels/${channelId}/pins/${messageId}`;
62
- },
63
- pins: (channelId)=>{
64
- return `/channels/${channelId}/pins`;
65
- },
66
- reactions: {
67
- bot: (channelId, messageId, emoji)=>{
68
- return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`;
69
- },
70
- user: (channelId, messageId, emoji, userId)=>{
71
- return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/${userId}`;
72
- },
73
- all: (channelId, messageId)=>{
74
- return `/channels/${channelId}/messages/${messageId}/reactions`;
75
- },
76
- emoji: (channelId, messageId, emoji, options)=>{
77
- let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`;
78
- if (options) {
79
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
80
- if (options.after) url += `after=${options.after}`;
81
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
82
- if (options.limit) url += `&limit=${options.limit}`;
83
- }
84
- return url;
85
- },
86
- message: (channelId, messageId, emoji, options)=>{
87
- let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`;
88
- if (options) {
89
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
90
- if (options.after) url += `after=${options.after}`;
91
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
92
- if (options.limit) url += `&limit=${options.limit}`;
93
- }
94
- return url;
95
- }
96
- },
97
- webhooks: (channelId)=>{
98
- return `/channels/${channelId}/webhooks`;
99
- },
100
- channel: (channelId)=>{
101
- return `/channels/${channelId}`;
102
- },
103
- follow: (channelId)=>{
104
- return `/channels/${channelId}/followers`;
105
- },
106
- forum: (channelId)=>{
107
- return `/channels/${channelId}/threads?has_message=true`;
108
- },
109
- invites: (channelId)=>{
110
- return `/channels/${channelId}/invites`;
111
- },
112
- message: (channelId, messageId)=>{
113
- return `/channels/${channelId}/messages/${messageId}`;
114
- },
115
- messages: (channelId, options)=>{
116
- let url = `/channels/${channelId}/messages?`;
117
- if (options) {
118
- if (isGetMessagesAfter(options) && options.after) {
119
- url += `after=${options.after}`;
120
- }
121
- if (isGetMessagesBefore(options) && options.before) {
122
- url += `&before=${options.before}`;
123
- }
124
- if (isGetMessagesAround(options) && options.around) {
125
- url += `&around=${options.around}`;
126
- }
127
- if (isGetMessagesLimit(options) && options.limit) {
128
- url += `&limit=${options.limit}`;
129
- }
130
- }
131
- return url;
132
- },
133
- overwrite: (channelId, overwriteId)=>{
134
- return `/channels/${channelId}/permissions/${overwriteId}`;
135
- },
136
- crosspost: (channelId, messageId)=>{
137
- return `/channels/${channelId}/messages/${messageId}/crosspost`;
138
- },
139
- stages: ()=>{
140
- return '/stage-instances';
141
- },
142
- stage: (channelId)=>{
143
- return `/stage-instances/${channelId}`;
144
- },
145
- // Thread Endpoints
146
- threads: {
147
- message: (channelId, messageId)=>{
148
- return `/channels/${channelId}/messages/${messageId}/threads`;
149
- },
150
- all: (channelId)=>{
151
- return `/channels/${channelId}/threads`;
152
- },
153
- active: (guildId)=>{
154
- return `/guilds/${guildId}/threads/active`;
155
- },
156
- members: (channelId)=>{
157
- return `/channels/${channelId}/thread-members`;
158
- },
159
- me: (channelId)=>{
160
- return `/channels/${channelId}/thread-members/@me`;
161
- },
162
- user: (channelId, userId)=>{
163
- return `/channels/${channelId}/thread-members/${userId}`;
164
- },
165
- archived: (channelId)=>{
166
- return `/channels/${channelId}/threads/archived`;
167
- },
168
- public: (channelId, options)=>{
169
- let url = `/channels/${channelId}/threads/archived/public?`;
170
- if (options) {
171
- if (options.before) {
172
- url += `before=${new Date(options.before).toISOString()}`;
173
- }
174
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
175
- if (options.limit) url += `&limit=${options.limit}`;
176
- }
177
- return url;
178
- },
179
- private: (channelId, options)=>{
180
- let url = `/channels/${channelId}/threads/archived/private?`;
181
- if (options) {
182
- if (options.before) {
183
- url += `before=${new Date(options.before).toISOString()}`;
184
- }
185
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
186
- if (options.limit) url += `&limit=${options.limit}`;
187
- }
188
- return url;
189
- },
190
- joined: (channelId, options)=>{
191
- let url = `/channels/${channelId}/users/@me/threads/archived/private?`;
192
- if (options) {
193
- if (options.before) {
194
- url += `before=${new Date(options.before).toISOString()}`;
195
- }
196
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
197
- if (options.limit) url += `&limit=${options.limit}`;
198
- }
199
- return url;
200
- }
201
- },
202
- typing: (channelId)=>{
203
- return `/channels/${channelId}/typing`;
204
- }
205
- },
206
- // Guild Endpoints
207
- guilds: {
208
- all: ()=>{
209
- return '/guilds';
210
- },
211
- auditlogs: (guildId, options)=>{
212
- let url = `/guilds/${guildId}/audit-logs?`;
213
- if (options) {
214
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
215
- if (options.actionType) url += `action_type=${options.actionType}`;
216
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
217
- if (options.before) url += `&before=${options.before}`;
218
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
219
- if (options.limit) url += `&limit=${options.limit}`;
220
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
221
- if (options.userId) url += `&user_id=${options.userId}`;
222
- }
223
- return url;
224
- },
225
- automod: {
226
- rule: (guildId, ruleId)=>{
227
- return `/guilds/${guildId}/auto-moderation/rules/${ruleId}`;
228
- },
229
- rules: (guildId)=>{
230
- return `/guilds/${guildId}/auto-moderation/rules`;
231
- }
232
- },
233
- channels: (guildId)=>{
234
- return `/guilds/${guildId}/channels`;
235
- },
236
- emoji: (guildId, emojiId)=>{
237
- return `/guilds/${guildId}/emojis/${emojiId}`;
238
- },
239
- emojis: (guildId)=>{
240
- return `/guilds/${guildId}/emojis`;
241
- },
242
- events: {
243
- events: (guildId, withUserCount)=>{
244
- let url = `/guilds/${guildId}/scheduled-events?`;
245
- if (withUserCount !== undefined) {
246
- url += `with_user_count=${withUserCount.toString()}`;
247
- }
248
- return url;
249
- },
250
- event: (guildId, eventId, withUserCount)=>{
251
- let url = `/guilds/${guildId}/scheduled-events/${eventId}`;
252
- if (withUserCount !== undefined) {
253
- url += `with_user_count=${withUserCount.toString()}`;
254
- }
255
- return url;
256
- },
257
- users: (guildId, eventId, options)=>{
258
- let url = `/guilds/${guildId}/scheduled-events/${eventId}/users?`;
259
- if (options) {
260
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
261
- if (options.limit !== undefined) url += `limit=${options.limit}`;
262
- if (options.withMember !== undefined) {
263
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
264
- url += `&with_member=${options.withMember.toString()}`;
265
- }
266
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
267
- if (options.after !== undefined) url += `&after=${options.after}`;
268
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
269
- if (options.before !== undefined) url += `&before=${options.before}`;
270
- }
271
- return url;
272
- }
273
- },
274
- guild (guildId, withCounts) {
275
- let url = `/guilds/${guildId}?`;
276
- if (withCounts !== undefined) {
277
- url += `with_counts=${withCounts.toString()}`;
278
- }
279
- return url;
280
- },
281
- integration (guildId, integrationId) {
282
- return `/guilds/${guildId}/integrations/${integrationId}`;
283
- },
284
- integrations: (guildId)=>{
285
- return `/guilds/${guildId}/integrations?include_applications=true`;
286
- },
287
- invite (inviteCode, options) {
288
- let url = `/invites/${inviteCode}?`;
289
- if (options) {
290
- if (options.withCounts !== undefined) {
291
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
292
- url += `with_counts=${options.withCounts.toString()}`;
293
- }
294
- if (options.withExpiration !== undefined) {
295
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
296
- url += `&with_expiration=${options.withExpiration.toString()}`;
297
- }
298
- if (options.scheduledEventId) {
299
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
300
- url += `&guild_scheduled_event_id=${options.scheduledEventId}`;
301
- }
302
- }
303
- return url;
304
- },
305
- invites: (guildId)=>{
306
- return `/guilds/${guildId}/invites`;
307
- },
308
- leave: (guildId)=>{
309
- return `/users/@me/guilds/${guildId}`;
310
- },
311
- members: {
312
- ban: (guildId, userId)=>{
313
- return `/guilds/${guildId}/bans/${userId}`;
314
- },
315
- bans: (guildId, options)=>{
316
- let url = `/guilds/${guildId}/bans?`;
317
- if (options) {
318
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
319
- if (options.limit) url += `limit=${options.limit}`;
320
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
321
- if (options.after) url += `&after=${options.after}`;
322
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
323
- if (options.before) url += `&before=${options.before}`;
324
- }
325
- return url;
326
- },
327
- bot: (guildId)=>{
328
- return `/guilds/${guildId}/members/@me`;
329
- },
330
- member: (guildId, userId)=>{
331
- return `/guilds/${guildId}/members/${userId}`;
332
- },
333
- members: (guildId, options)=>{
334
- let url = `/guilds/${guildId}/members?`;
335
- if (options !== undefined) {
336
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
337
- if (options.limit) url += `limit=${options.limit}`;
338
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
339
- if (options.after) url += `&after=${options.after}`;
340
- }
341
- return url;
342
- },
343
- search: (guildId, query, options)=>{
344
- let url = `/guilds/${guildId}/members/search?query=${encodeURIComponent(query)}`;
345
- if (options) {
346
- if (options.limit !== undefined) url += `&limit=${options.limit}`;
347
- }
348
- return url;
349
- },
350
- prune: (guildId, options)=>{
351
- let url = `/guilds/${guildId}/prune?`;
352
- if (options) {
353
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
354
- if (options.days) url += `days=${options.days}`;
355
- if (Array.isArray(options.includeRoles)) {
356
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
357
- url += `&include_roles=${options.includeRoles.join(',')}`;
358
- } else if (options.includeRoles) {
359
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
360
- url += `&include_roles=${options.includeRoles}`;
361
- }
362
- }
363
- return url;
364
- }
365
- },
366
- mfa: (guildId)=>`/guilds/${guildId}/mfa`,
367
- preview: (guildId)=>{
368
- return `/guilds/${guildId}/preview`;
369
- },
370
- prune: (guildId, options)=>{
371
- let url = `/guilds/${guildId}/prune?`;
372
- if (options) {
373
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
374
- if (options.days) url += `days=${options.days}`;
375
- if (Array.isArray(options.includeRoles)) {
376
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
377
- url += `&include_roles=${options.includeRoles.join(',')}`;
378
- } else if (options.includeRoles) {
379
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
380
- url += `&include_roles=${options.includeRoles}`;
381
- }
382
- }
383
- return url;
384
- },
385
- roles: {
386
- one: (guildId, roleId)=>{
387
- return `/guilds/${guildId}/roles/${roleId}`;
388
- },
389
- all: (guildId)=>{
390
- return `/guilds/${guildId}/roles`;
391
- },
392
- member: (guildId, memberId, roleId)=>{
393
- return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`;
394
- }
395
- },
396
- stickers: (guildId)=>{
397
- return `/guilds/${guildId}/stickers`;
398
- },
399
- sticker: (guildId, stickerId)=>{
400
- return `/guilds/${guildId}/stickers/${stickerId}`;
401
- },
402
- voice: (guildId, userId)=>{
403
- return `/guilds/${guildId}/voice-states/${userId ?? '@me'}`;
404
- },
405
- templates: {
406
- code: (code)=>{
407
- return `/guilds/templates/${code}`;
408
- },
409
- guild: (guildId, code)=>{
410
- return `/guilds/${guildId}/templates/${code}`;
411
- },
412
- all: (guildId)=>{
413
- return `/guilds/${guildId}/templates`;
414
- }
415
- },
416
- vanity: (guildId)=>{
417
- return `/guilds/${guildId}/vanity-url`;
418
- },
419
- regions: (guildId)=>{
420
- return `/guilds/${guildId}/regions`;
421
- },
422
- webhooks: (guildId)=>{
423
- return `/guilds/${guildId}/webhooks`;
424
- },
425
- welcome: (guildId)=>{
426
- return `/guilds/${guildId}/welcome-screen`;
427
- },
428
- widget: (guildId)=>{
429
- return `/guilds/${guildId}/widget`;
430
- },
431
- widgetJson: (guildId)=>{
432
- return `/guilds/${guildId}/widget.json`;
433
- }
434
- },
435
- sticker: (stickerId)=>{
436
- return `/stickers/${stickerId}`;
437
- },
438
- regions: ()=>{
439
- return '/voice/regions';
440
- },
441
- // Interaction Endpoints
442
- interactions: {
443
- commands: {
444
- // Application Endpoints
445
- commands: (applicationId)=>{
446
- return `/applications/${applicationId}/commands`;
447
- },
448
- guilds: {
449
- all (applicationId, guildId) {
450
- return `/applications/${applicationId}/guilds/${guildId}/commands`;
451
- },
452
- one (applicationId, guildId, commandId, withLocalizations) {
453
- let url = `/applications/${applicationId}/guilds/${guildId}/commands/${commandId}?`;
454
- if (withLocalizations !== undefined) {
455
- url += `with_localizations=${withLocalizations.toString()}`;
456
- }
457
- return url;
458
- }
459
- },
460
- permissions: (applicationId, guildId)=>{
461
- return `/applications/${applicationId}/guilds/${guildId}/commands/permissions`;
462
- },
463
- permission: (applicationId, guildId, commandId)=>{
464
- return `/applications/${applicationId}/guilds/${guildId}/commands/${commandId}/permissions`;
465
- },
466
- command: (applicationId, commandId, withLocalizations)=>{
467
- let url = `/applications/${applicationId}/commands/${commandId}?`;
468
- if (withLocalizations !== undefined) {
469
- url += `withLocalizations=${withLocalizations.toString()}`;
470
- }
471
- return url;
472
- }
473
- },
474
- responses: {
475
- // Interaction Endpoints
476
- callback: (interactionId, token)=>{
477
- return `/interactions/${interactionId}/${token}/callback`;
478
- },
479
- original: (interactionId, token)=>{
480
- return `/webhooks/${interactionId}/${token}/messages/@original`;
481
- },
482
- message: (applicationId, token, messageId)=>{
483
- return `/webhooks/${applicationId}/${token}/messages/${messageId}`;
484
- }
485
- }
486
- },
487
- // User endpoints
488
- user (userId) {
489
- return `/users/${userId}`;
490
- },
491
- userBot () {
492
- return '/users/@me';
493
- },
494
- oauth2Application () {
495
- return 'oauth2/applications/@me';
496
- },
497
- gatewayBot () {
498
- return '/gateway/bot';
499
- },
500
- nitroStickerPacks () {
501
- return '/sticker-packs';
502
- }
503
- },
26
+ authorization: options.proxy?.authorization,
27
+ routes: createRoutes(),
504
28
  checkRateLimits (url) {
505
29
  const ratelimited = rest.rateLimitedPaths.get(url);
506
30
  const global = rest.rateLimitedPaths.get('global');
@@ -541,56 +65,47 @@ export function createRestManager(options) {
541
65
  if (typeof obj === 'bigint') return obj.toString();
542
66
  return obj;
543
67
  },
544
- createRequest (options) {
68
+ createRequestBody (method, options) {
545
69
  const headers = {
546
70
  'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v${version})`
547
71
  };
548
- if (!options.unauthorized) headers.authorization = `Bot ${rest.token}`;
549
- // SOMETIMES SPECIAL HEADERS (E.G. CUSTOM AUTHORIZATION) NEED TO BE USED
550
- if (options.headers) {
551
- for(const key in options.headers){
552
- headers[key.toLowerCase()] = options.headers[key];
553
- }
554
- }
555
- // GET METHODS SHOULD NOT HAVE A BODY
556
- if (options.method === 'GET') {
557
- options.body = undefined;
558
- }
72
+ if (options?.unauthorized !== false) headers.authorization = `Bot ${rest.token}`;
559
73
  // IF A REASON IS PROVIDED ENCODE IT IN HEADERS
560
- if (options.body?.reason) {
561
- headers['X-Audit-Log-Reason'] = encodeURIComponent(options.body.reason);
562
- options.body.reason = undefined;
74
+ if (options?.reason !== undefined) {
75
+ headers['x-audit-log-reason'] = encodeURIComponent(options?.reason);
563
76
  }
564
- if (options.body) {
565
- const { file } = options.body;
566
- if (file) {
567
- const files = findFiles(file);
568
- const form = new FormData();
569
- // WHEN CREATING A STICKER, DISCORD WANTS FORM DATA ONLY
570
- if (options.url?.endsWith('/stickers') && options.method === 'POST') {
571
- form.append('file', files[0].blob, files[0].name);
572
- form.append('name', options.body.name);
573
- form.append('description', options.body.description);
574
- form.append('tags', options.body.tags);
575
- } else {
576
- for(let i = 0; i < files.length; i++){
577
- form.append(`file${i}`, files[i].blob, files[i].name);
578
- }
579
- if (file) options.body.file = undefined;
580
- form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat(options.body)));
581
- }
582
- options.body.file = form;
583
- } else if (options.body && ![
584
- 'GET',
585
- 'DELETE'
586
- ].includes(options.method)) {
587
- headers['Content-Type'] = 'application/json';
77
+ let body;
78
+ // TODO: check if we need to add specific check for GET method
79
+ // Since GET does not allow bodies
80
+ // Have to check for attachments first, since body then has to be send in a different way.
81
+ if (options?.files !== undefined) {
82
+ const form = new FormData();
83
+ for(let i = 0; i < options.files.length; ++i){
84
+ form.append(`file${i}`, options.files[i].blob, options.files[i].name);
85
+ }
86
+ form.append('payload_json', JSON.stringify({
87
+ ...options.body,
88
+ files: undefined
89
+ }));
90
+ body = form;
91
+ // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
92
+ } else if (options?.body !== undefined) {
93
+ if (options.body instanceof FormData) {
94
+ body = options.body;
95
+ // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
96
+ } else {
97
+ body = JSON.stringify(rest.changeToDiscordFormat(options.body));
98
+ headers['content-type'] = `application/json`;
588
99
  }
589
100
  }
101
+ // SOMETIMES SPECIAL HEADERS (E.G. CUSTOM AUTHORIZATION) NEED TO BE USED
102
+ if (options?.headers) {
103
+ Object.assign(headers, options.headers);
104
+ }
590
105
  return {
106
+ body,
591
107
  headers,
592
- body: options.body?.file ?? JSON.stringify(rest.changeToDiscordFormat(options.body)),
593
- method: options.method
108
+ method
594
109
  };
595
110
  },
596
111
  processRateLimitedPaths () {
@@ -655,8 +170,8 @@ export function createRestManager(options) {
655
170
  }
656
171
  // IF THERE IS NO REMAINING GLOBAL LIMIT, MARK IT RATE LIMITED GLOBALLY
657
172
  if (global) {
658
- const retryAfter1 = headers.get('retry-after');
659
- const globalReset = Date.now() + Number(retryAfter1) * 1000;
173
+ const retryAfter = headers.get('retry-after');
174
+ const globalReset = Date.now() + Number(retryAfter) * 1000;
660
175
  // rest.debug(
661
176
  // `[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}`
662
177
  // )
@@ -685,12 +200,7 @@ export function createRestManager(options) {
685
200
  },
686
201
  async sendRequest (options) {
687
202
  const url = options.url.startsWith('https://') ? options.url : `${rest.baseUrl}/v${rest.version}${options.url}`;
688
- const payload = rest.createRequest({
689
- method: options.method,
690
- url: options.url,
691
- body: options.body,
692
- ...options.options
693
- });
203
+ const payload = rest.createRequestBody(options.method, options.requestBodyOptions);
694
204
  logger.debug(`sending request to ${url}`, 'with payload:', {
695
205
  ...payload,
696
206
  headers: {
@@ -712,11 +222,12 @@ export function createRestManager(options) {
712
222
  logger.debug(`Request to ${url} exceeded the maximum allowed retries.`, 'with payload:', payload);
713
223
  // rest.debug(`[REST - RetriesMaxed] ${JSON.stringify(options)}`)
714
224
  // Remove item from queue to prevent retry
715
- return options.reject({
225
+ options.reject({
716
226
  ok: false,
717
227
  status: response.status,
718
228
  error: 'The options was rate limited and it maxed out the retries limit.'
719
229
  });
230
+ return;
720
231
  }
721
232
  // Rate limited, add back to queue
722
233
  rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get('X-RateLimit-Scope') === 'shared');
@@ -726,41 +237,44 @@ export function createRestManager(options) {
726
237
  await response.json();
727
238
  return await options.retryRequest?.(options);
728
239
  }
729
- return options.reject({
240
+ options.reject({
730
241
  ok: false,
731
242
  status: response.status,
732
243
  body: JSON.stringify(await response.json())
733
244
  });
245
+ return;
734
246
  }
735
247
  const is204 = response.status === 204;
736
248
  const json = is204 ? undefined : await response.json();
737
249
  // Discord sometimes sends no response with 204 code
738
- return options.resolve({
250
+ options.resolve({
739
251
  ok: true,
740
252
  status: response.status,
741
253
  body: JSON.stringify(json)
742
254
  });
743
255
  },
744
- // Credits: github.com/abalabahaha/eris lib/rest/RequestHandler.js#L397
745
- // Modified for our use-case
746
256
  simplifyUrl (url, method) {
747
- let route = url.replace(/\/([a-z-]+)\/(?:[0-9]{17,19})/g, function(match, p) {
748
- return [
749
- 'channels',
750
- 'guilds'
751
- ].includes(p) ? match : `/${p}/x`;
752
- }).replace(/\/reactions\/[^/]+/g, '/reactions/x');
753
- // GENERAL /reactions and /reactions/emoji/@me share the buckets
754
- if (route.includes('/reactions')) {
755
- route = route.substring(0, route.indexOf('/reactions') + '/reactions'.length);
257
+ const parts = url.split('/');
258
+ const secondLastPart = parts[parts.length - 2];
259
+ if (secondLastPart === 'channels' || secondLastPart === 'guilds') {
260
+ return url;
756
261
  }
757
- // Delete Message endpoint has its own rate limit
758
- if (method === 'DELETE' && route.endsWith('/messages/x')) {
759
- route = method + route;
262
+ if (secondLastPart === 'reactions' || parts[parts.length - 1] === '@me') {
263
+ parts.splice(-2);
264
+ parts.push('reactions');
265
+ } else {
266
+ parts.splice(-1);
267
+ parts.push('x');
268
+ }
269
+ if (parts[parts.length - 3] === 'reactions') {
270
+ parts.splice(-2);
760
271
  }
761
- return route;
272
+ if (method === 'DELETE' && secondLastPart === 'messages') {
273
+ return `D${parts.join('/')}`;
274
+ }
275
+ return parts.join('/');
762
276
  },
763
- processRequest (request) {
277
+ async processRequest (request) {
764
278
  const route = request.url.substring(request.url.indexOf('api/'));
765
279
  const parts = route.split('/');
766
280
  // Remove the api/
@@ -770,6 +284,10 @@ export function createRestManager(options) {
770
284
  // Set the full url to discord api in case it was recieved in a proxy rest
771
285
  request.url = `${rest.baseUrl}/v${rest.version}/${parts.join('/')}`;
772
286
  const url = rest.simplifyUrl(request.url, request.method);
287
+ if (request.runThroughQueue === false) {
288
+ await rest.sendRequest(request);
289
+ return;
290
+ }
773
291
  const queue = rest.queues.get(url);
774
292
  if (queue !== undefined) {
775
293
  queue.makeRequest(request);
@@ -785,45 +303,60 @@ export function createRestManager(options) {
785
303
  rest.queues.set(url, bucketQueue);
786
304
  }
787
305
  },
788
- async makeRequest (method, url, body, options) {
789
- return await new Promise((resolve, reject)=>{
306
+ async makeRequest (method, url, options) {
307
+ if (!rest.baseUrl.startsWith('https://discord.com') && url[0] === '/') {
308
+ const result = await fetch(`${rest.baseUrl}${url}`, rest.createRequestBody(method, options));
309
+ if (!result.ok) {
310
+ const err = await result.json().catch(()=>{});
311
+ // Legacy Handling to not break old code or when body is missing
312
+ if (!err?.body) throw new Error(`Error: ${err.message ?? result.statusText}`);
313
+ throw new Error(JSON.stringify(err));
314
+ }
315
+ return result.status !== 204 ? await result.json() : undefined;
316
+ }
317
+ // eslint-disable-next-line no-async-promise-executor
318
+ return await new Promise(async (resolve, reject)=>{
790
319
  const payload = {
791
320
  url,
792
321
  method,
793
- body,
322
+ requestBodyOptions: options,
794
323
  retryCount: 0,
795
- retryRequest: async function(options) {
796
- rest.processRequest(payload);
324
+ retryRequest: async function(payload) {
325
+ await rest.processRequest(payload);
326
+ },
327
+ resolve: (data)=>{
328
+ resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined);
797
329
  },
798
- resolve: (data)=>resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined),
799
330
  reject,
800
- options
331
+ runThroughQueue: options?.runThroughQueue
801
332
  };
802
- rest.processRequest(payload);
333
+ await rest.processRequest(payload);
803
334
  });
804
335
  },
805
- async get (url) {
806
- return camelize(await rest.makeRequest('GET', url));
336
+ async get (url, options) {
337
+ return camelize(await rest.makeRequest('GET', url, options));
807
338
  },
808
- async post (url, body) {
809
- return camelize(await rest.makeRequest('POST', url, body));
339
+ async post (url, options) {
340
+ return camelize(await rest.makeRequest('POST', url, options));
810
341
  },
811
- async delete (url, body) {
812
- return camelize(await rest.makeRequest('DELETE', url, body));
342
+ async delete (url, options) {
343
+ camelize(await rest.makeRequest('DELETE', url, options));
813
344
  },
814
- async patch (url, body) {
815
- return camelize(await rest.makeRequest('PATCH', url, body));
345
+ async patch (url, options) {
346
+ return camelize(await rest.makeRequest('PATCH', url, options));
816
347
  },
817
- async put (url, body, options) {
818
- return camelize(await rest.makeRequest('PUT', url, body, options));
348
+ async put (url, options) {
349
+ return camelize(await rest.makeRequest('PUT', url, options));
819
350
  },
820
351
  async addReaction (channelId, messageId, reaction) {
821
352
  reaction = processReactionString(reaction);
822
- return await rest.put(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
353
+ await rest.put(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
823
354
  },
824
355
  async addReactions (channelId, messageId, reactions, ordered = false) {
825
356
  if (!ordered) {
826
- await Promise.all(reactions.map(async (reaction)=>await rest.addReaction(channelId, messageId, reaction)));
357
+ await Promise.all(reactions.map(async (reaction)=>{
358
+ await rest.addReaction(channelId, messageId, reaction);
359
+ }));
827
360
  return;
828
361
  }
829
362
  for (const reaction of reactions){
@@ -831,283 +364,408 @@ export function createRestManager(options) {
831
364
  }
832
365
  },
833
366
  async addRole (guildId, userId, roleId, reason) {
834
- return await rest.put(rest.routes.guilds.roles.member(guildId, userId, roleId), {
367
+ await rest.put(rest.routes.guilds.roles.member(guildId, userId, roleId), {
835
368
  reason
836
369
  });
837
370
  },
838
371
  async addThreadMember (channelId, userId) {
839
- return await rest.put(rest.routes.channels.threads.user(channelId, userId));
372
+ await rest.put(rest.routes.channels.threads.user(channelId, userId));
840
373
  },
841
- async createAutomodRule (guildId, options) {
842
- return await rest.post(rest.routes.guilds.automod.rules(guildId), options);
374
+ async createAutomodRule (guildId, body, reason) {
375
+ return await rest.post(rest.routes.guilds.automod.rules(guildId), {
376
+ body,
377
+ reason
378
+ });
843
379
  },
844
- async createChannel (guildId, options) {
845
- return await rest.post(rest.routes.guilds.channels(guildId), options);
380
+ async createChannel (guildId, body, reason) {
381
+ return await rest.post(rest.routes.guilds.channels(guildId), {
382
+ body,
383
+ reason
384
+ });
846
385
  },
847
- async createEmoji (guildId, options) {
848
- return await rest.post(rest.routes.guilds.emojis(guildId), options);
386
+ async createEmoji (guildId, body, reason) {
387
+ return await rest.post(rest.routes.guilds.emojis(guildId), {
388
+ body,
389
+ reason
390
+ });
849
391
  },
850
- async createGlobalApplicationCommand (command) {
851
- return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), command);
392
+ async createGlobalApplicationCommand (body) {
393
+ return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), {
394
+ body
395
+ });
852
396
  },
853
- async createGuild (options) {
854
- return await rest.post(rest.routes.guilds.all(), options);
397
+ async createGuild (body) {
398
+ return await rest.post(rest.routes.guilds.all(), {
399
+ body
400
+ });
855
401
  },
856
- async createGuildApplicationCommand (command, guildId) {
857
- return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), command);
402
+ async createGuildApplicationCommand (body, guildId) {
403
+ return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), {
404
+ body
405
+ });
858
406
  },
859
- async createGuildFromTemplate (templateCode, options) {
860
- if (options.icon) {
861
- options.icon = await urlToBase64(options.icon);
407
+ async createGuildFromTemplate (templateCode, body) {
408
+ if (body.icon) {
409
+ body.icon = await urlToBase64(body.icon);
862
410
  }
863
- return await rest.post(rest.routes.guilds.templates.code(templateCode), options);
411
+ return await rest.post(rest.routes.guilds.templates.code(templateCode), {
412
+ body
413
+ });
864
414
  },
865
- async createGuildSticker (guildId, options) {
866
- return await rest.post(rest.routes.guilds.stickers(guildId), options);
415
+ async createGuildSticker (guildId, options, reason) {
416
+ const form = new FormData();
417
+ form.append('file', options.file.blob, options.file.name);
418
+ form.append('name', options.name);
419
+ form.append('description', options.description);
420
+ form.append('tags', options.tags);
421
+ return await rest.post(rest.routes.guilds.stickers(guildId), {
422
+ body: form,
423
+ reason
424
+ });
867
425
  },
868
- async createGuildTemplate (guildId, options) {
869
- return await rest.post(rest.routes.guilds.templates.all(guildId), options);
426
+ async createGuildTemplate (guildId, body) {
427
+ return await rest.post(rest.routes.guilds.templates.all(guildId), {
428
+ body
429
+ });
870
430
  },
871
- async createForumThread (channelId, options) {
872
- return await rest.post(rest.routes.channels.forum(channelId), options);
431
+ async createForumThread (channelId, body, reason) {
432
+ return await rest.post(rest.routes.channels.forum(channelId), {
433
+ body,
434
+ files: body.files,
435
+ reason
436
+ });
873
437
  },
874
- async createInvite (channelId, options = {}) {
875
- return await rest.post(rest.routes.channels.invites(channelId), options);
438
+ async createInvite (channelId, body = {}, reason) {
439
+ return await rest.post(rest.routes.channels.invites(channelId), {
440
+ body,
441
+ reason
442
+ });
876
443
  },
877
- async createRole (guildId, options, reason) {
444
+ async createRole (guildId, body, reason) {
878
445
  return await rest.post(rest.routes.guilds.roles.all(guildId), {
879
- ...options,
446
+ body,
880
447
  reason
881
448
  });
882
449
  },
883
- async createScheduledEvent (guildId, options) {
884
- return await rest.post(rest.routes.guilds.events.events(guildId), options);
450
+ async createScheduledEvent (guildId, body, reason) {
451
+ return await rest.post(rest.routes.guilds.events.events(guildId), {
452
+ body,
453
+ reason
454
+ });
885
455
  },
886
- async createStageInstance (options) {
887
- return await rest.post(rest.routes.channels.stages(), options);
456
+ async createStageInstance (body, reason) {
457
+ return await rest.post(rest.routes.channels.stages(), {
458
+ body,
459
+ reason
460
+ });
888
461
  },
889
- async createWebhook (channelId, options) {
462
+ async createWebhook (channelId, options, reason) {
890
463
  return await rest.post(rest.routes.channels.webhooks(channelId), {
891
- name: options.name,
892
- avatar: options.avatar ? await urlToBase64(options.avatar) : undefined,
893
- reason: options.reason
464
+ body: {
465
+ name: options.name,
466
+ avatar: options.avatar ? await urlToBase64(options.avatar) : undefined
467
+ },
468
+ reason
894
469
  });
895
470
  },
896
471
  async deleteAutomodRule (guildId, ruleId, reason) {
897
- return await rest.delete(rest.routes.guilds.automod.rule(guildId, ruleId), {
472
+ await rest.delete(rest.routes.guilds.automod.rule(guildId, ruleId), {
898
473
  reason
899
474
  });
900
475
  },
901
476
  async deleteChannel (channelId, reason) {
902
- return await rest.delete(rest.routes.channels.channel(channelId), {
477
+ await rest.delete(rest.routes.channels.channel(channelId), {
903
478
  reason
904
479
  });
905
480
  },
906
481
  async deleteChannelPermissionOverride (channelId, overwriteId, reason) {
907
- return await rest.delete(rest.routes.channels.overwrite(channelId, overwriteId), reason ? {
482
+ await rest.delete(rest.routes.channels.overwrite(channelId, overwriteId), {
908
483
  reason
909
- } : undefined);
484
+ });
910
485
  },
911
486
  async deleteEmoji (guildId, id, reason) {
912
- return await rest.delete(rest.routes.guilds.emoji(guildId, id), {
487
+ await rest.delete(rest.routes.guilds.emoji(guildId, id), {
913
488
  reason
914
489
  });
915
490
  },
916
491
  async deleteFollowupMessage (token, messageId) {
917
- return await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId));
492
+ await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
493
+ unauthorized: true
494
+ });
918
495
  },
919
496
  async deleteGlobalApplicationCommand (commandId) {
920
- return await rest.delete(rest.routes.interactions.commands.command(rest.applicationId, commandId));
497
+ await rest.delete(rest.routes.interactions.commands.command(rest.applicationId, commandId));
921
498
  },
922
499
  async deleteGuild (guildId) {
923
- return await rest.delete(rest.routes.guilds.guild(guildId));
500
+ await rest.delete(rest.routes.guilds.guild(guildId));
924
501
  },
925
502
  async deleteGuildApplicationCommand (commandId, guildId) {
926
- return await rest.delete(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId));
503
+ await rest.delete(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId));
927
504
  },
928
505
  async deleteGuildSticker (guildId, stickerId, reason) {
929
- return await rest.delete(rest.routes.guilds.sticker(guildId, stickerId), reason ? {
506
+ await rest.delete(rest.routes.guilds.sticker(guildId, stickerId), {
930
507
  reason
931
- } : undefined);
508
+ });
932
509
  },
933
510
  async deleteGuildTemplate (guildId, templateCode) {
934
- return await rest.delete(rest.routes.guilds.templates.guild(guildId, templateCode));
511
+ await rest.delete(rest.routes.guilds.templates.guild(guildId, templateCode));
935
512
  },
936
- async deleteIntegration (guildId, integrationId) {
937
- return await rest.delete(rest.routes.guilds.integration(guildId, integrationId));
513
+ async deleteIntegration (guildId, integrationId, reason) {
514
+ await rest.delete(rest.routes.guilds.integration(guildId, integrationId), {
515
+ reason
516
+ });
938
517
  },
939
518
  async deleteInvite (inviteCode, reason) {
940
- return await rest.delete(rest.routes.guilds.invite(inviteCode), reason ? {
519
+ await rest.delete(rest.routes.guilds.invite(inviteCode), {
941
520
  reason
942
- } : undefined);
521
+ });
943
522
  },
944
523
  async deleteMessage (channelId, messageId, reason) {
945
- return await rest.delete(rest.routes.channels.message(channelId, messageId), {
524
+ await rest.delete(rest.routes.channels.message(channelId, messageId), {
946
525
  reason
947
526
  });
948
527
  },
949
528
  async deleteMessages (channelId, messageIds, reason) {
950
- return await rest.post(rest.routes.channels.bulk(channelId), {
951
- messages: messageIds.slice(0, 100).map((id)=>id.toString()),
529
+ await rest.post(rest.routes.channels.bulk(channelId), {
530
+ body: {
531
+ messages: messageIds.slice(0, 100).map((id)=>id.toString())
532
+ },
952
533
  reason
953
534
  });
954
535
  },
955
536
  async deleteOriginalInteractionResponse (token) {
956
- return await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token));
537
+ await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token), {
538
+ unauthorized: true
539
+ });
957
540
  },
958
541
  async deleteOwnReaction (channelId, messageId, reaction) {
959
542
  reaction = processReactionString(reaction);
960
- return await rest.delete(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
543
+ await rest.delete(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
961
544
  },
962
545
  async deleteReactionsAll (channelId, messageId) {
963
- return await rest.delete(rest.routes.channels.reactions.all(channelId, messageId));
546
+ await rest.delete(rest.routes.channels.reactions.all(channelId, messageId));
964
547
  },
965
548
  async deleteReactionsEmoji (channelId, messageId, reaction) {
966
549
  reaction = processReactionString(reaction);
967
- return await rest.delete(rest.routes.channels.reactions.emoji(channelId, messageId, reaction));
550
+ await rest.delete(rest.routes.channels.reactions.emoji(channelId, messageId, reaction));
968
551
  },
969
- async deleteRole (guildId, roleId) {
970
- return await rest.delete(rest.routes.guilds.roles.one(guildId, roleId));
552
+ async deleteRole (guildId, roleId, reason) {
553
+ await rest.delete(rest.routes.guilds.roles.one(guildId, roleId), {
554
+ reason
555
+ });
971
556
  },
972
557
  async deleteScheduledEvent (guildId, eventId) {
973
- return await rest.delete(rest.routes.guilds.events.event(guildId, eventId));
558
+ await rest.delete(rest.routes.guilds.events.event(guildId, eventId));
974
559
  },
975
560
  async deleteStageInstance (channelId, reason) {
976
- return await rest.delete(rest.routes.channels.stage(channelId), reason ? {
561
+ await rest.delete(rest.routes.channels.stage(channelId), {
977
562
  reason
978
- } : undefined);
563
+ });
979
564
  },
980
565
  async deleteUserReaction (channelId, messageId, userId, reaction) {
981
566
  reaction = processReactionString(reaction);
982
- return await rest.delete(rest.routes.channels.reactions.user(channelId, messageId, reaction, userId));
567
+ await rest.delete(rest.routes.channels.reactions.user(channelId, messageId, reaction, userId));
983
568
  },
984
569
  async deleteWebhook (webhookId, reason) {
985
- return await rest.delete(rest.routes.webhooks.id(webhookId), {
570
+ await rest.delete(rest.routes.webhooks.id(webhookId), {
986
571
  reason
987
572
  });
988
573
  },
989
574
  async deleteWebhookMessage (webhookId, token, messageId, options) {
990
- return await rest.delete(rest.routes.webhooks.message(webhookId, token, messageId, options));
575
+ await rest.delete(rest.routes.webhooks.message(webhookId, token, messageId, options));
991
576
  },
992
577
  async deleteWebhookWithToken (webhookId, token) {
993
- return await rest.delete(rest.routes.webhooks.webhook(webhookId, token));
578
+ await rest.delete(rest.routes.webhooks.webhook(webhookId, token));
994
579
  },
995
- async editApplicationCommandPermissions (guildId, commandId, bearerToken, options) {
580
+ async editApplicationCommandPermissions (guildId, commandId, bearerToken, permissions) {
996
581
  return await rest.put(rest.routes.interactions.commands.permission(rest.applicationId, guildId, commandId), {
997
- permissions: options
998
- }, {
582
+ body: {
583
+ permissions
584
+ },
999
585
  headers: {
1000
586
  authorization: `Bearer ${bearerToken}`
1001
587
  }
1002
588
  });
1003
589
  },
1004
- async editAutomodRule (guildId, ruleId, options) {
1005
- return await rest.patch(rest.routes.guilds.automod.rule(guildId, ruleId), options);
590
+ async editAutomodRule (guildId, ruleId, body, reason) {
591
+ return await rest.patch(rest.routes.guilds.automod.rule(guildId, ruleId), {
592
+ body,
593
+ reason
594
+ });
1006
595
  },
1007
596
  async editBotProfile (options) {
1008
597
  const avatar = options?.botAvatarURL ? await urlToBase64(options?.botAvatarURL) : options?.botAvatarURL;
1009
598
  return await rest.patch(rest.routes.userBot(), {
1010
- username: options.username?.trim(),
1011
- avatar
599
+ body: {
600
+ username: options.username?.trim(),
601
+ avatar
602
+ }
1012
603
  });
1013
604
  },
1014
- async editChannel (channelId, options) {
1015
- return await rest.patch(rest.routes.channels.channel(channelId), options);
605
+ async editChannel (channelId, body, reason) {
606
+ return await rest.patch(rest.routes.channels.channel(channelId), {
607
+ body,
608
+ reason
609
+ });
1016
610
  },
1017
- async editChannelPermissionOverrides (channelId, options) {
1018
- return await rest.put(rest.routes.channels.overwrite(channelId, options.id), options);
611
+ async editChannelPermissionOverrides (channelId, body, reason) {
612
+ await rest.put(rest.routes.channels.overwrite(channelId, body.id), {
613
+ body,
614
+ reason
615
+ });
1019
616
  },
1020
- async editChannelPositions (guildId, channelPositions) {
1021
- return await rest.patch(rest.routes.guilds.channels(guildId), channelPositions);
617
+ async editChannelPositions (guildId, body) {
618
+ await rest.patch(rest.routes.guilds.channels(guildId), {
619
+ body
620
+ });
1022
621
  },
1023
- async editEmoji (guildId, id, options) {
1024
- return await rest.patch(rest.routes.guilds.emoji(guildId, id), options);
622
+ async editEmoji (guildId, id, body, reason) {
623
+ return await rest.patch(rest.routes.guilds.emoji(guildId, id), {
624
+ body,
625
+ reason
626
+ });
1025
627
  },
1026
- async editFollowupMessage (token, messageId, options) {
1027
- return await rest.patch(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), options);
628
+ async editFollowupMessage (token, messageId, body) {
629
+ return await rest.patch(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
630
+ body,
631
+ files: body.files,
632
+ unauthorized: true
633
+ });
1028
634
  },
1029
- async editGlobalApplicationCommand (commandId, options) {
1030
- return await rest.patch(rest.routes.interactions.commands.command(rest.applicationId, commandId), options);
635
+ async editGlobalApplicationCommand (commandId, body) {
636
+ return await rest.patch(rest.routes.interactions.commands.command(rest.applicationId, commandId), {
637
+ body
638
+ });
1031
639
  },
1032
- async editGuild (guildId, options) {
1033
- return await rest.patch(rest.routes.guilds.guild(guildId), options);
640
+ async editGuild (guildId, body, reason) {
641
+ return await rest.patch(rest.routes.guilds.guild(guildId), {
642
+ body,
643
+ reason
644
+ });
1034
645
  },
1035
- async editGuildApplicationCommand (commandId, guildId, options) {
1036
- return await rest.patch(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId), options);
646
+ async editGuildApplicationCommand (commandId, guildId, body) {
647
+ return await rest.patch(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId), {
648
+ body
649
+ });
1037
650
  },
1038
651
  async editGuildMfaLevel (guildId, mfaLevel, reason) {
1039
- return await rest.post(rest.routes.guilds.mfa(guildId), {
1040
- level: mfaLevel,
652
+ await rest.post(rest.routes.guilds.mfa(guildId), {
653
+ body: {
654
+ level: mfaLevel
655
+ },
1041
656
  reason
1042
657
  });
1043
658
  },
1044
- async editGuildSticker (guildId, stickerId, options) {
1045
- return await rest.patch(rest.routes.guilds.sticker(guildId, stickerId), options);
659
+ async editGuildSticker (guildId, stickerId, body, reason) {
660
+ return await rest.patch(rest.routes.guilds.sticker(guildId, stickerId), {
661
+ body,
662
+ reason
663
+ });
1046
664
  },
1047
- async editGuildTemplate (guildId, templateCode, options) {
1048
- return await rest.patch(rest.routes.guilds.templates.guild(guildId, templateCode), options);
665
+ async editGuildTemplate (guildId, templateCode, body) {
666
+ return await rest.patch(rest.routes.guilds.templates.guild(guildId, templateCode), {
667
+ body
668
+ });
1049
669
  },
1050
- async editMessage (channelId, messageId, options) {
1051
- return await rest.patch(rest.routes.channels.message(channelId, messageId), options);
670
+ async editMessage (channelId, messageId, body) {
671
+ return await rest.patch(rest.routes.channels.message(channelId, messageId), {
672
+ body
673
+ });
1052
674
  },
1053
- async editOriginalInteractionResponse (token, options) {
1054
- return await rest.patch(rest.routes.interactions.responses.original(rest.applicationId, token), options);
675
+ async editOriginalInteractionResponse (token, body) {
676
+ return await rest.patch(rest.routes.interactions.responses.original(rest.applicationId, token), {
677
+ body,
678
+ files: body.files
679
+ });
1055
680
  },
1056
681
  async editOriginalWebhookMessage (webhookId, token, options) {
1057
682
  return await rest.patch(rest.routes.webhooks.original(webhookId, token, options), {
1058
- type: InteractionResponseTypes.UpdateMessage,
1059
- data: options
683
+ body: {
684
+ type: InteractionResponseTypes.UpdateMessage,
685
+ data: options
686
+ },
687
+ files: options.files,
688
+ unauthorized: true
1060
689
  });
1061
690
  },
1062
691
  async editOwnVoiceState (guildId, options) {
1063
- return await rest.patch(rest.routes.guilds.voice(guildId), {
1064
- channel_id: options.channelId,
1065
- suppress: options.suppress,
1066
- request_to_speak_timestamp: options.requestToSpeakTimestamp ? new Date(options.requestToSpeakTimestamp).toISOString() : options.requestToSpeakTimestamp
692
+ await rest.patch(rest.routes.guilds.voice(guildId), {
693
+ body: {
694
+ ...options,
695
+ request_to_speak_timestamp: options.requestToSpeakTimestamp ? new Date(options.requestToSpeakTimestamp).toISOString() : options.requestToSpeakTimestamp
696
+ }
1067
697
  });
1068
698
  },
1069
- async editScheduledEvent (guildId, eventId, options) {
1070
- return await rest.patch(rest.routes.guilds.events.event(guildId, eventId), options);
699
+ async editScheduledEvent (guildId, eventId, body, reason) {
700
+ return await rest.patch(rest.routes.guilds.events.event(guildId, eventId), {
701
+ body,
702
+ reason
703
+ });
1071
704
  },
1072
- async editRole (guildId, roleId, options) {
1073
- return await rest.patch(rest.routes.guilds.roles.one(guildId, roleId), options);
705
+ async editRole (guildId, roleId, body, reason) {
706
+ return await rest.patch(rest.routes.guilds.roles.one(guildId, roleId), {
707
+ body,
708
+ reason
709
+ });
1074
710
  },
1075
- async editRolePositions (guildId, options) {
1076
- return await rest.patch(rest.routes.guilds.roles.all(guildId), options);
711
+ async editRolePositions (guildId, body, reason) {
712
+ return await rest.patch(rest.routes.guilds.roles.all(guildId), {
713
+ body,
714
+ reason
715
+ });
1077
716
  },
1078
- async editStageInstance (channelId, data) {
717
+ async editStageInstance (channelId, topic, reason) {
1079
718
  return await rest.patch(rest.routes.channels.stage(channelId), {
1080
- topic: data.topic
719
+ body: {
720
+ topic
721
+ },
722
+ reason
1081
723
  });
1082
724
  },
1083
725
  async editUserVoiceState (guildId, options) {
1084
- return await rest.patch(rest.routes.guilds.voice(guildId, options.userId), {
1085
- channel_id: options.channelId,
1086
- suppress: options.suppress,
1087
- user_id: options.userId
726
+ await rest.patch(rest.routes.guilds.voice(guildId, options.userId), {
727
+ body: options
1088
728
  });
1089
729
  },
1090
- async editWebhook (webhookId, options) {
1091
- return await rest.patch(rest.routes.webhooks.id(webhookId), options);
730
+ async editWebhook (webhookId, body, reason) {
731
+ return await rest.patch(rest.routes.webhooks.id(webhookId), {
732
+ body,
733
+ reason
734
+ });
1092
735
  },
1093
736
  async editWebhookMessage (webhookId, token, messageId, options) {
1094
- return await rest.patch(rest.routes.webhooks.message(webhookId, token, messageId, options), options);
737
+ return await rest.patch(rest.routes.webhooks.message(webhookId, token, messageId, options), {
738
+ body: options,
739
+ files: options.files
740
+ });
1095
741
  },
1096
- async editWebhookWithToken (webhookId, token, options) {
1097
- return await rest.patch(rest.routes.webhooks.webhook(webhookId, token), options);
742
+ async editWebhookWithToken (webhookId, token, body) {
743
+ return await rest.patch(rest.routes.webhooks.webhook(webhookId, token), {
744
+ body
745
+ });
1098
746
  },
1099
- async editWelcomeScreen (guildId, options) {
1100
- return await rest.patch(rest.routes.guilds.welcome(guildId), options);
747
+ async editWelcomeScreen (guildId, body, reason) {
748
+ return await rest.patch(rest.routes.guilds.welcome(guildId), {
749
+ body,
750
+ reason
751
+ });
1101
752
  },
1102
- async editWidgetSettings (guildId, options) {
1103
- return await rest.patch(rest.routes.guilds.widget(guildId), options);
753
+ async editWidgetSettings (guildId, body, reason) {
754
+ return await rest.patch(rest.routes.guilds.widget(guildId), {
755
+ body,
756
+ reason
757
+ });
1104
758
  },
1105
759
  async executeWebhook (webhookId, token, options) {
1106
- return await rest.post(rest.routes.webhooks.webhook(webhookId, token, options), options);
760
+ return await rest.post(rest.routes.webhooks.webhook(webhookId, token, options), {
761
+ body: options
762
+ });
1107
763
  },
1108
764
  async followAnnouncement (sourceChannelId, targetChannelId) {
1109
765
  return await rest.post(rest.routes.channels.follow(sourceChannelId), {
1110
- webhook_channel_id: targetChannelId
766
+ body: {
767
+ webhook_channel_id: targetChannelId
768
+ }
1111
769
  });
1112
770
  },
1113
771
  async getActiveThreads (guildId) {
@@ -1154,7 +812,9 @@ export function createRestManager(options) {
1154
812
  },
1155
813
  async getDmChannel (userId) {
1156
814
  return await rest.post(rest.routes.channels.dm(), {
1157
- recipient_id: userId.toString()
815
+ body: {
816
+ recipient_id: userId
817
+ }
1158
818
  });
1159
819
  },
1160
820
  async getEmoji (guildId, emojiId) {
@@ -1164,7 +824,9 @@ export function createRestManager(options) {
1164
824
  return await rest.get(rest.routes.guilds.emojis(guildId));
1165
825
  },
1166
826
  async getFollowupMessage (token, messageId) {
1167
- return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId));
827
+ return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
828
+ unauthorized: true
829
+ });
1168
830
  },
1169
831
  async getGatewayBot () {
1170
832
  return await rest.get(rest.routes.gatewayBot());
@@ -1217,7 +879,9 @@ export function createRestManager(options) {
1217
879
  return await rest.get(rest.routes.nitroStickerPacks());
1218
880
  },
1219
881
  async getOriginalInteractionResponse (token) {
1220
- return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token));
882
+ return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token), {
883
+ unauthorized: true
884
+ });
1221
885
  },
1222
886
  async getPinnedMessages (channelId) {
1223
887
  return await rest.get(rest.routes.channels.pins(channelId));
@@ -1298,77 +962,78 @@ export function createRestManager(options) {
1298
962
  return await rest.get(rest.routes.guilds.widget(guildId));
1299
963
  },
1300
964
  async joinThread (channelId) {
1301
- return await rest.put(rest.routes.channels.threads.me(channelId));
965
+ await rest.put(rest.routes.channels.threads.me(channelId));
1302
966
  },
1303
967
  async leaveGuild (guildId) {
1304
- return await rest.delete(rest.routes.guilds.leave(guildId));
968
+ await rest.delete(rest.routes.guilds.leave(guildId));
1305
969
  },
1306
970
  async leaveThread (channelId) {
1307
- return await rest.delete(rest.routes.channels.threads.me(channelId));
971
+ await rest.delete(rest.routes.channels.threads.me(channelId));
1308
972
  },
1309
973
  async publishMessage (channelId, messageId) {
1310
974
  return await rest.post(rest.routes.channels.crosspost(channelId, messageId));
1311
975
  },
1312
976
  async removeRole (guildId, userId, roleId, reason) {
1313
- return await rest.delete(rest.routes.guilds.roles.member(guildId, userId, roleId), {
977
+ await rest.delete(rest.routes.guilds.roles.member(guildId, userId, roleId), {
1314
978
  reason
1315
979
  });
1316
980
  },
1317
981
  async removeThreadMember (channelId, userId) {
1318
- return await rest.delete(rest.routes.channels.threads.user(channelId, userId));
982
+ await rest.delete(rest.routes.channels.threads.user(channelId, userId));
1319
983
  },
1320
984
  async sendFollowupMessage (token, options) {
1321
- return await new Promise((resolve, reject)=>{
1322
- rest.sendRequest({
1323
- url: rest.routes.webhooks.webhook(rest.applicationId, token),
1324
- method: 'POST',
1325
- body: options,
1326
- retryCount: 0,
1327
- retryRequest: async function(options) {
1328
- // TODO: should change to reprocess queue item
1329
- await rest.sendRequest(options);
1330
- },
1331
- resolve: (data)=>resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined),
1332
- reject
1333
- });
985
+ return await rest.post(rest.routes.webhooks.webhook(rest.applicationId, token), {
986
+ body: options,
987
+ files: options.files,
988
+ unauthorized: true
1334
989
  });
1335
990
  },
1336
991
  async sendInteractionResponse (interactionId, token, options) {
1337
- return await new Promise((resolve, reject)=>{
1338
- rest.sendRequest({
1339
- url: rest.routes.interactions.responses.callback(interactionId, token),
1340
- method: 'POST',
1341
- body: options,
1342
- retryCount: 0,
1343
- retryRequest: async function(options) {
1344
- // TODO: should change to reprocess queue item
1345
- await rest.sendRequest(options);
1346
- },
1347
- resolve: (data)=>resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined),
1348
- reject
1349
- });
992
+ return await rest.post(rest.routes.interactions.responses.callback(interactionId, token), {
993
+ body: options,
994
+ files: options.data?.files,
995
+ runThroughQueue: false,
996
+ unauthorized: true
1350
997
  });
1351
998
  },
1352
- async sendMessage (channelId, options) {
1353
- return await rest.post(rest.routes.channels.messages(channelId), options);
999
+ async sendMessage (channelId, body) {
1000
+ return await rest.post(rest.routes.channels.messages(channelId), {
1001
+ body,
1002
+ files: body.files
1003
+ });
1354
1004
  },
1355
- async startThreadWithMessage (channelId, messageId, options) {
1356
- return await rest.post(rest.routes.channels.threads.message(channelId, messageId), options);
1005
+ async startThreadWithMessage (channelId, messageId, body, reason) {
1006
+ return await rest.post(rest.routes.channels.threads.message(channelId, messageId), {
1007
+ body,
1008
+ reason
1009
+ });
1357
1010
  },
1358
- async startThreadWithoutMessage (channelId, options) {
1359
- return await rest.post(rest.routes.channels.threads.all(channelId), options);
1011
+ async startThreadWithoutMessage (channelId, body, reason) {
1012
+ return await rest.post(rest.routes.channels.threads.all(channelId), {
1013
+ body,
1014
+ reason
1015
+ });
1360
1016
  },
1361
1017
  async syncGuildTemplate (guildId) {
1362
1018
  return await rest.put(rest.routes.guilds.templates.all(guildId));
1363
1019
  },
1364
- async banMember (guildId, userId, options) {
1365
- return await rest.put(rest.routes.guilds.members.ban(guildId, userId), options);
1020
+ async banMember (guildId, userId, body, reason) {
1021
+ await rest.put(rest.routes.guilds.members.ban(guildId, userId), {
1022
+ body,
1023
+ reason
1024
+ });
1366
1025
  },
1367
- async editBotMember (guildId, options) {
1368
- return await rest.patch(rest.routes.guilds.members.bot(guildId), options);
1026
+ async editBotMember (guildId, body, reason) {
1027
+ return await rest.patch(rest.routes.guilds.members.bot(guildId), {
1028
+ body,
1029
+ reason
1030
+ });
1369
1031
  },
1370
- async editMember (guildId, userId, options) {
1371
- return await rest.patch(rest.routes.guilds.members.member(guildId, userId), options);
1032
+ async editMember (guildId, userId, body, reason) {
1033
+ return await rest.patch(rest.routes.guilds.members.member(guildId, userId), {
1034
+ body,
1035
+ reason
1036
+ });
1372
1037
  },
1373
1038
  async getMember (guildId, userId) {
1374
1039
  return await rest.get(rest.routes.guilds.members.member(guildId, userId));
@@ -1377,37 +1042,46 @@ export function createRestManager(options) {
1377
1042
  return await rest.get(rest.routes.guilds.members.members(guildId, options));
1378
1043
  },
1379
1044
  async kickMember (guildId, userId, reason) {
1380
- return await rest.delete(rest.routes.guilds.members.member(guildId, userId), {
1045
+ await rest.delete(rest.routes.guilds.members.member(guildId, userId), {
1381
1046
  reason
1382
1047
  });
1383
1048
  },
1384
1049
  async pinMessage (channelId, messageId, reason) {
1385
- return await rest.put(rest.routes.channels.pin(channelId, messageId), reason ? {
1050
+ await rest.put(rest.routes.channels.pin(channelId, messageId), {
1386
1051
  reason
1387
- } : undefined);
1052
+ });
1388
1053
  },
1389
- async pruneMembers (guildId, options) {
1390
- return await rest.post(rest.routes.guilds.members.prune(guildId), options);
1054
+ async pruneMembers (guildId, body, reason) {
1055
+ return await rest.post(rest.routes.guilds.members.prune(guildId), {
1056
+ body,
1057
+ reason
1058
+ });
1391
1059
  },
1392
1060
  async searchMembers (guildId, query, options) {
1393
1061
  return await rest.get(rest.routes.guilds.members.search(guildId, query, options));
1394
1062
  },
1395
- async unbanMember (guildId, userId) {
1396
- return await rest.delete(rest.routes.guilds.members.ban(guildId, userId));
1063
+ async unbanMember (guildId, userId, reason) {
1064
+ await rest.delete(rest.routes.guilds.members.ban(guildId, userId), {
1065
+ reason
1066
+ });
1397
1067
  },
1398
1068
  async unpinMessage (channelId, messageId, reason) {
1399
- return await rest.delete(rest.routes.channels.pin(channelId, messageId), reason ? {
1069
+ await rest.delete(rest.routes.channels.pin(channelId, messageId), {
1400
1070
  reason
1401
- } : undefined);
1071
+ });
1402
1072
  },
1403
1073
  async triggerTypingIndicator (channelId) {
1404
- return await rest.post(rest.routes.channels.typing(channelId));
1074
+ await rest.post(rest.routes.channels.typing(channelId));
1405
1075
  },
1406
- async upsertGlobalApplicationCommands (commands) {
1407
- return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), commands);
1076
+ async upsertGlobalApplicationCommands (body) {
1077
+ return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), {
1078
+ body
1079
+ });
1408
1080
  },
1409
- async upsertGuildApplicationCommands (guildId, commands) {
1410
- return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), commands);
1081
+ async upsertGuildApplicationCommands (guildId, body) {
1082
+ return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), {
1083
+ body
1084
+ });
1411
1085
  }
1412
1086
  };
1413
1087
  return rest;