@discordjs/rest 1.6.0-dev.1677499520-ffdb197.0 → 1.6.0
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/CHANGELOG.md +21 -0
- package/dist/index.js +516 -107
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +512 -107
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
package/dist/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { URL } from "node:url";
|
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import { APIVersion } from "discord-api-types/v10";
|
|
10
10
|
import { Agent } from "undici";
|
|
11
|
-
var DefaultUserAgent = `DiscordBot (https://discord.js.org,
|
|
11
|
+
var DefaultUserAgent = `DiscordBot (https://discord.js.org, [VI]{{inject}}[/VI])`;
|
|
12
12
|
var DefaultRestOptions = {
|
|
13
13
|
get agent() {
|
|
14
14
|
return new Agent({
|
|
@@ -33,19 +33,40 @@ var DefaultRestOptions = {
|
|
|
33
33
|
hashLifetime: 864e5,
|
|
34
34
|
handlerSweepInterval: 36e5
|
|
35
35
|
};
|
|
36
|
-
var RESTEvents
|
|
36
|
+
var RESTEvents;
|
|
37
|
+
(function(RESTEvents2) {
|
|
37
38
|
RESTEvents2["Debug"] = "restDebug";
|
|
38
39
|
RESTEvents2["HandlerSweep"] = "handlerSweep";
|
|
39
40
|
RESTEvents2["HashSweep"] = "hashSweep";
|
|
40
41
|
RESTEvents2["InvalidRequestWarning"] = "invalidRequestWarning";
|
|
41
42
|
RESTEvents2["RateLimited"] = "rateLimited";
|
|
42
43
|
RESTEvents2["Response"] = "response";
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
})(RESTEvents || (RESTEvents = {}));
|
|
45
|
+
var ALLOWED_EXTENSIONS = [
|
|
46
|
+
"webp",
|
|
47
|
+
"png",
|
|
48
|
+
"jpg",
|
|
49
|
+
"jpeg",
|
|
50
|
+
"gif"
|
|
51
|
+
];
|
|
52
|
+
var ALLOWED_STICKER_EXTENSIONS = [
|
|
53
|
+
"png",
|
|
54
|
+
"json",
|
|
55
|
+
"gif"
|
|
56
|
+
];
|
|
57
|
+
var ALLOWED_SIZES = [
|
|
58
|
+
16,
|
|
59
|
+
32,
|
|
60
|
+
64,
|
|
61
|
+
128,
|
|
62
|
+
256,
|
|
63
|
+
512,
|
|
64
|
+
1024,
|
|
65
|
+
2048,
|
|
66
|
+
4096
|
|
67
|
+
];
|
|
48
68
|
var OverwrittenMimeTypes = {
|
|
69
|
+
// https://github.com/discordjs/discord.js/issues/8557
|
|
49
70
|
"image/apng": "image/png"
|
|
50
71
|
};
|
|
51
72
|
|
|
@@ -54,60 +75,201 @@ var CDN = class {
|
|
|
54
75
|
constructor(base = DefaultRestOptions.cdn) {
|
|
55
76
|
this.base = base;
|
|
56
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Generates an app asset URL for a client's asset.
|
|
80
|
+
*
|
|
81
|
+
* @param clientId - The client id that has the asset
|
|
82
|
+
* @param assetHash - The hash provided by Discord for this asset
|
|
83
|
+
* @param options - Optional options for the asset
|
|
84
|
+
*/
|
|
57
85
|
appAsset(clientId, assetHash, options) {
|
|
58
86
|
return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);
|
|
59
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Generates an app icon URL for a client's icon.
|
|
90
|
+
*
|
|
91
|
+
* @param clientId - The client id that has the icon
|
|
92
|
+
* @param iconHash - The hash provided by Discord for this icon
|
|
93
|
+
* @param options - Optional options for the icon
|
|
94
|
+
*/
|
|
60
95
|
appIcon(clientId, iconHash, options) {
|
|
61
96
|
return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);
|
|
62
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Generates an avatar URL, e.g. for a user or a webhook.
|
|
100
|
+
*
|
|
101
|
+
* @param id - The id that has the icon
|
|
102
|
+
* @param avatarHash - The hash provided by Discord for this avatar
|
|
103
|
+
* @param options - Optional options for the avatar
|
|
104
|
+
*/
|
|
63
105
|
avatar(id, avatarHash, options) {
|
|
64
106
|
return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);
|
|
65
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Generates a banner URL, e.g. for a user or a guild.
|
|
110
|
+
*
|
|
111
|
+
* @param id - The id that has the banner splash
|
|
112
|
+
* @param bannerHash - The hash provided by Discord for this banner
|
|
113
|
+
* @param options - Optional options for the banner
|
|
114
|
+
*/
|
|
66
115
|
banner(id, bannerHash, options) {
|
|
67
116
|
return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);
|
|
68
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Generates an icon URL for a channel, e.g. a group DM.
|
|
120
|
+
*
|
|
121
|
+
* @param channelId - The channel id that has the icon
|
|
122
|
+
* @param iconHash - The hash provided by Discord for this channel
|
|
123
|
+
* @param options - Optional options for the icon
|
|
124
|
+
*/
|
|
69
125
|
channelIcon(channelId, iconHash, options) {
|
|
70
126
|
return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);
|
|
71
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Generates the default avatar URL for a discriminator.
|
|
130
|
+
*
|
|
131
|
+
* @param discriminator - The discriminator modulo 5
|
|
132
|
+
*/
|
|
72
133
|
defaultAvatar(discriminator) {
|
|
73
|
-
return this.makeURL(`/embed/avatars/${discriminator}`, {
|
|
134
|
+
return this.makeURL(`/embed/avatars/${discriminator}`, {
|
|
135
|
+
extension: "png"
|
|
136
|
+
});
|
|
74
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Generates a discovery splash URL for a guild's discovery splash.
|
|
140
|
+
*
|
|
141
|
+
* @param guildId - The guild id that has the discovery splash
|
|
142
|
+
* @param splashHash - The hash provided by Discord for this splash
|
|
143
|
+
* @param options - Optional options for the splash
|
|
144
|
+
*/
|
|
75
145
|
discoverySplash(guildId, splashHash, options) {
|
|
76
146
|
return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);
|
|
77
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Generates an emoji's URL for an emoji.
|
|
150
|
+
*
|
|
151
|
+
* @param emojiId - The emoji id
|
|
152
|
+
* @param extension - The extension of the emoji
|
|
153
|
+
*/
|
|
78
154
|
emoji(emojiId, extension) {
|
|
79
|
-
return this.makeURL(`/emojis/${emojiId}`, {
|
|
155
|
+
return this.makeURL(`/emojis/${emojiId}`, {
|
|
156
|
+
extension
|
|
157
|
+
});
|
|
80
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Generates a guild member avatar URL.
|
|
161
|
+
*
|
|
162
|
+
* @param guildId - The id of the guild
|
|
163
|
+
* @param userId - The id of the user
|
|
164
|
+
* @param avatarHash - The hash provided by Discord for this avatar
|
|
165
|
+
* @param options - Optional options for the avatar
|
|
166
|
+
*/
|
|
81
167
|
guildMemberAvatar(guildId, userId, avatarHash, options) {
|
|
82
168
|
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);
|
|
83
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Generates a guild member banner URL.
|
|
172
|
+
*
|
|
173
|
+
* @param guildId - The id of the guild
|
|
174
|
+
* @param userId - The id of the user
|
|
175
|
+
* @param bannerHash - The hash provided by Discord for this banner
|
|
176
|
+
* @param options - Optional options for the banner
|
|
177
|
+
*/
|
|
84
178
|
guildMemberBanner(guildId, userId, bannerHash, options) {
|
|
85
179
|
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banner`, bannerHash, options);
|
|
86
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Generates an icon URL, e.g. for a guild.
|
|
183
|
+
*
|
|
184
|
+
* @param id - The id that has the icon splash
|
|
185
|
+
* @param iconHash - The hash provided by Discord for this icon
|
|
186
|
+
* @param options - Optional options for the icon
|
|
187
|
+
*/
|
|
87
188
|
icon(id, iconHash, options) {
|
|
88
189
|
return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);
|
|
89
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Generates a URL for the icon of a role
|
|
193
|
+
*
|
|
194
|
+
* @param roleId - The id of the role that has the icon
|
|
195
|
+
* @param roleIconHash - The hash provided by Discord for this role icon
|
|
196
|
+
* @param options - Optional options for the role icon
|
|
197
|
+
*/
|
|
90
198
|
roleIcon(roleId, roleIconHash, options) {
|
|
91
199
|
return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);
|
|
92
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Generates a guild invite splash URL for a guild's invite splash.
|
|
203
|
+
*
|
|
204
|
+
* @param guildId - The guild id that has the invite splash
|
|
205
|
+
* @param splashHash - The hash provided by Discord for this splash
|
|
206
|
+
* @param options - Optional options for the splash
|
|
207
|
+
*/
|
|
93
208
|
splash(guildId, splashHash, options) {
|
|
94
209
|
return this.makeURL(`/splashes/${guildId}/${splashHash}`, options);
|
|
95
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Generates a sticker URL.
|
|
213
|
+
*
|
|
214
|
+
* @param stickerId - The sticker id
|
|
215
|
+
* @param extension - The extension of the sticker
|
|
216
|
+
* @privateRemarks
|
|
217
|
+
* Stickers cannot have a `.webp` extension, so we default to a `.png`
|
|
218
|
+
*/
|
|
96
219
|
sticker(stickerId, extension = "png") {
|
|
97
|
-
return this.makeURL(`/stickers/${stickerId}`, {
|
|
220
|
+
return this.makeURL(`/stickers/${stickerId}`, {
|
|
221
|
+
allowedExtensions: ALLOWED_STICKER_EXTENSIONS,
|
|
222
|
+
extension
|
|
223
|
+
});
|
|
98
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Generates a sticker pack banner URL.
|
|
227
|
+
*
|
|
228
|
+
* @param bannerId - The banner id
|
|
229
|
+
* @param options - Optional options for the banner
|
|
230
|
+
*/
|
|
99
231
|
stickerPackBanner(bannerId, options) {
|
|
100
232
|
return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);
|
|
101
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Generates a team icon URL for a team's icon.
|
|
236
|
+
*
|
|
237
|
+
* @param teamId - The team id that has the icon
|
|
238
|
+
* @param iconHash - The hash provided by Discord for this icon
|
|
239
|
+
* @param options - Optional options for the icon
|
|
240
|
+
*/
|
|
102
241
|
teamIcon(teamId, iconHash, options) {
|
|
103
242
|
return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);
|
|
104
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Generates a cover image for a guild scheduled event.
|
|
246
|
+
*
|
|
247
|
+
* @param scheduledEventId - The scheduled event id
|
|
248
|
+
* @param coverHash - The hash provided by discord for this cover image
|
|
249
|
+
* @param options - Optional options for the cover image
|
|
250
|
+
*/
|
|
105
251
|
guildScheduledEventCover(scheduledEventId, coverHash, options) {
|
|
106
252
|
return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);
|
|
107
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.
|
|
256
|
+
*
|
|
257
|
+
* @param route - The base cdn route
|
|
258
|
+
* @param hash - The hash provided by Discord for this icon
|
|
259
|
+
* @param options - Optional options for the link
|
|
260
|
+
*/
|
|
108
261
|
dynamicMakeURL(route, hash, { forceStatic = false, ...options } = {}) {
|
|
109
|
-
return this.makeURL(route, !forceStatic && hash.startsWith("a_") ? {
|
|
110
|
-
|
|
262
|
+
return this.makeURL(route, !forceStatic && hash.startsWith("a_") ? {
|
|
263
|
+
...options,
|
|
264
|
+
extension: "gif"
|
|
265
|
+
} : options);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Constructs the URL for the resource
|
|
269
|
+
*
|
|
270
|
+
* @param route - The base cdn route
|
|
271
|
+
* @param options - The extension/size options for the link
|
|
272
|
+
*/
|
|
111
273
|
makeURL(route, { allowedExtensions = ALLOWED_EXTENSIONS, extension = "webp", size } = {}) {
|
|
112
274
|
extension = String(extension).toLowerCase();
|
|
113
275
|
if (!allowedExtensions.includes(extension)) {
|
|
@@ -137,6 +299,14 @@ function isErrorResponse(error) {
|
|
|
137
299
|
}
|
|
138
300
|
__name(isErrorResponse, "isErrorResponse");
|
|
139
301
|
var DiscordAPIError = class extends Error {
|
|
302
|
+
/**
|
|
303
|
+
* @param rawError - The error reported by Discord
|
|
304
|
+
* @param code - The error code reported by Discord
|
|
305
|
+
* @param status - The status code of the response
|
|
306
|
+
* @param method - The method of the request that erred
|
|
307
|
+
* @param url - The url of the request that erred
|
|
308
|
+
* @param bodyData - The unparsed data for the request that errored
|
|
309
|
+
*/
|
|
140
310
|
constructor(rawError, code, status, method, url, bodyData) {
|
|
141
311
|
super(DiscordAPIError.getMessage(rawError));
|
|
142
312
|
this.rawError = rawError;
|
|
@@ -144,9 +314,14 @@ var DiscordAPIError = class extends Error {
|
|
|
144
314
|
this.status = status;
|
|
145
315
|
this.method = method;
|
|
146
316
|
this.url = url;
|
|
147
|
-
this.requestBody = {
|
|
317
|
+
this.requestBody = {
|
|
318
|
+
files: bodyData.files,
|
|
319
|
+
json: bodyData.body
|
|
320
|
+
};
|
|
148
321
|
}
|
|
149
|
-
|
|
322
|
+
/**
|
|
323
|
+
* The name of the error
|
|
324
|
+
*/
|
|
150
325
|
get name() {
|
|
151
326
|
return `${DiscordAPIError.name}[${this.code}]`;
|
|
152
327
|
}
|
|
@@ -154,7 +329,9 @@ var DiscordAPIError = class extends Error {
|
|
|
154
329
|
let flattened = "";
|
|
155
330
|
if ("code" in error) {
|
|
156
331
|
if (error.errors) {
|
|
157
|
-
flattened = [
|
|
332
|
+
flattened = [
|
|
333
|
+
...this.flattenDiscordError(error.errors)
|
|
334
|
+
].join("\n");
|
|
158
335
|
}
|
|
159
336
|
return error.message && flattened ? `${error.message}
|
|
160
337
|
${flattened}` : error.message || flattened || "Unknown Error";
|
|
@@ -184,28 +361,28 @@ __name(DiscordAPIError, "DiscordAPIError");
|
|
|
184
361
|
// src/lib/errors/HTTPError.ts
|
|
185
362
|
import { STATUS_CODES } from "node:http";
|
|
186
363
|
var HTTPError = class extends Error {
|
|
364
|
+
/**
|
|
365
|
+
* @param status - The status code of the response
|
|
366
|
+
* @param method - The method of the request that erred
|
|
367
|
+
* @param url - The url of the request that erred
|
|
368
|
+
* @param bodyData - The unparsed data for the request that errored
|
|
369
|
+
*/
|
|
187
370
|
constructor(status, method, url, bodyData) {
|
|
188
371
|
super(STATUS_CODES[status]);
|
|
189
372
|
this.status = status;
|
|
190
373
|
this.method = method;
|
|
191
374
|
this.url = url;
|
|
192
|
-
this.
|
|
375
|
+
this.name = HTTPError.name;
|
|
376
|
+
this.requestBody = {
|
|
377
|
+
files: bodyData.files,
|
|
378
|
+
json: bodyData.body
|
|
379
|
+
};
|
|
193
380
|
}
|
|
194
|
-
requestBody;
|
|
195
|
-
name = HTTPError.name;
|
|
196
381
|
};
|
|
197
382
|
__name(HTTPError, "HTTPError");
|
|
198
383
|
|
|
199
384
|
// src/lib/errors/RateLimitError.ts
|
|
200
385
|
var RateLimitError = class extends Error {
|
|
201
|
-
timeToReset;
|
|
202
|
-
limit;
|
|
203
|
-
method;
|
|
204
|
-
hash;
|
|
205
|
-
url;
|
|
206
|
-
route;
|
|
207
|
-
majorParameter;
|
|
208
|
-
global;
|
|
209
386
|
constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }) {
|
|
210
387
|
super();
|
|
211
388
|
this.timeToReset = timeToReset;
|
|
@@ -217,6 +394,9 @@ var RateLimitError = class extends Error {
|
|
|
217
394
|
this.majorParameter = majorParameter;
|
|
218
395
|
this.global = global;
|
|
219
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* The name of the error
|
|
399
|
+
*/
|
|
220
400
|
get name() {
|
|
221
401
|
return `${RateLimitError.name}[${this.route}]`;
|
|
222
402
|
}
|
|
@@ -296,10 +476,13 @@ function hasSublimit(bucketRoute, body, method) {
|
|
|
296
476
|
if (bucketRoute === "/channels/:id") {
|
|
297
477
|
if (typeof body !== "object" || body === null)
|
|
298
478
|
return false;
|
|
299
|
-
if (method !==
|
|
479
|
+
if (method !== RequestMethod.Patch)
|
|
300
480
|
return false;
|
|
301
481
|
const castedBody = body;
|
|
302
|
-
return [
|
|
482
|
+
return [
|
|
483
|
+
"name",
|
|
484
|
+
"topic"
|
|
485
|
+
].some((key) => Reflect.has(castedBody, key));
|
|
303
486
|
}
|
|
304
487
|
return true;
|
|
305
488
|
}
|
|
@@ -322,7 +505,9 @@ async function resolveBody(body) {
|
|
|
322
505
|
} else if (body instanceof FormData) {
|
|
323
506
|
return body;
|
|
324
507
|
} else if (body[Symbol.iterator]) {
|
|
325
|
-
const chunks = [
|
|
508
|
+
const chunks = [
|
|
509
|
+
...body
|
|
510
|
+
];
|
|
326
511
|
const length = chunks.reduce((a, b) => a + b.length, 0);
|
|
327
512
|
const uint8 = new Uint8Array(length);
|
|
328
513
|
let lengthUsed = 0;
|
|
@@ -351,43 +536,96 @@ __name(shouldRetry, "shouldRetry");
|
|
|
351
536
|
// src/lib/handlers/SequentialHandler.ts
|
|
352
537
|
var invalidCount = 0;
|
|
353
538
|
var invalidCountResetTime = null;
|
|
539
|
+
var QueueType;
|
|
540
|
+
(function(QueueType2) {
|
|
541
|
+
QueueType2[QueueType2["Standard"] = 0] = "Standard";
|
|
542
|
+
QueueType2[QueueType2["Sublimit"] = 1] = "Sublimit";
|
|
543
|
+
})(QueueType || (QueueType = {}));
|
|
354
544
|
var SequentialHandler = class {
|
|
545
|
+
/**
|
|
546
|
+
* The interface used to sequence async requests sequentially
|
|
547
|
+
*/
|
|
548
|
+
#asyncQueue;
|
|
549
|
+
/**
|
|
550
|
+
* The interface used to sequence sublimited async requests sequentially
|
|
551
|
+
*/
|
|
552
|
+
#sublimitedQueue;
|
|
553
|
+
/**
|
|
554
|
+
* A promise wrapper for when the sublimited queue is finished being processed or null when not being processed
|
|
555
|
+
*/
|
|
556
|
+
#sublimitPromise;
|
|
557
|
+
/**
|
|
558
|
+
* Whether the sublimit queue needs to be shifted in the finally block
|
|
559
|
+
*/
|
|
560
|
+
#shiftSublimit;
|
|
561
|
+
/**
|
|
562
|
+
* @param manager - The request manager
|
|
563
|
+
* @param hash - The hash that this RequestHandler handles
|
|
564
|
+
* @param majorParameter - The major parameter for this handler
|
|
565
|
+
*/
|
|
355
566
|
constructor(manager, hash, majorParameter) {
|
|
356
567
|
this.manager = manager;
|
|
357
568
|
this.hash = hash;
|
|
358
569
|
this.majorParameter = majorParameter;
|
|
570
|
+
this.reset = -1;
|
|
571
|
+
this.remaining = 1;
|
|
572
|
+
this.limit = Number.POSITIVE_INFINITY;
|
|
573
|
+
this.#asyncQueue = new AsyncQueue();
|
|
574
|
+
this.#sublimitedQueue = null;
|
|
575
|
+
this.#sublimitPromise = null;
|
|
576
|
+
this.#shiftSublimit = false;
|
|
359
577
|
this.id = `${hash}:${majorParameter}`;
|
|
360
578
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
limit = Number.POSITIVE_INFINITY;
|
|
365
|
-
#asyncQueue = new AsyncQueue();
|
|
366
|
-
#sublimitedQueue = null;
|
|
367
|
-
#sublimitPromise = null;
|
|
368
|
-
#shiftSublimit = false;
|
|
579
|
+
/**
|
|
580
|
+
* {@inheritDoc IHandler.inactive}
|
|
581
|
+
*/
|
|
369
582
|
get inactive() {
|
|
370
583
|
return this.#asyncQueue.remaining === 0 && (this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) && !this.limited;
|
|
371
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* If the rate limit bucket is currently limited by the global limit
|
|
587
|
+
*/
|
|
372
588
|
get globalLimited() {
|
|
373
589
|
return this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;
|
|
374
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* If the rate limit bucket is currently limited by its limit
|
|
593
|
+
*/
|
|
375
594
|
get localLimited() {
|
|
376
595
|
return this.remaining <= 0 && Date.now() < this.reset;
|
|
377
596
|
}
|
|
597
|
+
/**
|
|
598
|
+
* If the rate limit bucket is currently limited
|
|
599
|
+
*/
|
|
378
600
|
get limited() {
|
|
379
601
|
return this.globalLimited || this.localLimited;
|
|
380
602
|
}
|
|
603
|
+
/**
|
|
604
|
+
* The time until queued requests can continue
|
|
605
|
+
*/
|
|
381
606
|
get timeToReset() {
|
|
382
607
|
return this.reset + this.manager.options.offset - Date.now();
|
|
383
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* Emits a debug message
|
|
611
|
+
*
|
|
612
|
+
* @param message - The message to debug
|
|
613
|
+
*/
|
|
384
614
|
debug(message) {
|
|
385
|
-
this.manager.emit(
|
|
615
|
+
this.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);
|
|
386
616
|
}
|
|
617
|
+
/**
|
|
618
|
+
* Delay all requests for the specified amount of time, handling global rate limits
|
|
619
|
+
*
|
|
620
|
+
* @param time - The amount of time to delay all requests for
|
|
621
|
+
*/
|
|
387
622
|
async globalDelayFor(time) {
|
|
388
623
|
await sleep(time);
|
|
389
624
|
this.manager.globalDelay = null;
|
|
390
625
|
}
|
|
626
|
+
/*
|
|
627
|
+
* Determines whether the request should be queued or whether a RateLimitError should be thrown
|
|
628
|
+
*/
|
|
391
629
|
async onRateLimit(rateLimitData) {
|
|
392
630
|
const { options } = this.manager;
|
|
393
631
|
if (!options.rejectOnRateLimit)
|
|
@@ -397,15 +635,20 @@ var SequentialHandler = class {
|
|
|
397
635
|
throw new RateLimitError(rateLimitData);
|
|
398
636
|
}
|
|
399
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* {@inheritDoc IHandler.queueRequest}
|
|
640
|
+
*/
|
|
400
641
|
async queueRequest(routeId, url, options, requestData) {
|
|
401
642
|
let queue = this.#asyncQueue;
|
|
402
|
-
let queueType = 0
|
|
643
|
+
let queueType = 0;
|
|
403
644
|
if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {
|
|
404
645
|
queue = this.#sublimitedQueue;
|
|
405
|
-
queueType = 1
|
|
646
|
+
queueType = 1;
|
|
406
647
|
}
|
|
407
|
-
await queue.wait({
|
|
408
|
-
|
|
648
|
+
await queue.wait({
|
|
649
|
+
signal: requestData.signal
|
|
650
|
+
});
|
|
651
|
+
if (queueType === 0) {
|
|
409
652
|
if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {
|
|
410
653
|
queue = this.#sublimitedQueue;
|
|
411
654
|
const wait = queue.wait();
|
|
@@ -429,6 +672,15 @@ var SequentialHandler = class {
|
|
|
429
672
|
}
|
|
430
673
|
}
|
|
431
674
|
}
|
|
675
|
+
/**
|
|
676
|
+
* The method that actually makes the request to the api, and updates info about the bucket accordingly
|
|
677
|
+
*
|
|
678
|
+
* @param routeId - The generalized api route with literal ids for major parameters
|
|
679
|
+
* @param url - The fully resolved url to make the request to
|
|
680
|
+
* @param options - The fetch options needed to make the request
|
|
681
|
+
* @param requestData - Extra data from the user's request needed for errors and additional processing
|
|
682
|
+
* @param retries - The number of retries this request has already attempted (recursion)
|
|
683
|
+
*/
|
|
432
684
|
async runRequest(routeId, url, options, requestData, retries = 0) {
|
|
433
685
|
while (this.limited) {
|
|
434
686
|
const isGlobal = this.globalLimited;
|
|
@@ -457,7 +709,7 @@ var SequentialHandler = class {
|
|
|
457
709
|
majorParameter: this.majorParameter,
|
|
458
710
|
global: isGlobal
|
|
459
711
|
};
|
|
460
|
-
this.manager.emit(
|
|
712
|
+
this.manager.emit(RESTEvents.RateLimited, rateLimitData);
|
|
461
713
|
await this.onRateLimit(rateLimitData);
|
|
462
714
|
if (isGlobal) {
|
|
463
715
|
this.debug(`Global rate limit hit, blocking all requests for ${timeout2}ms`);
|
|
@@ -483,7 +735,10 @@ var SequentialHandler = class {
|
|
|
483
735
|
}
|
|
484
736
|
let res;
|
|
485
737
|
try {
|
|
486
|
-
res = await request(url, {
|
|
738
|
+
res = await request(url, {
|
|
739
|
+
...options,
|
|
740
|
+
signal: controller.signal
|
|
741
|
+
});
|
|
487
742
|
} catch (error) {
|
|
488
743
|
if (!(error instanceof Error))
|
|
489
744
|
throw error;
|
|
@@ -494,19 +749,17 @@ var SequentialHandler = class {
|
|
|
494
749
|
} finally {
|
|
495
750
|
clearTimeout(timeout);
|
|
496
751
|
}
|
|
497
|
-
if (this.manager.listenerCount(
|
|
498
|
-
this.manager.emit(
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
{ ...res }
|
|
509
|
-
);
|
|
752
|
+
if (this.manager.listenerCount(RESTEvents.Response)) {
|
|
753
|
+
this.manager.emit(RESTEvents.Response, {
|
|
754
|
+
method,
|
|
755
|
+
path: routeId.original,
|
|
756
|
+
route: routeId.bucketRoute,
|
|
757
|
+
options,
|
|
758
|
+
data: requestData,
|
|
759
|
+
retries
|
|
760
|
+
}, {
|
|
761
|
+
...res
|
|
762
|
+
});
|
|
510
763
|
}
|
|
511
764
|
const status = res.statusCode;
|
|
512
765
|
let retryAfter = 0;
|
|
@@ -521,8 +774,15 @@ var SequentialHandler = class {
|
|
|
521
774
|
if (retry)
|
|
522
775
|
retryAfter = Number(retry) * 1e3 + this.manager.options.offset;
|
|
523
776
|
if (hash && hash !== this.hash) {
|
|
524
|
-
this.debug([
|
|
525
|
-
|
|
777
|
+
this.debug([
|
|
778
|
+
"Received bucket hash update",
|
|
779
|
+
` Old Hash : ${this.hash}`,
|
|
780
|
+
` New Hash : ${hash}`
|
|
781
|
+
].join("\n"));
|
|
782
|
+
this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, {
|
|
783
|
+
value: hash,
|
|
784
|
+
lastAccess: Date.now()
|
|
785
|
+
});
|
|
526
786
|
} else if (hash) {
|
|
527
787
|
const hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);
|
|
528
788
|
if (hashData) {
|
|
@@ -546,7 +806,7 @@ var SequentialHandler = class {
|
|
|
546
806
|
invalidCount++;
|
|
547
807
|
const emitInvalid = this.manager.options.invalidRequestWarningInterval > 0 && invalidCount % this.manager.options.invalidRequestWarningInterval === 0;
|
|
548
808
|
if (emitInvalid) {
|
|
549
|
-
this.manager.emit(
|
|
809
|
+
this.manager.emit(RESTEvents.InvalidRequestWarning, {
|
|
550
810
|
count: invalidCount,
|
|
551
811
|
remainingTime: invalidCountResetTime - Date.now()
|
|
552
812
|
});
|
|
@@ -575,20 +835,18 @@ var SequentialHandler = class {
|
|
|
575
835
|
majorParameter: this.majorParameter,
|
|
576
836
|
global: isGlobal
|
|
577
837
|
});
|
|
578
|
-
this.debug(
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
].join("\n")
|
|
591
|
-
);
|
|
838
|
+
this.debug([
|
|
839
|
+
"Encountered unexpected 429 rate limit",
|
|
840
|
+
` Global : ${isGlobal.toString()}`,
|
|
841
|
+
` Method : ${method}`,
|
|
842
|
+
` URL : ${url}`,
|
|
843
|
+
` Bucket : ${routeId.bucketRoute}`,
|
|
844
|
+
` Major parameter: ${routeId.majorParameter}`,
|
|
845
|
+
` Hash : ${this.hash}`,
|
|
846
|
+
` Limit : ${limit2}`,
|
|
847
|
+
` Retry After : ${retryAfter}ms`,
|
|
848
|
+
` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : "None"}`
|
|
849
|
+
].join("\n"));
|
|
592
850
|
if (sublimitTimeout) {
|
|
593
851
|
const firstSublimit = !this.#sublimitedQueue;
|
|
594
852
|
if (firstSublimit) {
|
|
@@ -601,7 +859,10 @@ var SequentialHandler = class {
|
|
|
601
859
|
await sleep(sublimitTimeout);
|
|
602
860
|
let resolve;
|
|
603
861
|
const promise = new Promise((res2) => resolve = res2);
|
|
604
|
-
this.#sublimitPromise = {
|
|
862
|
+
this.#sublimitPromise = {
|
|
863
|
+
promise,
|
|
864
|
+
resolve
|
|
865
|
+
};
|
|
605
866
|
if (firstSublimit) {
|
|
606
867
|
await this.#asyncQueue.wait();
|
|
607
868
|
this.#shiftSublimit = true;
|
|
@@ -629,28 +890,43 @@ __name(SequentialHandler, "SequentialHandler");
|
|
|
629
890
|
|
|
630
891
|
// src/lib/RequestManager.ts
|
|
631
892
|
var getFileType = lazy(async () => import("file-type"));
|
|
632
|
-
var RequestMethod
|
|
893
|
+
var RequestMethod;
|
|
894
|
+
(function(RequestMethod2) {
|
|
633
895
|
RequestMethod2["Delete"] = "DELETE";
|
|
634
896
|
RequestMethod2["Get"] = "GET";
|
|
635
897
|
RequestMethod2["Patch"] = "PATCH";
|
|
636
898
|
RequestMethod2["Post"] = "POST";
|
|
637
899
|
RequestMethod2["Put"] = "PUT";
|
|
638
|
-
|
|
639
|
-
})(RequestMethod || {});
|
|
900
|
+
})(RequestMethod || (RequestMethod = {}));
|
|
640
901
|
var RequestManager = class extends EventEmitter {
|
|
902
|
+
/**
|
|
903
|
+
* The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} for all requests
|
|
904
|
+
* performed by this manager.
|
|
905
|
+
*/
|
|
641
906
|
agent = null;
|
|
642
|
-
|
|
907
|
+
/**
|
|
908
|
+
* The promise used to wait out the global rate limit
|
|
909
|
+
*/
|
|
643
910
|
globalDelay = null;
|
|
911
|
+
/**
|
|
912
|
+
* The timestamp at which the global bucket resets
|
|
913
|
+
*/
|
|
644
914
|
globalReset = -1;
|
|
915
|
+
/**
|
|
916
|
+
* API bucket hashes that are cached from provided routes
|
|
917
|
+
*/
|
|
645
918
|
hashes = new Collection();
|
|
919
|
+
/**
|
|
920
|
+
* Request handlers created from the bucket hash and the major parameters
|
|
921
|
+
*/
|
|
646
922
|
handlers = new Collection();
|
|
647
923
|
#token = null;
|
|
648
|
-
hashTimer;
|
|
649
|
-
handlerTimer;
|
|
650
|
-
options;
|
|
651
924
|
constructor(options) {
|
|
652
925
|
super();
|
|
653
|
-
this.options = {
|
|
926
|
+
this.options = {
|
|
927
|
+
...DefaultRestOptions,
|
|
928
|
+
...options
|
|
929
|
+
};
|
|
654
930
|
this.options.offset = Math.max(0, this.options.offset);
|
|
655
931
|
this.globalRemaining = this.options.globalRequestsPerSecond;
|
|
656
932
|
this.agent = options.agent ?? null;
|
|
@@ -674,10 +950,10 @@ var RequestManager = class extends EventEmitter {
|
|
|
674
950
|
if (shouldSweep) {
|
|
675
951
|
sweptHashes.set(key, val);
|
|
676
952
|
}
|
|
677
|
-
this.emit(
|
|
953
|
+
this.emit(RESTEvents.Debug, `Hash ${val.value} for ${key} swept due to lifetime being exceeded`);
|
|
678
954
|
return shouldSweep;
|
|
679
955
|
});
|
|
680
|
-
this.emit(
|
|
956
|
+
this.emit(RESTEvents.HashSweep, sweptHashes);
|
|
681
957
|
}, this.options.hashSweepInterval).unref();
|
|
682
958
|
}
|
|
683
959
|
if (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Number.POSITIVE_INFINITY) {
|
|
@@ -689,21 +965,37 @@ var RequestManager = class extends EventEmitter {
|
|
|
689
965
|
if (inactive) {
|
|
690
966
|
sweptHandlers.set(key, val);
|
|
691
967
|
}
|
|
692
|
-
this.emit(
|
|
968
|
+
this.emit(RESTEvents.Debug, `Handler ${val.id} for ${key} swept due to being inactive`);
|
|
693
969
|
return inactive;
|
|
694
970
|
});
|
|
695
|
-
this.emit(
|
|
971
|
+
this.emit(RESTEvents.HandlerSweep, sweptHandlers);
|
|
696
972
|
}, this.options.handlerSweepInterval).unref();
|
|
697
973
|
}
|
|
698
974
|
}
|
|
975
|
+
/**
|
|
976
|
+
* Sets the default agent to use for requests performed by this manager
|
|
977
|
+
*
|
|
978
|
+
* @param agent - The agent to use
|
|
979
|
+
*/
|
|
699
980
|
setAgent(agent) {
|
|
700
981
|
this.agent = agent;
|
|
701
982
|
return this;
|
|
702
983
|
}
|
|
984
|
+
/**
|
|
985
|
+
* Sets the authorization token that should be used for requests
|
|
986
|
+
*
|
|
987
|
+
* @param token - The authorization token to use
|
|
988
|
+
*/
|
|
703
989
|
setToken(token) {
|
|
704
990
|
this.#token = token;
|
|
705
991
|
return this;
|
|
706
992
|
}
|
|
993
|
+
/**
|
|
994
|
+
* Queues a request to be sent
|
|
995
|
+
*
|
|
996
|
+
* @param request - All the information needed to make a request
|
|
997
|
+
* @returns The response from the api request
|
|
998
|
+
*/
|
|
707
999
|
async queueRequest(request2) {
|
|
708
1000
|
const routeId = RequestManager.generateRouteData(request2.fullRoute, request2.method);
|
|
709
1001
|
const hash = this.hashes.get(`${request2.method}:${routeId.bucketRoute}`) ?? {
|
|
@@ -719,11 +1011,23 @@ var RequestManager = class extends EventEmitter {
|
|
|
719
1011
|
signal: request2.signal
|
|
720
1012
|
});
|
|
721
1013
|
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Creates a new rate limit handler from a hash, based on the hash and the major parameter
|
|
1016
|
+
*
|
|
1017
|
+
* @param hash - The hash for the route
|
|
1018
|
+
* @param majorParameter - The major parameter for this handler
|
|
1019
|
+
* @internal
|
|
1020
|
+
*/
|
|
722
1021
|
createHandler(hash, majorParameter) {
|
|
723
1022
|
const queue = new SequentialHandler(this, hash, majorParameter);
|
|
724
1023
|
this.handlers.set(queue.id, queue);
|
|
725
1024
|
return queue;
|
|
726
1025
|
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Formats the request data to a usable format for fetch
|
|
1028
|
+
*
|
|
1029
|
+
* @param request - The request data
|
|
1030
|
+
*/
|
|
727
1031
|
async resolveRequest(request2) {
|
|
728
1032
|
const { options } = this;
|
|
729
1033
|
let query = "";
|
|
@@ -762,9 +1066,17 @@ var RequestManager = class extends EventEmitter {
|
|
|
762
1066
|
contentType = OverwrittenMimeTypes[parsedType] ?? parsedType;
|
|
763
1067
|
}
|
|
764
1068
|
}
|
|
765
|
-
formData.append(fileKey, new Blob2([
|
|
1069
|
+
formData.append(fileKey, new Blob2([
|
|
1070
|
+
file.data
|
|
1071
|
+
], {
|
|
1072
|
+
type: contentType
|
|
1073
|
+
}), file.name);
|
|
766
1074
|
} else {
|
|
767
|
-
formData.append(fileKey, new Blob2([
|
|
1075
|
+
formData.append(fileKey, new Blob2([
|
|
1076
|
+
`${file.data}`
|
|
1077
|
+
], {
|
|
1078
|
+
type: file.contentType
|
|
1079
|
+
}), file.name);
|
|
768
1080
|
}
|
|
769
1081
|
}
|
|
770
1082
|
if (request2.body != null) {
|
|
@@ -782,33 +1094,55 @@ var RequestManager = class extends EventEmitter {
|
|
|
782
1094
|
finalBody = request2.body;
|
|
783
1095
|
} else {
|
|
784
1096
|
finalBody = JSON.stringify(request2.body);
|
|
785
|
-
additionalHeaders = {
|
|
1097
|
+
additionalHeaders = {
|
|
1098
|
+
"Content-Type": "application/json"
|
|
1099
|
+
};
|
|
786
1100
|
}
|
|
787
1101
|
}
|
|
788
1102
|
finalBody = await resolveBody(finalBody);
|
|
789
1103
|
const fetchOptions = {
|
|
790
|
-
headers: {
|
|
1104
|
+
headers: {
|
|
1105
|
+
...request2.headers,
|
|
1106
|
+
...additionalHeaders,
|
|
1107
|
+
...headers
|
|
1108
|
+
},
|
|
791
1109
|
method: request2.method.toUpperCase()
|
|
792
1110
|
};
|
|
793
1111
|
if (finalBody !== void 0) {
|
|
794
1112
|
fetchOptions.body = finalBody;
|
|
795
1113
|
}
|
|
796
1114
|
fetchOptions.dispatcher = request2.dispatcher ?? this.agent ?? void 0;
|
|
797
|
-
return {
|
|
1115
|
+
return {
|
|
1116
|
+
url,
|
|
1117
|
+
fetchOptions
|
|
1118
|
+
};
|
|
798
1119
|
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Stops the hash sweeping interval
|
|
1122
|
+
*/
|
|
799
1123
|
clearHashSweeper() {
|
|
800
1124
|
clearInterval(this.hashTimer);
|
|
801
1125
|
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Stops the request handler sweeping interval
|
|
1128
|
+
*/
|
|
802
1129
|
clearHandlerSweeper() {
|
|
803
1130
|
clearInterval(this.handlerTimer);
|
|
804
1131
|
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Generates route data for an endpoint:method
|
|
1134
|
+
*
|
|
1135
|
+
* @param endpoint - The raw endpoint to generalize
|
|
1136
|
+
* @param method - The HTTP method this endpoint is called without
|
|
1137
|
+
* @internal
|
|
1138
|
+
*/
|
|
805
1139
|
static generateRouteData(endpoint, method) {
|
|
806
|
-
const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{
|
|
1140
|
+
const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{17,19})/.exec(endpoint);
|
|
807
1141
|
const majorId = majorIdMatch?.[1] ?? "global";
|
|
808
|
-
const baseRoute = endpoint.replaceAll(/\d{
|
|
1142
|
+
const baseRoute = endpoint.replaceAll(/\d{17,19}/g, ":id").replace(/\/reactions\/(.*)/, "/reactions/:reaction");
|
|
809
1143
|
let exceptions = "";
|
|
810
|
-
if (method === "DELETE"
|
|
811
|
-
const id = /\d{
|
|
1144
|
+
if (method === "DELETE" && baseRoute === "/channels/:id/messages/:id") {
|
|
1145
|
+
const id = /\d{17,19}$/.exec(endpoint)[0];
|
|
812
1146
|
const timestamp = DiscordSnowflake.timestampFrom(id);
|
|
813
1147
|
if (Date.now() - timestamp > 1e3 * 60 * 60 * 24 * 14) {
|
|
814
1148
|
exceptions += "/Delete Old Message";
|
|
@@ -826,51 +1160,122 @@ __name(RequestManager, "RequestManager");
|
|
|
826
1160
|
// src/lib/REST.ts
|
|
827
1161
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
828
1162
|
var REST = class extends EventEmitter2 {
|
|
829
|
-
cdn;
|
|
830
|
-
requestManager;
|
|
831
1163
|
constructor(options = {}) {
|
|
832
1164
|
super();
|
|
833
1165
|
this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn);
|
|
834
|
-
this.requestManager = new RequestManager(options).on(
|
|
1166
|
+
this.requestManager = new RequestManager(options).on(RESTEvents.Debug, this.emit.bind(this, RESTEvents.Debug)).on(RESTEvents.RateLimited, this.emit.bind(this, RESTEvents.RateLimited)).on(RESTEvents.InvalidRequestWarning, this.emit.bind(this, RESTEvents.InvalidRequestWarning)).on(RESTEvents.HashSweep, this.emit.bind(this, RESTEvents.HashSweep));
|
|
835
1167
|
this.on("newListener", (name, listener) => {
|
|
836
|
-
if (name ===
|
|
1168
|
+
if (name === RESTEvents.Response)
|
|
837
1169
|
this.requestManager.on(name, listener);
|
|
838
1170
|
});
|
|
839
1171
|
this.on("removeListener", (name, listener) => {
|
|
840
|
-
if (name ===
|
|
1172
|
+
if (name === RESTEvents.Response)
|
|
841
1173
|
this.requestManager.off(name, listener);
|
|
842
1174
|
});
|
|
843
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Gets the agent set for this instance
|
|
1178
|
+
*/
|
|
844
1179
|
getAgent() {
|
|
845
1180
|
return this.requestManager.agent;
|
|
846
1181
|
}
|
|
1182
|
+
/**
|
|
1183
|
+
* Sets the default agent to use for requests performed by this instance
|
|
1184
|
+
*
|
|
1185
|
+
* @param agent - Sets the agent to use
|
|
1186
|
+
*/
|
|
847
1187
|
setAgent(agent) {
|
|
848
1188
|
this.requestManager.setAgent(agent);
|
|
849
1189
|
return this;
|
|
850
1190
|
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Sets the authorization token that should be used for requests
|
|
1193
|
+
*
|
|
1194
|
+
* @param token - The authorization token to use
|
|
1195
|
+
*/
|
|
851
1196
|
setToken(token) {
|
|
852
1197
|
this.requestManager.setToken(token);
|
|
853
1198
|
return this;
|
|
854
1199
|
}
|
|
1200
|
+
/**
|
|
1201
|
+
* Runs a get request from the api
|
|
1202
|
+
*
|
|
1203
|
+
* @param fullRoute - The full route to query
|
|
1204
|
+
* @param options - Optional request options
|
|
1205
|
+
*/
|
|
855
1206
|
async get(fullRoute, options = {}) {
|
|
856
|
-
return this.request({
|
|
1207
|
+
return this.request({
|
|
1208
|
+
...options,
|
|
1209
|
+
fullRoute,
|
|
1210
|
+
method: RequestMethod.Get
|
|
1211
|
+
});
|
|
857
1212
|
}
|
|
1213
|
+
/**
|
|
1214
|
+
* Runs a delete request from the api
|
|
1215
|
+
*
|
|
1216
|
+
* @param fullRoute - The full route to query
|
|
1217
|
+
* @param options - Optional request options
|
|
1218
|
+
*/
|
|
858
1219
|
async delete(fullRoute, options = {}) {
|
|
859
|
-
return this.request({
|
|
1220
|
+
return this.request({
|
|
1221
|
+
...options,
|
|
1222
|
+
fullRoute,
|
|
1223
|
+
method: RequestMethod.Delete
|
|
1224
|
+
});
|
|
860
1225
|
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Runs a post request from the api
|
|
1228
|
+
*
|
|
1229
|
+
* @param fullRoute - The full route to query
|
|
1230
|
+
* @param options - Optional request options
|
|
1231
|
+
*/
|
|
861
1232
|
async post(fullRoute, options = {}) {
|
|
862
|
-
return this.request({
|
|
1233
|
+
return this.request({
|
|
1234
|
+
...options,
|
|
1235
|
+
fullRoute,
|
|
1236
|
+
method: RequestMethod.Post
|
|
1237
|
+
});
|
|
863
1238
|
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Runs a put request from the api
|
|
1241
|
+
*
|
|
1242
|
+
* @param fullRoute - The full route to query
|
|
1243
|
+
* @param options - Optional request options
|
|
1244
|
+
*/
|
|
864
1245
|
async put(fullRoute, options = {}) {
|
|
865
|
-
return this.request({
|
|
1246
|
+
return this.request({
|
|
1247
|
+
...options,
|
|
1248
|
+
fullRoute,
|
|
1249
|
+
method: RequestMethod.Put
|
|
1250
|
+
});
|
|
866
1251
|
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Runs a patch request from the api
|
|
1254
|
+
*
|
|
1255
|
+
* @param fullRoute - The full route to query
|
|
1256
|
+
* @param options - Optional request options
|
|
1257
|
+
*/
|
|
867
1258
|
async patch(fullRoute, options = {}) {
|
|
868
|
-
return this.request({
|
|
1259
|
+
return this.request({
|
|
1260
|
+
...options,
|
|
1261
|
+
fullRoute,
|
|
1262
|
+
method: RequestMethod.Patch
|
|
1263
|
+
});
|
|
869
1264
|
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Runs a request from the api
|
|
1267
|
+
*
|
|
1268
|
+
* @param options - Request options
|
|
1269
|
+
*/
|
|
870
1270
|
async request(options) {
|
|
871
1271
|
const response = await this.raw(options);
|
|
872
1272
|
return parseResponse(response);
|
|
873
1273
|
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Runs a request from the API, yielding the raw Response object
|
|
1276
|
+
*
|
|
1277
|
+
* @param options - Request options
|
|
1278
|
+
*/
|
|
874
1279
|
async raw(options) {
|
|
875
1280
|
return this.requestManager.queueRequest(options);
|
|
876
1281
|
}
|
|
@@ -878,7 +1283,7 @@ var REST = class extends EventEmitter2 {
|
|
|
878
1283
|
__name(REST, "REST");
|
|
879
1284
|
|
|
880
1285
|
// src/index.ts
|
|
881
|
-
var version = "
|
|
1286
|
+
var version = "[VI]{{inject}}[/VI]";
|
|
882
1287
|
export {
|
|
883
1288
|
ALLOWED_EXTENSIONS,
|
|
884
1289
|
ALLOWED_SIZES,
|