@discordjs/rest 0.4.0-dev.1648166871.cedd053 → 0.4.0-dev.1649030897-5748dbe
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/index.js +927 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +881 -7
- package/dist/index.mjs.map +1 -1
- package/dist/lib/REST.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,882 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
6
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
7
|
+
};
|
|
8
|
+
var __publicField = (obj, key, value) => {
|
|
9
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
return value;
|
|
11
|
+
};
|
|
12
|
+
var __accessCheck = (obj, member, msg) => {
|
|
13
|
+
if (!member.has(obj))
|
|
14
|
+
throw TypeError("Cannot " + msg);
|
|
15
|
+
};
|
|
16
|
+
var __privateGet = (obj, member, getter) => {
|
|
17
|
+
__accessCheck(obj, member, "read from private field");
|
|
18
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
19
|
+
};
|
|
20
|
+
var __privateAdd = (obj, member, value) => {
|
|
21
|
+
if (member.has(obj))
|
|
22
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
23
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
24
|
+
};
|
|
25
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
26
|
+
__accessCheck(obj, member, "write to private field");
|
|
27
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// package.json
|
|
32
|
+
var require_package = __commonJS({
|
|
33
|
+
"package.json"(exports, module) {
|
|
34
|
+
module.exports = {
|
|
35
|
+
name: "@discordjs/rest",
|
|
36
|
+
version: "0.4.0-dev",
|
|
37
|
+
description: "The REST API for discord.js",
|
|
38
|
+
scripts: {
|
|
39
|
+
build: "tsup && tsc --emitDeclarationOnly --incremental",
|
|
40
|
+
test: "jest --pass-with-no-tests --collect-coverage",
|
|
41
|
+
lint: "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
|
|
42
|
+
format: "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
|
|
43
|
+
docs: "typedoc --json docs/typedoc-out.json src/index.ts && node scripts/docs.mjs",
|
|
44
|
+
prepublishOnly: "yarn build && yarn lint && yarn test",
|
|
45
|
+
changelog: "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/rest/*'"
|
|
46
|
+
},
|
|
47
|
+
main: "./dist/index.js",
|
|
48
|
+
module: "./dist/index.mjs",
|
|
49
|
+
typings: "./dist/index.d.ts",
|
|
50
|
+
exports: {
|
|
51
|
+
import: "./dist/index.mjs",
|
|
52
|
+
require: "./dist/index.js",
|
|
53
|
+
types: "./dist/index.d.ts"
|
|
54
|
+
},
|
|
55
|
+
directories: {
|
|
56
|
+
lib: "src",
|
|
57
|
+
test: "__tests__"
|
|
58
|
+
},
|
|
59
|
+
files: [
|
|
60
|
+
"dist"
|
|
61
|
+
],
|
|
62
|
+
contributors: [
|
|
63
|
+
"Crawl <icrawltogo@gmail.com>",
|
|
64
|
+
"Amish Shah <amishshah.2k@gmail.com>",
|
|
65
|
+
"SpaceEEC <spaceeec@yahoo.com>",
|
|
66
|
+
"Vlad Frangu <kingdgrizzle@gmail.com>",
|
|
67
|
+
"Antonio Roman <kyradiscord@gmail.com>"
|
|
68
|
+
],
|
|
69
|
+
license: "Apache-2.0",
|
|
70
|
+
keywords: [
|
|
71
|
+
"discord",
|
|
72
|
+
"api",
|
|
73
|
+
"rest",
|
|
74
|
+
"discordapp",
|
|
75
|
+
"discordjs"
|
|
76
|
+
],
|
|
77
|
+
repository: {
|
|
78
|
+
type: "git",
|
|
79
|
+
url: "git+https://github.com/discordjs/discord.js.git"
|
|
80
|
+
},
|
|
81
|
+
bugs: {
|
|
82
|
+
url: "https://github.com/discordjs/discord.js/issues"
|
|
83
|
+
},
|
|
84
|
+
homepage: "https://discord.js.org",
|
|
85
|
+
dependencies: {
|
|
86
|
+
"@discordjs/collection": "workspace:^",
|
|
87
|
+
"@sapphire/async-queue": "^1.2.0",
|
|
88
|
+
"@sapphire/snowflake": "^3.1.0",
|
|
89
|
+
"@types/node-fetch": "^2.5.12",
|
|
90
|
+
"discord-api-types": "^0.29.0",
|
|
91
|
+
"form-data": "^4.0.0",
|
|
92
|
+
"node-fetch": "^2.6.7",
|
|
93
|
+
tslib: "^2.3.1"
|
|
94
|
+
},
|
|
95
|
+
devDependencies: {
|
|
96
|
+
"@babel/core": "^7.17.2",
|
|
97
|
+
"@babel/plugin-proposal-decorators": "^7.17.2",
|
|
98
|
+
"@babel/preset-env": "^7.16.11",
|
|
99
|
+
"@babel/preset-typescript": "^7.16.7",
|
|
100
|
+
"@discordjs/ts-docgen": "^0.3.4",
|
|
101
|
+
"@types/jest": "^27.4.0",
|
|
102
|
+
"@typescript-eslint/eslint-plugin": "^5.11.0",
|
|
103
|
+
"@typescript-eslint/parser": "^5.11.0",
|
|
104
|
+
"babel-plugin-const-enum": "^1.2.0",
|
|
105
|
+
"babel-plugin-transform-typescript-metadata": "^0.3.2",
|
|
106
|
+
eslint: "^8.9.0",
|
|
107
|
+
"eslint-config-marine": "^9.3.2",
|
|
108
|
+
"eslint-config-prettier": "^8.3.0",
|
|
109
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
110
|
+
jest: "^27.5.1",
|
|
111
|
+
nock: "^13.2.4",
|
|
112
|
+
prettier: "^2.5.1",
|
|
113
|
+
tsup: "^5.11.13",
|
|
114
|
+
typedoc: "^0.22.11",
|
|
115
|
+
typescript: "^4.5.5"
|
|
116
|
+
},
|
|
117
|
+
engines: {
|
|
118
|
+
node: ">=16.9.0"
|
|
119
|
+
},
|
|
120
|
+
publishConfig: {
|
|
121
|
+
access: "public"
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// src/lib/utils/constants.ts
|
|
128
|
+
import { APIVersion } from "discord-api-types/v10";
|
|
129
|
+
var Package = require_package();
|
|
130
|
+
var DefaultUserAgent = `DiscordBot (${Package.homepage}, ${Package.version})`;
|
|
131
|
+
var DefaultRestOptions = {
|
|
132
|
+
agent: {},
|
|
133
|
+
api: "https://discord.com/api",
|
|
134
|
+
cdn: "https://cdn.discordapp.com",
|
|
135
|
+
headers: {},
|
|
136
|
+
invalidRequestWarningInterval: 0,
|
|
137
|
+
globalRequestsPerSecond: 50,
|
|
138
|
+
offset: 50,
|
|
139
|
+
rejectOnRateLimit: null,
|
|
140
|
+
retries: 3,
|
|
141
|
+
timeout: 15e3,
|
|
142
|
+
userAgentAppendix: `Node.js ${process.version}`,
|
|
143
|
+
version: APIVersion,
|
|
144
|
+
hashSweepInterval: 144e5,
|
|
145
|
+
hashLifetime: 864e5,
|
|
146
|
+
handlerSweepInterval: 36e5
|
|
147
|
+
};
|
|
148
|
+
var RESTEvents = /* @__PURE__ */ ((RESTEvents2) => {
|
|
149
|
+
RESTEvents2["Debug"] = "restDebug";
|
|
150
|
+
RESTEvents2["InvalidRequestWarning"] = "invalidRequestWarning";
|
|
151
|
+
RESTEvents2["RateLimited"] = "rateLimited";
|
|
152
|
+
RESTEvents2["Request"] = "request";
|
|
153
|
+
RESTEvents2["Response"] = "response";
|
|
154
|
+
RESTEvents2["HashSweep"] = "hashSweep";
|
|
155
|
+
RESTEvents2["HandlerSweep"] = "handlerSweep";
|
|
156
|
+
return RESTEvents2;
|
|
157
|
+
})(RESTEvents || {});
|
|
158
|
+
var ALLOWED_EXTENSIONS = ["webp", "png", "jpg", "jpeg", "gif"];
|
|
159
|
+
var ALLOWED_STICKER_EXTENSIONS = ["png", "json"];
|
|
160
|
+
var ALLOWED_SIZES = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096];
|
|
161
|
+
|
|
162
|
+
// src/lib/CDN.ts
|
|
163
|
+
var CDN = class {
|
|
164
|
+
constructor(base = DefaultRestOptions.cdn) {
|
|
165
|
+
this.base = base;
|
|
166
|
+
}
|
|
167
|
+
appAsset(clientId, assetHash, options) {
|
|
168
|
+
return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);
|
|
169
|
+
}
|
|
170
|
+
appIcon(clientId, iconHash, options) {
|
|
171
|
+
return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);
|
|
172
|
+
}
|
|
173
|
+
avatar(id, avatarHash, options) {
|
|
174
|
+
return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);
|
|
175
|
+
}
|
|
176
|
+
banner(id, bannerHash, options) {
|
|
177
|
+
return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);
|
|
178
|
+
}
|
|
179
|
+
channelIcon(channelId, iconHash, options) {
|
|
180
|
+
return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);
|
|
181
|
+
}
|
|
182
|
+
defaultAvatar(discriminator) {
|
|
183
|
+
return this.makeURL(`/embed/avatars/${discriminator}`, { extension: "png" });
|
|
184
|
+
}
|
|
185
|
+
discoverySplash(guildId, splashHash, options) {
|
|
186
|
+
return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);
|
|
187
|
+
}
|
|
188
|
+
emoji(emojiId, extension) {
|
|
189
|
+
return this.makeURL(`/emojis/${emojiId}`, { extension });
|
|
190
|
+
}
|
|
191
|
+
guildMemberAvatar(guildId, userId, avatarHash, options) {
|
|
192
|
+
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);
|
|
193
|
+
}
|
|
194
|
+
icon(id, iconHash, options) {
|
|
195
|
+
return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);
|
|
196
|
+
}
|
|
197
|
+
roleIcon(roleId, roleIconHash, options) {
|
|
198
|
+
return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);
|
|
199
|
+
}
|
|
200
|
+
splash(guildId, splashHash, options) {
|
|
201
|
+
return this.makeURL(`/splashes/${guildId}/${splashHash}`, options);
|
|
202
|
+
}
|
|
203
|
+
sticker(stickerId, extension) {
|
|
204
|
+
return this.makeURL(`/stickers/${stickerId}`, {
|
|
205
|
+
allowedExtensions: ALLOWED_STICKER_EXTENSIONS,
|
|
206
|
+
extension: extension ?? "png"
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
stickerPackBanner(bannerId, options) {
|
|
210
|
+
return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);
|
|
211
|
+
}
|
|
212
|
+
teamIcon(teamId, iconHash, options) {
|
|
213
|
+
return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);
|
|
214
|
+
}
|
|
215
|
+
guildScheduledEventCover(scheduledEventId, coverHash, options) {
|
|
216
|
+
return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);
|
|
217
|
+
}
|
|
218
|
+
dynamicMakeURL(route, hash, { forceStatic = false, ...options } = {}) {
|
|
219
|
+
return this.makeURL(route, !forceStatic && hash.startsWith("a_") ? { ...options, extension: "gif" } : options);
|
|
220
|
+
}
|
|
221
|
+
makeURL(route, { allowedExtensions = ALLOWED_EXTENSIONS, extension = "webp", size } = {}) {
|
|
222
|
+
extension = String(extension).toLowerCase();
|
|
223
|
+
if (!allowedExtensions.includes(extension)) {
|
|
224
|
+
throw new RangeError(`Invalid extension provided: ${extension}
|
|
225
|
+
Must be one of: ${allowedExtensions.join(", ")}`);
|
|
226
|
+
}
|
|
227
|
+
if (size && !ALLOWED_SIZES.includes(size)) {
|
|
228
|
+
throw new RangeError(`Invalid size provided: ${size}
|
|
229
|
+
Must be one of: ${ALLOWED_SIZES.join(", ")}`);
|
|
230
|
+
}
|
|
231
|
+
const url = new URL(`${this.base}${route}.${extension}`);
|
|
232
|
+
if (size) {
|
|
233
|
+
url.searchParams.set("size", String(size));
|
|
234
|
+
}
|
|
235
|
+
return url.toString();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
__name(CDN, "CDN");
|
|
239
|
+
|
|
240
|
+
// src/lib/errors/DiscordAPIError.ts
|
|
241
|
+
function isErrorGroupWrapper(error) {
|
|
242
|
+
return Reflect.has(error, "_errors");
|
|
243
|
+
}
|
|
244
|
+
__name(isErrorGroupWrapper, "isErrorGroupWrapper");
|
|
245
|
+
function isErrorResponse(error) {
|
|
246
|
+
return typeof Reflect.get(error, "message") === "string";
|
|
247
|
+
}
|
|
248
|
+
__name(isErrorResponse, "isErrorResponse");
|
|
249
|
+
var DiscordAPIError = class extends Error {
|
|
250
|
+
constructor(rawError, code, status, method, url, bodyData) {
|
|
251
|
+
super(DiscordAPIError.getMessage(rawError));
|
|
252
|
+
this.rawError = rawError;
|
|
253
|
+
this.code = code;
|
|
254
|
+
this.status = status;
|
|
255
|
+
this.method = method;
|
|
256
|
+
this.url = url;
|
|
257
|
+
__publicField(this, "requestBody");
|
|
258
|
+
this.requestBody = { files: bodyData.files, json: bodyData.body };
|
|
259
|
+
}
|
|
260
|
+
get name() {
|
|
261
|
+
return `${DiscordAPIError.name}[${this.code}]`;
|
|
262
|
+
}
|
|
263
|
+
static getMessage(error) {
|
|
264
|
+
let flattened = "";
|
|
265
|
+
if ("code" in error) {
|
|
266
|
+
if (error.errors) {
|
|
267
|
+
flattened = [...this.flattenDiscordError(error.errors)].join("\n");
|
|
268
|
+
}
|
|
269
|
+
return error.message && flattened ? `${error.message}
|
|
270
|
+
${flattened}` : error.message || flattened || "Unknown Error";
|
|
271
|
+
}
|
|
272
|
+
return error.error_description ?? "No Description";
|
|
273
|
+
}
|
|
274
|
+
static *flattenDiscordError(obj, key = "") {
|
|
275
|
+
if (isErrorResponse(obj)) {
|
|
276
|
+
return yield `${key.length ? `${key}[${obj.code}]` : `${obj.code}`}: ${obj.message}`.trim();
|
|
277
|
+
}
|
|
278
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
279
|
+
const nextKey = k.startsWith("_") ? key : key ? Number.isNaN(Number(k)) ? `${key}.${k}` : `${key}[${k}]` : k;
|
|
280
|
+
if (typeof v === "string") {
|
|
281
|
+
yield v;
|
|
282
|
+
} else if (isErrorGroupWrapper(v)) {
|
|
283
|
+
for (const error of v._errors) {
|
|
284
|
+
yield* this.flattenDiscordError(error, nextKey);
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
yield* this.flattenDiscordError(v, nextKey);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
__name(DiscordAPIError, "DiscordAPIError");
|
|
293
|
+
|
|
294
|
+
// src/lib/errors/HTTPError.ts
|
|
295
|
+
var HTTPError = class extends Error {
|
|
296
|
+
constructor(message, name, status, method, url, bodyData) {
|
|
297
|
+
super(message);
|
|
298
|
+
this.name = name;
|
|
299
|
+
this.status = status;
|
|
300
|
+
this.method = method;
|
|
301
|
+
this.url = url;
|
|
302
|
+
__publicField(this, "requestBody");
|
|
303
|
+
this.requestBody = { files: bodyData.files, json: bodyData.body };
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
__name(HTTPError, "HTTPError");
|
|
307
|
+
|
|
308
|
+
// src/lib/errors/RateLimitError.ts
|
|
309
|
+
var RateLimitError = class extends Error {
|
|
310
|
+
constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }) {
|
|
311
|
+
super();
|
|
312
|
+
__publicField(this, "timeToReset");
|
|
313
|
+
__publicField(this, "limit");
|
|
314
|
+
__publicField(this, "method");
|
|
315
|
+
__publicField(this, "hash");
|
|
316
|
+
__publicField(this, "url");
|
|
317
|
+
__publicField(this, "route");
|
|
318
|
+
__publicField(this, "majorParameter");
|
|
319
|
+
__publicField(this, "global");
|
|
320
|
+
this.timeToReset = timeToReset;
|
|
321
|
+
this.limit = limit;
|
|
322
|
+
this.method = method;
|
|
323
|
+
this.hash = hash;
|
|
324
|
+
this.url = url;
|
|
325
|
+
this.route = route;
|
|
326
|
+
this.majorParameter = majorParameter;
|
|
327
|
+
this.global = global;
|
|
328
|
+
}
|
|
329
|
+
get name() {
|
|
330
|
+
return `${RateLimitError.name}[${this.route}]`;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
__name(RateLimitError, "RateLimitError");
|
|
334
|
+
|
|
335
|
+
// src/lib/RequestManager.ts
|
|
336
|
+
import Collection from "@discordjs/collection";
|
|
337
|
+
import FormData from "form-data";
|
|
338
|
+
import { DiscordSnowflake } from "@sapphire/snowflake";
|
|
339
|
+
import { EventEmitter } from "node:events";
|
|
340
|
+
import { Agent as httpsAgent } from "node:https";
|
|
341
|
+
import { Agent as httpAgent } from "node:http";
|
|
342
|
+
|
|
343
|
+
// src/lib/handlers/SequentialHandler.ts
|
|
344
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
345
|
+
import { AsyncQueue } from "@sapphire/async-queue";
|
|
346
|
+
import fetch from "node-fetch";
|
|
347
|
+
|
|
348
|
+
// src/lib/utils/utils.ts
|
|
349
|
+
function parseResponse(res) {
|
|
350
|
+
if (res.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
351
|
+
return res.json();
|
|
352
|
+
}
|
|
353
|
+
return res.arrayBuffer();
|
|
354
|
+
}
|
|
355
|
+
__name(parseResponse, "parseResponse");
|
|
356
|
+
function hasSublimit(bucketRoute, body, method) {
|
|
357
|
+
if (bucketRoute === "/channels/:id") {
|
|
358
|
+
if (typeof body !== "object" || body === null)
|
|
359
|
+
return false;
|
|
360
|
+
if (method !== "patch" /* Patch */)
|
|
361
|
+
return false;
|
|
362
|
+
const castedBody = body;
|
|
363
|
+
return ["name", "topic"].some((key) => Reflect.has(castedBody, key));
|
|
364
|
+
}
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
__name(hasSublimit, "hasSublimit");
|
|
368
|
+
|
|
369
|
+
// src/lib/handlers/SequentialHandler.ts
|
|
370
|
+
var invalidCount = 0;
|
|
371
|
+
var invalidCountResetTime = null;
|
|
372
|
+
var _asyncQueue, _sublimitedQueue, _sublimitPromise, _shiftSublimit;
|
|
373
|
+
var SequentialHandler = class {
|
|
374
|
+
constructor(manager, hash, majorParameter) {
|
|
375
|
+
this.manager = manager;
|
|
376
|
+
this.hash = hash;
|
|
377
|
+
this.majorParameter = majorParameter;
|
|
378
|
+
__publicField(this, "id");
|
|
379
|
+
__publicField(this, "reset", -1);
|
|
380
|
+
__publicField(this, "remaining", 1);
|
|
381
|
+
__publicField(this, "limit", Infinity);
|
|
382
|
+
__privateAdd(this, _asyncQueue, new AsyncQueue());
|
|
383
|
+
__privateAdd(this, _sublimitedQueue, null);
|
|
384
|
+
__privateAdd(this, _sublimitPromise, null);
|
|
385
|
+
__privateAdd(this, _shiftSublimit, false);
|
|
386
|
+
this.id = `${hash}:${majorParameter}`;
|
|
387
|
+
}
|
|
388
|
+
get inactive() {
|
|
389
|
+
return __privateGet(this, _asyncQueue).remaining === 0 && (__privateGet(this, _sublimitedQueue) === null || __privateGet(this, _sublimitedQueue).remaining === 0) && !this.limited;
|
|
390
|
+
}
|
|
391
|
+
get globalLimited() {
|
|
392
|
+
return this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;
|
|
393
|
+
}
|
|
394
|
+
get localLimited() {
|
|
395
|
+
return this.remaining <= 0 && Date.now() < this.reset;
|
|
396
|
+
}
|
|
397
|
+
get limited() {
|
|
398
|
+
return this.globalLimited || this.localLimited;
|
|
399
|
+
}
|
|
400
|
+
get timeToReset() {
|
|
401
|
+
return this.reset + this.manager.options.offset - Date.now();
|
|
402
|
+
}
|
|
403
|
+
debug(message) {
|
|
404
|
+
this.manager.emit("restDebug" /* Debug */, `[REST ${this.id}] ${message}`);
|
|
405
|
+
}
|
|
406
|
+
async globalDelayFor(time) {
|
|
407
|
+
await sleep(time, void 0, { ref: false });
|
|
408
|
+
this.manager.globalDelay = null;
|
|
409
|
+
}
|
|
410
|
+
async onRateLimit(rateLimitData) {
|
|
411
|
+
const { options } = this.manager;
|
|
412
|
+
if (!options.rejectOnRateLimit)
|
|
413
|
+
return;
|
|
414
|
+
const shouldThrow = typeof options.rejectOnRateLimit === "function" ? await options.rejectOnRateLimit(rateLimitData) : options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));
|
|
415
|
+
if (shouldThrow) {
|
|
416
|
+
throw new RateLimitError(rateLimitData);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async queueRequest(routeId, url, options, requestData) {
|
|
420
|
+
let queue = __privateGet(this, _asyncQueue);
|
|
421
|
+
let queueType = 0 /* Standard */;
|
|
422
|
+
if (__privateGet(this, _sublimitedQueue) && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {
|
|
423
|
+
queue = __privateGet(this, _sublimitedQueue);
|
|
424
|
+
queueType = 1 /* Sublimit */;
|
|
425
|
+
}
|
|
426
|
+
await queue.wait();
|
|
427
|
+
if (queueType === 0 /* Standard */) {
|
|
428
|
+
if (__privateGet(this, _sublimitedQueue) && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {
|
|
429
|
+
queue = __privateGet(this, _sublimitedQueue);
|
|
430
|
+
const wait = queue.wait();
|
|
431
|
+
__privateGet(this, _asyncQueue).shift();
|
|
432
|
+
await wait;
|
|
433
|
+
} else if (__privateGet(this, _sublimitPromise)) {
|
|
434
|
+
await __privateGet(this, _sublimitPromise).promise;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
return await this.runRequest(routeId, url, options, requestData);
|
|
439
|
+
} finally {
|
|
440
|
+
queue.shift();
|
|
441
|
+
if (__privateGet(this, _shiftSublimit)) {
|
|
442
|
+
__privateSet(this, _shiftSublimit, false);
|
|
443
|
+
__privateGet(this, _sublimitedQueue)?.shift();
|
|
444
|
+
}
|
|
445
|
+
if (__privateGet(this, _sublimitedQueue)?.remaining === 0) {
|
|
446
|
+
__privateGet(this, _sublimitPromise)?.resolve();
|
|
447
|
+
__privateSet(this, _sublimitedQueue, null);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
async runRequest(routeId, url, options, requestData, retries = 0) {
|
|
452
|
+
while (this.limited) {
|
|
453
|
+
const isGlobal = this.globalLimited;
|
|
454
|
+
let limit2;
|
|
455
|
+
let timeout2;
|
|
456
|
+
let delay;
|
|
457
|
+
if (isGlobal) {
|
|
458
|
+
limit2 = this.manager.options.globalRequestsPerSecond;
|
|
459
|
+
timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now();
|
|
460
|
+
if (!this.manager.globalDelay) {
|
|
461
|
+
this.manager.globalDelay = this.globalDelayFor(timeout2);
|
|
462
|
+
}
|
|
463
|
+
delay = this.manager.globalDelay;
|
|
464
|
+
} else {
|
|
465
|
+
limit2 = this.limit;
|
|
466
|
+
timeout2 = this.timeToReset;
|
|
467
|
+
delay = sleep(timeout2);
|
|
468
|
+
}
|
|
469
|
+
const rateLimitData = {
|
|
470
|
+
timeToReset: timeout2,
|
|
471
|
+
limit: limit2,
|
|
472
|
+
method: options.method ?? "get",
|
|
473
|
+
hash: this.hash,
|
|
474
|
+
url,
|
|
475
|
+
route: routeId.bucketRoute,
|
|
476
|
+
majorParameter: this.majorParameter,
|
|
477
|
+
global: isGlobal
|
|
478
|
+
};
|
|
479
|
+
this.manager.emit("rateLimited" /* RateLimited */, rateLimitData);
|
|
480
|
+
await this.onRateLimit(rateLimitData);
|
|
481
|
+
if (isGlobal) {
|
|
482
|
+
this.debug(`Global rate limit hit, blocking all requests for ${timeout2}ms`);
|
|
483
|
+
} else {
|
|
484
|
+
this.debug(`Waiting ${timeout2}ms for rate limit to pass`);
|
|
485
|
+
}
|
|
486
|
+
await delay;
|
|
487
|
+
}
|
|
488
|
+
if (!this.manager.globalReset || this.manager.globalReset < Date.now()) {
|
|
489
|
+
this.manager.globalReset = Date.now() + 1e3;
|
|
490
|
+
this.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;
|
|
491
|
+
}
|
|
492
|
+
this.manager.globalRemaining--;
|
|
493
|
+
const method = options.method ?? "get";
|
|
494
|
+
if (this.manager.listenerCount("request" /* Request */)) {
|
|
495
|
+
this.manager.emit("request" /* Request */, {
|
|
496
|
+
method,
|
|
497
|
+
path: routeId.original,
|
|
498
|
+
route: routeId.bucketRoute,
|
|
499
|
+
options,
|
|
500
|
+
data: requestData,
|
|
501
|
+
retries
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
const controller = new AbortController();
|
|
505
|
+
const timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref();
|
|
506
|
+
let res;
|
|
507
|
+
try {
|
|
508
|
+
res = await fetch(url, { ...options, signal: controller.signal });
|
|
509
|
+
} catch (error) {
|
|
510
|
+
if (error instanceof Error && error.name === "AbortError" && retries !== this.manager.options.retries) {
|
|
511
|
+
return await this.runRequest(routeId, url, options, requestData, ++retries);
|
|
512
|
+
}
|
|
513
|
+
throw error;
|
|
514
|
+
} finally {
|
|
515
|
+
clearTimeout(timeout);
|
|
516
|
+
}
|
|
517
|
+
if (this.manager.listenerCount("response" /* Response */)) {
|
|
518
|
+
this.manager.emit("response" /* Response */, {
|
|
519
|
+
method,
|
|
520
|
+
path: routeId.original,
|
|
521
|
+
route: routeId.bucketRoute,
|
|
522
|
+
options,
|
|
523
|
+
data: requestData,
|
|
524
|
+
retries
|
|
525
|
+
}, res.clone());
|
|
526
|
+
}
|
|
527
|
+
let retryAfter = 0;
|
|
528
|
+
const limit = res.headers.get("X-RateLimit-Limit");
|
|
529
|
+
const remaining = res.headers.get("X-RateLimit-Remaining");
|
|
530
|
+
const reset = res.headers.get("X-RateLimit-Reset-After");
|
|
531
|
+
const hash = res.headers.get("X-RateLimit-Bucket");
|
|
532
|
+
const retry = res.headers.get("Retry-After");
|
|
533
|
+
this.limit = limit ? Number(limit) : Infinity;
|
|
534
|
+
this.remaining = remaining ? Number(remaining) : 1;
|
|
535
|
+
this.reset = reset ? Number(reset) * 1e3 + Date.now() + this.manager.options.offset : Date.now();
|
|
536
|
+
if (retry)
|
|
537
|
+
retryAfter = Number(retry) * 1e3 + this.manager.options.offset;
|
|
538
|
+
if (hash && hash !== this.hash) {
|
|
539
|
+
this.debug(["Received bucket hash update", ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join("\n"));
|
|
540
|
+
this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });
|
|
541
|
+
} else if (hash) {
|
|
542
|
+
const hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);
|
|
543
|
+
if (hashData) {
|
|
544
|
+
hashData.lastAccess = Date.now();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
let sublimitTimeout = null;
|
|
548
|
+
if (retryAfter > 0) {
|
|
549
|
+
if (res.headers.get("X-RateLimit-Global")) {
|
|
550
|
+
this.manager.globalRemaining = 0;
|
|
551
|
+
this.manager.globalReset = Date.now() + retryAfter;
|
|
552
|
+
} else if (!this.localLimited) {
|
|
553
|
+
sublimitTimeout = retryAfter;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (res.status === 401 || res.status === 403 || res.status === 429) {
|
|
557
|
+
if (!invalidCountResetTime || invalidCountResetTime < Date.now()) {
|
|
558
|
+
invalidCountResetTime = Date.now() + 1e3 * 60 * 10;
|
|
559
|
+
invalidCount = 0;
|
|
560
|
+
}
|
|
561
|
+
invalidCount++;
|
|
562
|
+
const emitInvalid = this.manager.options.invalidRequestWarningInterval > 0 && invalidCount % this.manager.options.invalidRequestWarningInterval === 0;
|
|
563
|
+
if (emitInvalid) {
|
|
564
|
+
this.manager.emit("invalidRequestWarning" /* InvalidRequestWarning */, {
|
|
565
|
+
count: invalidCount,
|
|
566
|
+
remainingTime: invalidCountResetTime - Date.now()
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
if (res.ok) {
|
|
571
|
+
return parseResponse(res);
|
|
572
|
+
} else if (res.status === 429) {
|
|
573
|
+
const isGlobal = this.globalLimited;
|
|
574
|
+
let limit2;
|
|
575
|
+
let timeout2;
|
|
576
|
+
if (isGlobal) {
|
|
577
|
+
limit2 = this.manager.options.globalRequestsPerSecond;
|
|
578
|
+
timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now();
|
|
579
|
+
} else {
|
|
580
|
+
limit2 = this.limit;
|
|
581
|
+
timeout2 = this.timeToReset;
|
|
582
|
+
}
|
|
583
|
+
await this.onRateLimit({
|
|
584
|
+
timeToReset: timeout2,
|
|
585
|
+
limit: limit2,
|
|
586
|
+
method,
|
|
587
|
+
hash: this.hash,
|
|
588
|
+
url,
|
|
589
|
+
route: routeId.bucketRoute,
|
|
590
|
+
majorParameter: this.majorParameter,
|
|
591
|
+
global: isGlobal
|
|
592
|
+
});
|
|
593
|
+
this.debug([
|
|
594
|
+
"Encountered unexpected 429 rate limit",
|
|
595
|
+
` Global : ${isGlobal.toString()}`,
|
|
596
|
+
` Method : ${method}`,
|
|
597
|
+
` URL : ${url}`,
|
|
598
|
+
` Bucket : ${routeId.bucketRoute}`,
|
|
599
|
+
` Major parameter: ${routeId.majorParameter}`,
|
|
600
|
+
` Hash : ${this.hash}`,
|
|
601
|
+
` Limit : ${limit2}`,
|
|
602
|
+
` Retry After : ${retryAfter}ms`,
|
|
603
|
+
` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : "None"}`
|
|
604
|
+
].join("\n"));
|
|
605
|
+
if (sublimitTimeout) {
|
|
606
|
+
const firstSublimit = !__privateGet(this, _sublimitedQueue);
|
|
607
|
+
if (firstSublimit) {
|
|
608
|
+
__privateSet(this, _sublimitedQueue, new AsyncQueue());
|
|
609
|
+
void __privateGet(this, _sublimitedQueue).wait();
|
|
610
|
+
__privateGet(this, _asyncQueue).shift();
|
|
611
|
+
}
|
|
612
|
+
__privateGet(this, _sublimitPromise)?.resolve();
|
|
613
|
+
__privateSet(this, _sublimitPromise, null);
|
|
614
|
+
await sleep(sublimitTimeout, void 0, { ref: false });
|
|
615
|
+
let resolve;
|
|
616
|
+
const promise = new Promise((res2) => resolve = res2);
|
|
617
|
+
__privateSet(this, _sublimitPromise, { promise, resolve });
|
|
618
|
+
if (firstSublimit) {
|
|
619
|
+
await __privateGet(this, _asyncQueue).wait();
|
|
620
|
+
__privateSet(this, _shiftSublimit, true);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return this.runRequest(routeId, url, options, requestData, retries);
|
|
624
|
+
} else if (res.status >= 500 && res.status < 600) {
|
|
625
|
+
if (retries !== this.manager.options.retries) {
|
|
626
|
+
return this.runRequest(routeId, url, options, requestData, ++retries);
|
|
627
|
+
}
|
|
628
|
+
throw new HTTPError(res.statusText, res.constructor.name, res.status, method, url, requestData);
|
|
629
|
+
} else {
|
|
630
|
+
if (res.status >= 400 && res.status < 500) {
|
|
631
|
+
if (res.status === 401 && requestData.auth) {
|
|
632
|
+
this.manager.setToken(null);
|
|
633
|
+
}
|
|
634
|
+
const data = await parseResponse(res);
|
|
635
|
+
throw new DiscordAPIError(data, "code" in data ? data.code : data.error, res.status, method, url, requestData);
|
|
636
|
+
}
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
__name(SequentialHandler, "SequentialHandler");
|
|
642
|
+
_asyncQueue = new WeakMap();
|
|
643
|
+
_sublimitedQueue = new WeakMap();
|
|
644
|
+
_sublimitPromise = new WeakMap();
|
|
645
|
+
_shiftSublimit = new WeakMap();
|
|
646
|
+
|
|
647
|
+
// src/lib/RequestManager.ts
|
|
648
|
+
var RequestMethod = /* @__PURE__ */ ((RequestMethod2) => {
|
|
649
|
+
RequestMethod2["Delete"] = "delete";
|
|
650
|
+
RequestMethod2["Get"] = "get";
|
|
651
|
+
RequestMethod2["Patch"] = "patch";
|
|
652
|
+
RequestMethod2["Post"] = "post";
|
|
653
|
+
RequestMethod2["Put"] = "put";
|
|
654
|
+
return RequestMethod2;
|
|
655
|
+
})(RequestMethod || {});
|
|
656
|
+
var _token;
|
|
657
|
+
var _RequestManager = class extends EventEmitter {
|
|
658
|
+
constructor(options) {
|
|
659
|
+
super();
|
|
660
|
+
__publicField(this, "globalRemaining");
|
|
661
|
+
__publicField(this, "globalDelay", null);
|
|
662
|
+
__publicField(this, "globalReset", -1);
|
|
663
|
+
__publicField(this, "hashes", new Collection());
|
|
664
|
+
__publicField(this, "handlers", new Collection());
|
|
665
|
+
__privateAdd(this, _token, null);
|
|
666
|
+
__publicField(this, "hashTimer");
|
|
667
|
+
__publicField(this, "handlerTimer");
|
|
668
|
+
__publicField(this, "agent", null);
|
|
669
|
+
__publicField(this, "options");
|
|
670
|
+
this.options = { ...DefaultRestOptions, ...options };
|
|
671
|
+
this.options.offset = Math.max(0, this.options.offset);
|
|
672
|
+
this.globalRemaining = this.options.globalRequestsPerSecond;
|
|
673
|
+
this.setupSweepers();
|
|
674
|
+
}
|
|
675
|
+
setupSweepers() {
|
|
676
|
+
const validateMaxInterval = /* @__PURE__ */ __name((interval) => {
|
|
677
|
+
if (interval > 144e5) {
|
|
678
|
+
throw new Error("Cannot set an interval greater than 4 hours");
|
|
679
|
+
}
|
|
680
|
+
}, "validateMaxInterval");
|
|
681
|
+
if (this.options.hashSweepInterval !== 0 && this.options.hashSweepInterval !== Infinity) {
|
|
682
|
+
validateMaxInterval(this.options.hashSweepInterval);
|
|
683
|
+
this.hashTimer = setInterval(() => {
|
|
684
|
+
const sweptHashes = new Collection();
|
|
685
|
+
const currentDate = Date.now();
|
|
686
|
+
this.hashes.sweep((v, k) => {
|
|
687
|
+
if (v.lastAccess === -1)
|
|
688
|
+
return false;
|
|
689
|
+
const shouldSweep = Math.floor(currentDate - v.lastAccess) > this.options.hashLifetime;
|
|
690
|
+
if (shouldSweep) {
|
|
691
|
+
sweptHashes.set(k, v);
|
|
692
|
+
}
|
|
693
|
+
this.emit("restDebug" /* Debug */, `Hash ${v.value} for ${k} swept due to lifetime being exceeded`);
|
|
694
|
+
return shouldSweep;
|
|
695
|
+
});
|
|
696
|
+
this.emit("hashSweep" /* HashSweep */, sweptHashes);
|
|
697
|
+
}, this.options.hashSweepInterval).unref();
|
|
698
|
+
}
|
|
699
|
+
if (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Infinity) {
|
|
700
|
+
validateMaxInterval(this.options.handlerSweepInterval);
|
|
701
|
+
this.handlerTimer = setInterval(() => {
|
|
702
|
+
const sweptHandlers = new Collection();
|
|
703
|
+
this.handlers.sweep((v, k) => {
|
|
704
|
+
const { inactive } = v;
|
|
705
|
+
if (inactive) {
|
|
706
|
+
sweptHandlers.set(k, v);
|
|
707
|
+
}
|
|
708
|
+
this.emit("restDebug" /* Debug */, `Handler ${v.id} for ${k} swept due to being inactive`);
|
|
709
|
+
return inactive;
|
|
710
|
+
});
|
|
711
|
+
this.emit("handlerSweep" /* HandlerSweep */, sweptHandlers);
|
|
712
|
+
}, this.options.handlerSweepInterval).unref();
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
setToken(token) {
|
|
716
|
+
__privateSet(this, _token, token);
|
|
717
|
+
return this;
|
|
718
|
+
}
|
|
719
|
+
async queueRequest(request) {
|
|
720
|
+
const routeId = _RequestManager.generateRouteData(request.fullRoute, request.method);
|
|
721
|
+
const hash = this.hashes.get(`${request.method}:${routeId.bucketRoute}`) ?? {
|
|
722
|
+
value: `Global(${request.method}:${routeId.bucketRoute})`,
|
|
723
|
+
lastAccess: -1
|
|
724
|
+
};
|
|
725
|
+
const handler = this.handlers.get(`${hash.value}:${routeId.majorParameter}`) ?? this.createHandler(hash.value, routeId.majorParameter);
|
|
726
|
+
const { url, fetchOptions } = this.resolveRequest(request);
|
|
727
|
+
return handler.queueRequest(routeId, url, fetchOptions, {
|
|
728
|
+
body: request.body,
|
|
729
|
+
files: request.files,
|
|
730
|
+
auth: request.auth !== false
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
createHandler(hash, majorParameter) {
|
|
734
|
+
const queue = new SequentialHandler(this, hash, majorParameter);
|
|
735
|
+
this.handlers.set(queue.id, queue);
|
|
736
|
+
return queue;
|
|
737
|
+
}
|
|
738
|
+
resolveRequest(request) {
|
|
739
|
+
const { options } = this;
|
|
740
|
+
this.agent ??= options.api.startsWith("https") ? new httpsAgent({ ...options.agent, keepAlive: true }) : new httpAgent({ ...options.agent, keepAlive: true });
|
|
741
|
+
let query = "";
|
|
742
|
+
if (request.query) {
|
|
743
|
+
const resolvedQuery = request.query.toString();
|
|
744
|
+
if (resolvedQuery !== "") {
|
|
745
|
+
query = `?${resolvedQuery}`;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
const headers = {
|
|
749
|
+
...this.options.headers,
|
|
750
|
+
"User-Agent": `${DefaultUserAgent} ${options.userAgentAppendix}`.trim()
|
|
751
|
+
};
|
|
752
|
+
if (request.auth !== false) {
|
|
753
|
+
if (!__privateGet(this, _token)) {
|
|
754
|
+
throw new Error("Expected token to be set for this request, but none was present");
|
|
755
|
+
}
|
|
756
|
+
headers.Authorization = `${request.authPrefix ?? "Bot"} ${__privateGet(this, _token)}`;
|
|
757
|
+
}
|
|
758
|
+
if (request.reason?.length) {
|
|
759
|
+
headers["X-Audit-Log-Reason"] = encodeURIComponent(request.reason);
|
|
760
|
+
}
|
|
761
|
+
const url = `${options.api}${request.versioned === false ? "" : `/v${options.version}`}${request.fullRoute}${query}`;
|
|
762
|
+
let finalBody;
|
|
763
|
+
let additionalHeaders = {};
|
|
764
|
+
if (request.files?.length) {
|
|
765
|
+
const formData = new FormData();
|
|
766
|
+
for (const [index, file] of request.files.entries()) {
|
|
767
|
+
formData.append(file.key ?? `files[${index}]`, file.data, file.name);
|
|
768
|
+
}
|
|
769
|
+
if (request.body != null) {
|
|
770
|
+
if (request.appendToFormData) {
|
|
771
|
+
for (const [key, value] of Object.entries(request.body)) {
|
|
772
|
+
formData.append(key, value);
|
|
773
|
+
}
|
|
774
|
+
} else {
|
|
775
|
+
formData.append("payload_json", JSON.stringify(request.body));
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
finalBody = formData;
|
|
779
|
+
additionalHeaders = formData.getHeaders();
|
|
780
|
+
} else if (request.body != null) {
|
|
781
|
+
if (request.passThroughBody) {
|
|
782
|
+
finalBody = request.body;
|
|
783
|
+
} else {
|
|
784
|
+
finalBody = JSON.stringify(request.body);
|
|
785
|
+
additionalHeaders = { "Content-Type": "application/json" };
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
const fetchOptions = {
|
|
789
|
+
agent: this.agent,
|
|
790
|
+
body: finalBody,
|
|
791
|
+
headers: { ...request.headers ?? {}, ...additionalHeaders, ...headers },
|
|
792
|
+
method: request.method
|
|
793
|
+
};
|
|
794
|
+
return { url, fetchOptions };
|
|
795
|
+
}
|
|
796
|
+
clearHashSweeper() {
|
|
797
|
+
clearInterval(this.hashTimer);
|
|
798
|
+
}
|
|
799
|
+
clearHandlerSweeper() {
|
|
800
|
+
clearInterval(this.handlerTimer);
|
|
801
|
+
}
|
|
802
|
+
static generateRouteData(endpoint, method) {
|
|
803
|
+
const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(endpoint);
|
|
804
|
+
const majorId = majorIdMatch?.[1] ?? "global";
|
|
805
|
+
const baseRoute = endpoint.replace(/\d{16,19}/g, ":id").replace(/\/reactions\/(.*)/, "/reactions/:reaction");
|
|
806
|
+
let exceptions = "";
|
|
807
|
+
if (method === "delete" /* Delete */ && baseRoute === "/channels/:id/messages/:id") {
|
|
808
|
+
const id = /\d{16,19}$/.exec(endpoint)[0];
|
|
809
|
+
const timestamp = DiscordSnowflake.timestampFrom(id);
|
|
810
|
+
if (Date.now() - timestamp > 1e3 * 60 * 60 * 24 * 14) {
|
|
811
|
+
exceptions += "/Delete Old Message";
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return {
|
|
815
|
+
majorParameter: majorId,
|
|
816
|
+
bucketRoute: baseRoute + exceptions,
|
|
817
|
+
original: endpoint
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
var RequestManager = _RequestManager;
|
|
822
|
+
__name(RequestManager, "RequestManager");
|
|
823
|
+
_token = new WeakMap();
|
|
824
|
+
|
|
825
|
+
// src/lib/REST.ts
|
|
826
|
+
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
827
|
+
var REST = class extends EventEmitter2 {
|
|
828
|
+
constructor(options = {}) {
|
|
829
|
+
super();
|
|
830
|
+
__publicField(this, "cdn");
|
|
831
|
+
__publicField(this, "requestManager");
|
|
832
|
+
this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn);
|
|
833
|
+
this.requestManager = new RequestManager(options).on("restDebug" /* Debug */, this.emit.bind(this, "restDebug" /* Debug */)).on("rateLimited" /* RateLimited */, this.emit.bind(this, "rateLimited" /* RateLimited */)).on("invalidRequestWarning" /* InvalidRequestWarning */, this.emit.bind(this, "invalidRequestWarning" /* InvalidRequestWarning */)).on("hashSweep" /* HashSweep */, this.emit.bind(this, "hashSweep" /* HashSweep */));
|
|
834
|
+
this.on("newListener", (name, listener) => {
|
|
835
|
+
if (name === "request" /* Request */ || name === "response" /* Response */)
|
|
836
|
+
this.requestManager.on(name, listener);
|
|
837
|
+
});
|
|
838
|
+
this.on("removeListener", (name, listener) => {
|
|
839
|
+
if (name === "request" /* Request */ || name === "response" /* Response */)
|
|
840
|
+
this.requestManager.off(name, listener);
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
setToken(token) {
|
|
844
|
+
this.requestManager.setToken(token);
|
|
845
|
+
return this;
|
|
846
|
+
}
|
|
847
|
+
get(fullRoute, options = {}) {
|
|
848
|
+
return this.request({ ...options, fullRoute, method: "get" /* Get */ });
|
|
849
|
+
}
|
|
850
|
+
delete(fullRoute, options = {}) {
|
|
851
|
+
return this.request({ ...options, fullRoute, method: "delete" /* Delete */ });
|
|
852
|
+
}
|
|
853
|
+
post(fullRoute, options = {}) {
|
|
854
|
+
return this.request({ ...options, fullRoute, method: "post" /* Post */ });
|
|
855
|
+
}
|
|
856
|
+
put(fullRoute, options = {}) {
|
|
857
|
+
return this.request({ ...options, fullRoute, method: "put" /* Put */ });
|
|
858
|
+
}
|
|
859
|
+
patch(fullRoute, options = {}) {
|
|
860
|
+
return this.request({ ...options, fullRoute, method: "patch" /* Patch */ });
|
|
861
|
+
}
|
|
862
|
+
request(options) {
|
|
863
|
+
return this.requestManager.queueRequest(options);
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
__name(REST, "REST");
|
|
867
|
+
export {
|
|
868
|
+
ALLOWED_EXTENSIONS,
|
|
869
|
+
ALLOWED_SIZES,
|
|
870
|
+
ALLOWED_STICKER_EXTENSIONS,
|
|
871
|
+
CDN,
|
|
872
|
+
DefaultRestOptions,
|
|
873
|
+
DefaultUserAgent,
|
|
874
|
+
DiscordAPIError,
|
|
875
|
+
HTTPError,
|
|
876
|
+
REST,
|
|
877
|
+
RESTEvents,
|
|
878
|
+
RateLimitError,
|
|
879
|
+
RequestManager,
|
|
880
|
+
RequestMethod
|
|
881
|
+
};
|
|
8
882
|
//# sourceMappingURL=index.mjs.map
|