@discordeno/rest 19.0.0-next.b044211 → 19.0.0-next.b1a4739

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.
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAA4B,wBAAwB,EAAE,WAAW,EAAsB,MAAM,YAAY,CAAA;AAKrH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,eAAe,4BAA4B,CAAA;AAExD,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAC3D,eAAO,MAAM,2BAA2B,0BAA0B,CAAA;AAClE,eAAO,MAAM,6BAA6B,4BAA4B,CAAA;AACtE,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,uBAAuB,sBAAsB,CAAA;AAC1D,eAAO,MAAM,uBAAuB,sBAAsB,CAAA;AAE1D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAkoChF"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAyDA,OAAO,KAAK,EAA4B,wBAAwB,EAAsB,WAAW,EAAsB,MAAM,YAAY,CAAA;AAKzI,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,eAAe,4BAA4B,CAAA;AAExD,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAC3D,eAAO,MAAM,2BAA2B,0BAA0B,CAAA;AAClE,eAAO,MAAM,6BAA6B,4BAA4B,CAAA;AACtE,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,uBAAuB,sBAAsB,CAAA;AAC1D,eAAO,MAAM,uBAAuB,sBAAsB,CAAA;AAE1D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAk3ChF"}
package/dist/manager.js CHANGED
@@ -1,4 +1,5 @@
1
- /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable no-const-assign */ import { calculateBits, camelToSnakeCase, camelize, delay, getBotIdFromToken, logger, processReactionString, urlToBase64 } from '@discordeno/utils';
1
+ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable no-const-assign */ import { Buffer } from 'node:buffer';
2
+ import { calculateBits, camelToSnakeCase, camelize, delay, getBotIdFromToken, logger, processReactionString, urlToBase64 } from '@discordeno/utils';
2
3
  import { createInvalidRequestBucket } from './invalidBucket.js';
3
4
  import { Queue } from './queue.js';
4
5
  import { InteractionResponseTypes } from '@discordeno/types';
@@ -35,8 +36,14 @@ export function createRestManager(options) {
35
36
  token: options.token,
36
37
  version: options.version ?? DISCORD_API_VERSION,
37
38
  routes: createRoutes(),
38
- checkRateLimits (url) {
39
- const ratelimited = rest.rateLimitedPaths.get(url);
39
+ createBaseHeaders () {
40
+ return {
41
+ 'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v${version})`
42
+ };
43
+ },
44
+ checkRateLimits (url, headers) {
45
+ const authHeader = headers?.authorization ?? '';
46
+ const ratelimited = rest.rateLimitedPaths.get(`${authHeader}${url}`);
40
47
  const global = rest.rateLimitedPaths.get('global');
41
48
  const now = Date.now();
42
49
  if (ratelimited && now < ratelimited.resetTimestamp) {
@@ -55,20 +62,27 @@ export function createRestManager(options) {
55
62
  }
56
63
  const newObj = {};
57
64
  for (const key of Object.keys(obj)){
58
- // Keys that dont require snake casing
59
- if ([
60
- 'permissions',
61
- 'allow',
62
- 'deny'
63
- ].includes(key) && obj[key] !== undefined) {
64
- newObj[key] = calculateBits(obj[key]);
65
- continue;
65
+ const value = obj[key];
66
+ // Some falsy values should be allowed like null or 0
67
+ if (value !== undefined) {
68
+ switch(key){
69
+ case 'permissions':
70
+ case 'allow':
71
+ case 'deny':
72
+ newObj[key] = typeof value === 'string' ? value : calculateBits(value);
73
+ continue;
74
+ case 'defaultMemberPermissions':
75
+ newObj.default_member_permissions = typeof value === 'string' ? value : calculateBits(value);
76
+ continue;
77
+ case 'nameLocalizations':
78
+ newObj.name_localizations = value;
79
+ continue;
80
+ case 'descriptionLocalizations':
81
+ newObj.description_localizations = value;
82
+ continue;
83
+ }
66
84
  }
67
- if (key === 'defaultMemberPermissions' && obj[key] !== undefined) {
68
- newObj.default_member_permissions = calculateBits(obj[key]);
69
- continue;
70
- }
71
- newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(obj[key]);
85
+ newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(value);
72
86
  }
73
87
  return newObj;
74
88
  }
@@ -76,10 +90,8 @@ export function createRestManager(options) {
76
90
  return obj;
77
91
  },
78
92
  createRequestBody (method, options) {
79
- const headers = {
80
- 'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v${version})`
81
- };
82
- if (options?.unauthorized !== false) headers.authorization = `Bot ${rest.token}`;
93
+ const headers = this.createBaseHeaders();
94
+ if (options?.unauthorized !== true) headers.authorization = `Bot ${rest.token}`;
83
95
  // IF A REASON IS PROVIDED ENCODE IT IN HEADERS
84
96
  if (options?.reason !== undefined) {
85
97
  headers[AUDIT_LOG_REASON_HEADER] = encodeURIComponent(options?.reason);
@@ -93,12 +105,21 @@ export function createRestManager(options) {
93
105
  for(let i = 0; i < options.files.length; ++i){
94
106
  form.append(`file${i}`, options.files[i].blob, options.files[i].name);
95
107
  }
96
- form.append('payload_json', JSON.stringify({
108
+ // Have to use changeToDiscordFormat or else JSON.stringify may throw an error for the presence of BigInt(s) in the json
109
+ form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat({
97
110
  ...options.body,
98
111
  files: undefined
99
- }));
112
+ })));
113
+ // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
100
114
  body = form;
101
- // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
115
+ } else if (options?.body && options.headers && options.headers['content-type'] === 'application/x-www-form-urlencoded') {
116
+ // OAuth2 body handling
117
+ const formBody = [];
118
+ const discordBody = rest.changeToDiscordFormat(options.body);
119
+ for(const prop in discordBody){
120
+ formBody.push(`${encodeURIComponent(prop)}=${encodeURIComponent(discordBody[prop])}`);
121
+ }
122
+ body = formBody.join('&');
102
123
  } else if (options?.body !== undefined) {
103
124
  if (options.body instanceof FormData) {
104
125
  body = options.body;
@@ -145,7 +166,7 @@ export function createRestManager(options) {
145
166
  }, 1000);
146
167
  }
147
168
  },
148
- /** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */ processHeaders (url, headers) {
169
+ /** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */ processHeaders (url, headers, requestAuthorization) {
149
170
  let rateLimited = false;
150
171
  // GET ALL NECESSARY HEADERS
151
172
  const remaining = headers.get(RATE_LIMIT_REMAINING_HEADER);
@@ -155,7 +176,7 @@ export function createRestManager(options) {
155
176
  // undefined override null needed for typings
156
177
  const bucketId = headers.get(RATE_LIMIT_BUCKET_HEADER) ?? undefined;
157
178
  const limit = headers.get(RATE_LIMIT_LIMIT_HEADER);
158
- rest.queues.get(url)?.handleCompletedRequest({
179
+ rest.queues.get(`${requestAuthorization}${url}`)?.handleCompletedRequest({
159
180
  remaining: remaining ? Number(remaining) : undefined,
160
181
  interval: retryAfter ? Number(retryAfter) * 1000 : undefined,
161
182
  max: limit ? Number(limit) : undefined
@@ -164,14 +185,14 @@ export function createRestManager(options) {
164
185
  if (remaining === '0') {
165
186
  rateLimited = true;
166
187
  // SAVE THE URL AS LIMITED, IMPORTANT FOR NEW REQUESTS BY USER WITHOUT BUCKET
167
- rest.rateLimitedPaths.set(url, {
188
+ rest.rateLimitedPaths.set(`${requestAuthorization}${url}`, {
168
189
  url,
169
190
  resetTimestamp: reset,
170
191
  bucketId
171
192
  });
172
193
  // SAVE THE BUCKET AS LIMITED SINCE DIFFERENT URLS MAY SHARE A BUCKET
173
194
  if (bucketId) {
174
- rest.rateLimitedPaths.set(bucketId, {
195
+ rest.rateLimitedPaths.set(`${requestAuthorization}${bucketId}`, {
175
196
  url,
176
197
  resetTimestamp: reset,
177
198
  bucketId
@@ -180,8 +201,8 @@ export function createRestManager(options) {
180
201
  }
181
202
  // IF THERE IS NO REMAINING GLOBAL LIMIT, MARK IT RATE LIMITED GLOBALLY
182
203
  if (global) {
183
- const retryAfter = headers.get('retry-after');
184
- const globalReset = Date.now() + Number(retryAfter) * 1000;
204
+ const retryAfter = Number(headers.get('retry-after')) * 1000;
205
+ const globalReset = Date.now() + retryAfter;
185
206
  // rest.debug(
186
207
  // `[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}`
187
208
  // )
@@ -189,14 +210,14 @@ export function createRestManager(options) {
189
210
  rateLimited = true;
190
211
  setTimeout(()=>{
191
212
  rest.globallyRateLimited = false;
192
- }, globalReset);
213
+ }, retryAfter);
193
214
  rest.rateLimitedPaths.set('global', {
194
215
  url: 'global',
195
216
  resetTimestamp: globalReset,
196
217
  bucketId
197
218
  });
198
219
  if (bucketId) {
199
- rest.rateLimitedPaths.set(bucketId, {
220
+ rest.rateLimitedPaths.set(`${requestAuthorization}${bucketId}`, {
200
221
  url: 'global',
201
222
  resetTimestamp: globalReset,
202
223
  bucketId
@@ -211,12 +232,16 @@ export function createRestManager(options) {
211
232
  async sendRequest (options) {
212
233
  const url = `${rest.baseUrl}/v${rest.version}${options.route}`;
213
234
  const payload = rest.createRequestBody(options.method, options.requestBodyOptions);
235
+ const loggingHeaders = {
236
+ ...payload.headers
237
+ };
238
+ const authenticationScheme = payload.headers.authorization?.split(' ')[0];
239
+ if (payload.headers.authorization) {
240
+ loggingHeaders.authorization = `${authenticationScheme} tokenhere`;
241
+ }
214
242
  logger.debug(`sending request to ${url}`, 'with payload:', {
215
243
  ...payload,
216
- headers: {
217
- ...payload.headers,
218
- authorization: 'Bot tokenhere'
219
- }
244
+ headers: loggingHeaders
220
245
  });
221
246
  const response = await fetch(url, payload).catch(async (error)=>{
222
247
  logger.error(error);
@@ -233,7 +258,7 @@ export function createRestManager(options) {
233
258
  // Mark request and completed
234
259
  rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get(RATE_LIMIT_SCOPE_HEADER) === 'shared');
235
260
  // Set the bucket id if it was available on the headers
236
- const bucketId = rest.processHeaders(rest.simplifyUrl(options.route, options.method), response.headers);
261
+ const bucketId = rest.processHeaders(rest.simplifyUrl(options.route, options.method), response.headers, authenticationScheme === 'Bearer' ? payload.headers.authorization : '');
237
262
  if (bucketId) options.bucketId = bucketId;
238
263
  if (response.status < 200 || response.status >= 400) {
239
264
  logger.debug(`Request to ${url} failed.`);
@@ -298,19 +323,21 @@ export function createRestManager(options) {
298
323
  await rest.sendRequest(request);
299
324
  return;
300
325
  }
301
- const queue = rest.queues.get(url);
326
+ const authHeader = request.requestBodyOptions?.headers?.authorization ?? '';
327
+ const queue = rest.queues.get(`${authHeader}${url}`);
302
328
  if (queue !== undefined) {
303
329
  queue.makeRequest(request);
304
330
  } else {
305
331
  // CREATES A NEW QUEUE
306
332
  const bucketQueue = new Queue(rest, {
307
333
  url,
308
- deleteQueueDelay: rest.deleteQueueDelay
334
+ deleteQueueDelay: rest.deleteQueueDelay,
335
+ authentication: authHeader
309
336
  });
310
337
  // Add request to queue
311
338
  bucketQueue.makeRequest(request);
312
339
  // Save queue
313
- rest.queues.set(url, bucketQueue);
340
+ rest.queues.set(`${authHeader}${url}`, bucketQueue);
314
341
  }
315
342
  },
316
343
  async makeRequest (method, route, options) {
@@ -386,6 +413,11 @@ export function createRestManager(options) {
386
413
  async addThreadMember (channelId, userId) {
387
414
  await rest.put(rest.routes.channels.threads.user(channelId, userId));
388
415
  },
416
+ async addDmRecipient (channelId, userId, body) {
417
+ await rest.put(rest.routes.channels.dmRecipient(channelId, userId), {
418
+ body
419
+ });
420
+ },
389
421
  async createAutomodRule (guildId, body, reason) {
390
422
  return await rest.post(rest.routes.guilds.automod.rules(guildId), {
391
423
  body,
@@ -404,20 +436,34 @@ export function createRestManager(options) {
404
436
  reason
405
437
  });
406
438
  },
407
- async createGlobalApplicationCommand (body) {
408
- return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), {
439
+ async createGlobalApplicationCommand (body, options) {
440
+ const restOptions = {
409
441
  body
410
- });
442
+ };
443
+ if (options?.bearerToken) {
444
+ restOptions.unauthorized = true;
445
+ restOptions.headers = {
446
+ authorization: `Bearer ${options.bearerToken}`
447
+ };
448
+ }
449
+ return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), restOptions);
411
450
  },
412
451
  async createGuild (body) {
413
452
  return await rest.post(rest.routes.guilds.all(), {
414
453
  body
415
454
  });
416
455
  },
417
- async createGuildApplicationCommand (body, guildId) {
418
- return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), {
456
+ async createGuildApplicationCommand (body, guildId, options) {
457
+ const restOptions = {
419
458
  body
420
- });
459
+ };
460
+ if (options?.bearerToken) {
461
+ restOptions.unauthorized = true;
462
+ restOptions.headers = {
463
+ authorization: `Bearer ${options.bearerToken}`
464
+ };
465
+ }
466
+ return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions);
421
467
  },
422
468
  async createGuildFromTemplate (templateCode, body) {
423
469
  if (body.icon) {
@@ -610,7 +656,7 @@ export function createRestManager(options) {
610
656
  },
611
657
  async editBotProfile (options) {
612
658
  const avatar = options?.botAvatarURL ? await urlToBase64(options?.botAvatarURL) : options?.botAvatarURL;
613
- return await rest.patch(rest.routes.userBot(), {
659
+ return await rest.patch(rest.routes.currentUser(), {
614
660
  body: {
615
661
  username: options.username?.trim(),
616
662
  avatar
@@ -684,7 +730,8 @@ export function createRestManager(options) {
684
730
  },
685
731
  async editMessage (channelId, messageId, body) {
686
732
  return await rest.patch(rest.routes.channels.message(channelId, messageId), {
687
- body
733
+ body,
734
+ files: body.files
688
735
  });
689
736
  },
690
737
  async editOriginalInteractionResponse (token, body) {
@@ -786,14 +833,60 @@ export function createRestManager(options) {
786
833
  async getActiveThreads (guildId) {
787
834
  return await rest.get(rest.routes.channels.threads.active(guildId));
788
835
  },
789
- async getApplicationCommandPermission (guildId, commandId) {
790
- return await rest.get(rest.routes.interactions.commands.permission(rest.applicationId, guildId, commandId));
791
- },
792
- async getApplicationCommandPermissions (guildId) {
793
- return await rest.get(rest.routes.interactions.commands.permissions(rest.applicationId, guildId));
836
+ async getApplicationCommandPermission (guildId, commandId, options) {
837
+ const restOptions = {};
838
+ if (options?.accessToken) {
839
+ restOptions.unauthorized = true;
840
+ restOptions.headers = {
841
+ authorization: `Bearer ${options.accessToken}`
842
+ };
843
+ }
844
+ return await rest.get(rest.routes.interactions.commands.permission(options?.applicationId ?? rest.applicationId, guildId, commandId), restOptions);
845
+ },
846
+ async getApplicationCommandPermissions (guildId, options) {
847
+ const restOptions = {};
848
+ if (options?.accessToken) {
849
+ restOptions.unauthorized = true;
850
+ restOptions.headers = {
851
+ authorization: `Bearer ${options.accessToken}`
852
+ };
853
+ }
854
+ return await rest.get(rest.routes.interactions.commands.permissions(options?.applicationId ?? rest.applicationId, guildId), restOptions);
794
855
  },
795
856
  async getApplicationInfo () {
796
- return await rest.get(rest.routes.oauth2Application());
857
+ return await rest.get(rest.routes.oauth2.application());
858
+ },
859
+ async getCurrentAuthenticationInfo (token) {
860
+ return await rest.get(rest.routes.oauth2.currentAuthorization(), {
861
+ headers: {
862
+ authorization: `Bearer ${token}`
863
+ },
864
+ unauthorized: true
865
+ });
866
+ },
867
+ async exchangeToken (body) {
868
+ const restOptions = {
869
+ body,
870
+ headers: {
871
+ 'content-type': 'application/x-www-form-urlencoded'
872
+ },
873
+ unauthorized: true
874
+ };
875
+ if (body.grantType === 'client_credentials') {
876
+ const basicCredentials = Buffer.from(`${body.clientId}:${body.clientSecret}`);
877
+ restOptions.headers.authorization = `Basic ${basicCredentials.toString('base64')}`;
878
+ restOptions.body.scope = body.scope.join(' ');
879
+ }
880
+ return await rest.post(rest.routes.oauth2.tokenExchange(), restOptions);
881
+ },
882
+ async revokeToken (body) {
883
+ await rest.post(rest.routes.oauth2.tokenRevoke(), {
884
+ body,
885
+ headers: {
886
+ 'content-type': 'application/x-www-form-urlencoded'
887
+ },
888
+ unauthorized: true
889
+ });
797
890
  },
798
891
  async getAuditLog (guildId, options) {
799
892
  return await rest.get(rest.routes.guilds.auditlogs(guildId, options));
@@ -832,6 +925,11 @@ export function createRestManager(options) {
832
925
  }
833
926
  });
834
927
  },
928
+ async getGroupDmChannel (body) {
929
+ return await rest.post(rest.routes.channels.dm(), {
930
+ body
931
+ });
932
+ },
835
933
  async getEmoji (guildId, emojiId) {
836
934
  return await rest.get(rest.routes.guilds.emoji(guildId, emojiId));
837
935
  },
@@ -857,6 +955,14 @@ export function createRestManager(options) {
857
955
  }) {
858
956
  return await rest.get(rest.routes.guilds.guild(guildId, options.counts));
859
957
  },
958
+ async getGuilds (token, options) {
959
+ return await rest.get(rest.routes.guilds.userGuilds(options), {
960
+ headers: {
961
+ authorization: `Bearer ${token}`
962
+ },
963
+ unauthorized: true
964
+ });
965
+ },
860
966
  async getGuildApplicationCommand (commandId, guildId) {
861
967
  return await rest.get(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId));
862
968
  },
@@ -952,6 +1058,30 @@ export function createRestManager(options) {
952
1058
  async getUser (id) {
953
1059
  return await rest.get(rest.routes.user(id));
954
1060
  },
1061
+ async getCurrentUser (token) {
1062
+ return await rest.get(rest.routes.currentUser(), {
1063
+ headers: {
1064
+ authorization: `Bearer ${token}`
1065
+ },
1066
+ unauthorized: true
1067
+ });
1068
+ },
1069
+ async getUserConnections (token) {
1070
+ return await rest.get(rest.routes.oauth2.connections(), {
1071
+ headers: {
1072
+ authorization: `Bearer ${token}`
1073
+ },
1074
+ unauthorized: true
1075
+ });
1076
+ },
1077
+ async getUserApplicationRoleConnection (token, applicationId) {
1078
+ return await rest.get(rest.routes.oauth2.roleConnections(applicationId), {
1079
+ headers: {
1080
+ authorization: `Bearer ${token}`
1081
+ },
1082
+ unauthorized: true
1083
+ });
1084
+ },
955
1085
  async getVanityUrl (guildId) {
956
1086
  return await rest.get(rest.routes.guilds.vanity(guildId));
957
1087
  },
@@ -996,6 +1126,9 @@ export function createRestManager(options) {
996
1126
  async removeThreadMember (channelId, userId) {
997
1127
  await rest.delete(rest.routes.channels.threads.user(channelId, userId));
998
1128
  },
1129
+ async removeDmRecipient (channelId, userId) {
1130
+ await rest.delete(rest.routes.channels.dmRecipient(channelId, userId));
1131
+ },
999
1132
  async sendFollowupMessage (token, options) {
1000
1133
  return await rest.post(rest.routes.webhooks.webhook(rest.applicationId, token), {
1001
1134
  body: options,
@@ -1053,6 +1186,14 @@ export function createRestManager(options) {
1053
1186
  async getMember (guildId, userId) {
1054
1187
  return await rest.get(rest.routes.guilds.members.member(guildId, userId));
1055
1188
  },
1189
+ async getCurrentMember (guildId, token) {
1190
+ return await rest.get(rest.routes.guilds.members.currentMember(guildId), {
1191
+ headers: {
1192
+ authorization: `Bearer ${token}`
1193
+ },
1194
+ unauthorized: true
1195
+ });
1196
+ },
1056
1197
  async getMembers (guildId, options) {
1057
1198
  return await rest.get(rest.routes.guilds.members.members(guildId, options));
1058
1199
  },
@@ -1088,15 +1229,62 @@ export function createRestManager(options) {
1088
1229
  async triggerTypingIndicator (channelId) {
1089
1230
  await rest.post(rest.routes.channels.typing(channelId));
1090
1231
  },
1091
- async upsertGlobalApplicationCommands (body) {
1092
- return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), {
1232
+ async upsertGlobalApplicationCommands (body, options) {
1233
+ const restOptions = {
1093
1234
  body
1235
+ };
1236
+ if (options?.bearerToken) {
1237
+ restOptions.unauthorized = true;
1238
+ restOptions.headers = {
1239
+ authorization: `Bearer ${options.bearerToken}`
1240
+ };
1241
+ }
1242
+ return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), restOptions);
1243
+ },
1244
+ async upsertGuildApplicationCommands (guildId, body, options) {
1245
+ const restOptions = {
1246
+ body
1247
+ };
1248
+ if (options?.bearerToken) {
1249
+ restOptions.unauthorized = true;
1250
+ restOptions.headers = {
1251
+ authorization: `Bearer ${options.bearerToken}`
1252
+ };
1253
+ }
1254
+ return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions);
1255
+ },
1256
+ async editUserApplicationRoleConnection (token, applicationId, body) {
1257
+ return await rest.put(rest.routes.oauth2.roleConnections(applicationId), {
1258
+ body,
1259
+ headers: {
1260
+ authorization: `Bearer ${token}`
1261
+ },
1262
+ unauthorized: true
1094
1263
  });
1095
1264
  },
1096
- async upsertGuildApplicationCommands (guildId, body) {
1097
- return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), {
1265
+ async addGuildMember (guildId, userId, body) {
1266
+ return await rest.put(rest.routes.guilds.members.member(guildId, userId), {
1098
1267
  body
1099
1268
  });
1269
+ },
1270
+ preferSnakeCase (enabled) {
1271
+ const camelizer = enabled ? (x)=>x : camelize;
1272
+ rest.get = async (url, options)=>{
1273
+ return camelizer(await rest.makeRequest('GET', url, options));
1274
+ };
1275
+ rest.post = async (url, options)=>{
1276
+ return camelizer(await rest.makeRequest('POST', url, options));
1277
+ };
1278
+ rest.delete = async (url, options)=>{
1279
+ camelizer(await rest.makeRequest('DELETE', url, options));
1280
+ };
1281
+ rest.patch = async (url, options)=>{
1282
+ return camelizer(await rest.makeRequest('PATCH', url, options));
1283
+ };
1284
+ rest.put = async (url, options)=>{
1285
+ return camelizer(await rest.makeRequest('PUT', url, options));
1286
+ };
1287
+ return rest;
1100
1288
  }
1101
1289
  };
1102
1290
  return rest;