@discordeno/rest 19.0.0-next.40c19da → 19.0.0-next.40eaf17

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