@discordjs/rest 1.0.0 → 1.0.1-dev.1658362255-96b62b6.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.
Files changed (66) hide show
  1. package/README.md +15 -12
  2. package/dist/index.cjs +31 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +9 -827
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.mjs +9 -985
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/lib/CDN.cjs +87 -0
  9. package/dist/lib/CDN.cjs.map +1 -0
  10. package/dist/lib/CDN.d.ts +199 -0
  11. package/dist/lib/CDN.d.ts.map +1 -0
  12. package/dist/lib/CDN.mjs +83 -0
  13. package/dist/lib/CDN.mjs.map +1 -0
  14. package/dist/lib/REST.cjs +61 -0
  15. package/dist/lib/REST.cjs.map +1 -0
  16. package/dist/lib/REST.d.ts +279 -0
  17. package/dist/lib/REST.d.ts.map +1 -0
  18. package/dist/lib/REST.mjs +57 -0
  19. package/dist/lib/REST.mjs.map +1 -0
  20. package/dist/lib/RequestManager.cjs +223 -0
  21. package/dist/lib/RequestManager.cjs.map +1 -0
  22. package/dist/lib/RequestManager.d.ts +232 -0
  23. package/dist/lib/RequestManager.d.ts.map +1 -0
  24. package/dist/lib/RequestManager.mjs +218 -0
  25. package/dist/lib/RequestManager.mjs.map +1 -0
  26. package/dist/lib/errors/DiscordAPIError.cjs +55 -0
  27. package/dist/lib/errors/DiscordAPIError.cjs.map +1 -0
  28. package/dist/lib/errors/DiscordAPIError.d.ts +53 -0
  29. package/dist/lib/errors/DiscordAPIError.d.ts.map +1 -0
  30. package/dist/lib/errors/DiscordAPIError.mjs +51 -0
  31. package/dist/lib/errors/DiscordAPIError.mjs.map +1 -0
  32. package/dist/lib/errors/HTTPError.cjs +17 -0
  33. package/dist/lib/errors/HTTPError.cjs.map +1 -0
  34. package/dist/lib/errors/HTTPError.d.ts +21 -0
  35. package/dist/lib/errors/HTTPError.d.ts.map +1 -0
  36. package/dist/lib/errors/HTTPError.mjs +13 -0
  37. package/dist/lib/errors/HTTPError.mjs.map +1 -0
  38. package/dist/lib/errors/RateLimitError.cjs +23 -0
  39. package/dist/lib/errors/RateLimitError.cjs.map +1 -0
  40. package/dist/lib/errors/RateLimitError.d.ts +17 -0
  41. package/dist/lib/errors/RateLimitError.d.ts.map +1 -0
  42. package/dist/lib/errors/RateLimitError.mjs +19 -0
  43. package/dist/lib/errors/RateLimitError.mjs.map +1 -0
  44. package/dist/lib/handlers/IHandler.d.ts +9 -0
  45. package/dist/lib/handlers/IHandler.d.ts.map +1 -0
  46. package/dist/lib/handlers/SequentialHandler.cjs +299 -0
  47. package/dist/lib/handlers/SequentialHandler.cjs.map +1 -0
  48. package/dist/lib/handlers/SequentialHandler.d.ts +88 -0
  49. package/dist/lib/handlers/SequentialHandler.d.ts.map +1 -0
  50. package/dist/lib/handlers/SequentialHandler.mjs +295 -0
  51. package/dist/lib/handlers/SequentialHandler.mjs.map +1 -0
  52. package/dist/lib/utils/constants.cjs +49 -0
  53. package/dist/lib/utils/constants.cjs.map +1 -0
  54. package/dist/lib/utils/constants.d.ts +21 -0
  55. package/dist/lib/utils/constants.d.ts.map +1 -0
  56. package/dist/lib/utils/constants.mjs +49 -0
  57. package/dist/lib/utils/constants.mjs.map +1 -0
  58. package/dist/lib/utils/utils.cjs +111 -0
  59. package/dist/lib/utils/utils.cjs.map +1 -0
  60. package/dist/lib/utils/utils.d.ts +32 -0
  61. package/dist/lib/utils/utils.d.ts.map +1 -0
  62. package/dist/lib/utils/utils.mjs +103 -0
  63. package/dist/lib/utils/utils.mjs.map +1 -0
  64. package/package.json +13 -10
  65. package/dist/index.js +0 -1026
  66. package/dist/index.js.map +0 -1
@@ -0,0 +1,223 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const node_buffer = require('node:buffer');
6
+ const node_events = require('node:events');
7
+ const collection = require('@discordjs/collection');
8
+ const snowflake = require('@sapphire/snowflake');
9
+ const undici = require('undici');
10
+ const SequentialHandler = require('./handlers/SequentialHandler.cjs');
11
+ const constants = require('./utils/constants.cjs');
12
+ const utils = require('./utils/utils.cjs');
13
+
14
+ var __accessCheck = (obj, member, msg) => {
15
+ if (!member.has(obj))
16
+ throw TypeError("Cannot " + msg);
17
+ };
18
+ var __privateGet = (obj, member, getter) => {
19
+ __accessCheck(obj, member, "read from private field");
20
+ return getter ? getter.call(obj) : member.get(obj);
21
+ };
22
+ var __privateAdd = (obj, member, value) => {
23
+ if (member.has(obj))
24
+ throw TypeError("Cannot add the same private member more than once");
25
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
26
+ };
27
+ var __privateSet = (obj, member, value, setter) => {
28
+ __accessCheck(obj, member, "write to private field");
29
+ setter ? setter.call(obj, value) : member.set(obj, value);
30
+ return value;
31
+ };
32
+ var _token;
33
+ const getFileType = () => {
34
+ let cached;
35
+ return cached ?? (cached = import('file-type'));
36
+ };
37
+ var RequestMethod = /* @__PURE__ */ ((RequestMethod2) => {
38
+ RequestMethod2["Delete"] = "DELETE";
39
+ RequestMethod2["Get"] = "GET";
40
+ RequestMethod2["Patch"] = "PATCH";
41
+ RequestMethod2["Post"] = "POST";
42
+ RequestMethod2["Put"] = "PUT";
43
+ return RequestMethod2;
44
+ })(RequestMethod || {});
45
+ const _RequestManager = class extends node_events.EventEmitter {
46
+ constructor(options) {
47
+ super();
48
+ this.agent = null;
49
+ this.globalDelay = null;
50
+ this.globalReset = -1;
51
+ this.hashes = new collection.Collection();
52
+ this.handlers = new collection.Collection();
53
+ __privateAdd(this, _token, null);
54
+ this.options = { ...constants.DefaultRestOptions, ...options };
55
+ this.options.offset = Math.max(0, this.options.offset);
56
+ this.globalRemaining = this.options.globalRequestsPerSecond;
57
+ this.agent = options.agent ?? null;
58
+ this.setupSweepers();
59
+ }
60
+ setupSweepers() {
61
+ const validateMaxInterval = (interval) => {
62
+ if (interval > 144e5) {
63
+ throw new Error("Cannot set an interval greater than 4 hours");
64
+ }
65
+ };
66
+ if (this.options.hashSweepInterval !== 0 && this.options.hashSweepInterval !== Infinity) {
67
+ validateMaxInterval(this.options.hashSweepInterval);
68
+ this.hashTimer = setInterval(() => {
69
+ const sweptHashes = new collection.Collection();
70
+ const currentDate = Date.now();
71
+ this.hashes.sweep((v, k) => {
72
+ if (v.lastAccess === -1)
73
+ return false;
74
+ const shouldSweep = Math.floor(currentDate - v.lastAccess) > this.options.hashLifetime;
75
+ if (shouldSweep) {
76
+ sweptHashes.set(k, v);
77
+ }
78
+ this.emit(constants.RESTEvents.Debug, `Hash ${v.value} for ${k} swept due to lifetime being exceeded`);
79
+ return shouldSweep;
80
+ });
81
+ this.emit(constants.RESTEvents.HashSweep, sweptHashes);
82
+ }, this.options.hashSweepInterval).unref();
83
+ }
84
+ if (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Infinity) {
85
+ validateMaxInterval(this.options.handlerSweepInterval);
86
+ this.handlerTimer = setInterval(() => {
87
+ const sweptHandlers = new collection.Collection();
88
+ this.handlers.sweep((v, k) => {
89
+ const { inactive } = v;
90
+ if (inactive) {
91
+ sweptHandlers.set(k, v);
92
+ }
93
+ this.emit(constants.RESTEvents.Debug, `Handler ${v.id} for ${k} swept due to being inactive`);
94
+ return inactive;
95
+ });
96
+ this.emit(constants.RESTEvents.HandlerSweep, sweptHandlers);
97
+ }, this.options.handlerSweepInterval).unref();
98
+ }
99
+ }
100
+ setAgent(agent) {
101
+ this.agent = agent;
102
+ return this;
103
+ }
104
+ setToken(token) {
105
+ __privateSet(this, _token, token);
106
+ return this;
107
+ }
108
+ async queueRequest(request) {
109
+ const routeId = _RequestManager.generateRouteData(request.fullRoute, request.method);
110
+ const hash = this.hashes.get(`${request.method}:${routeId.bucketRoute}`) ?? {
111
+ value: `Global(${request.method}:${routeId.bucketRoute})`,
112
+ lastAccess: -1
113
+ };
114
+ const handler = this.handlers.get(`${hash.value}:${routeId.majorParameter}`) ?? this.createHandler(hash.value, routeId.majorParameter);
115
+ const { url, fetchOptions } = await this.resolveRequest(request);
116
+ return handler.queueRequest(routeId, url, fetchOptions, {
117
+ body: request.body,
118
+ files: request.files,
119
+ auth: request.auth !== false
120
+ });
121
+ }
122
+ createHandler(hash, majorParameter) {
123
+ const queue = new SequentialHandler.SequentialHandler(this, hash, majorParameter);
124
+ this.handlers.set(queue.id, queue);
125
+ return queue;
126
+ }
127
+ async resolveRequest(request) {
128
+ const { options } = this;
129
+ let query = "";
130
+ if (request.query) {
131
+ const resolvedQuery = request.query.toString();
132
+ if (resolvedQuery !== "") {
133
+ query = `?${resolvedQuery}`;
134
+ }
135
+ }
136
+ const headers = {
137
+ ...this.options.headers,
138
+ "User-Agent": `${constants.DefaultUserAgent} ${options.userAgentAppendix}`.trim()
139
+ };
140
+ if (request.auth !== false) {
141
+ if (!__privateGet(this, _token)) {
142
+ throw new Error("Expected token to be set for this request, but none was present");
143
+ }
144
+ headers.Authorization = `${request.authPrefix ?? this.options.authPrefix} ${__privateGet(this, _token)}`;
145
+ }
146
+ if (request.reason?.length) {
147
+ headers["X-Audit-Log-Reason"] = encodeURIComponent(request.reason);
148
+ }
149
+ const url = `${options.api}${request.versioned === false ? "" : `/v${options.version}`}${request.fullRoute}${query}`;
150
+ let finalBody;
151
+ let additionalHeaders = {};
152
+ if (request.files?.length) {
153
+ const formData = new undici.FormData();
154
+ for (const [index, file] of request.files.entries()) {
155
+ const fileKey = file.key ?? `files[${index}]`;
156
+ if (Buffer.isBuffer(file.data)) {
157
+ const { fileTypeFromBuffer } = await getFileType();
158
+ const contentType = file.contentType ?? (await fileTypeFromBuffer(file.data))?.mime;
159
+ formData.append(fileKey, new node_buffer.Blob([file.data], { type: contentType }), file.name);
160
+ } else {
161
+ formData.append(fileKey, new node_buffer.Blob([`${file.data}`], { type: file.contentType }), file.name);
162
+ }
163
+ }
164
+ if (request.body != null) {
165
+ if (request.appendToFormData) {
166
+ for (const [key, value] of Object.entries(request.body)) {
167
+ formData.append(key, value);
168
+ }
169
+ } else {
170
+ formData.append("payload_json", JSON.stringify(request.body));
171
+ }
172
+ }
173
+ finalBody = formData;
174
+ } else if (request.body != null) {
175
+ if (request.passThroughBody) {
176
+ finalBody = request.body;
177
+ } else {
178
+ finalBody = JSON.stringify(request.body);
179
+ additionalHeaders = { "Content-Type": "application/json" };
180
+ }
181
+ }
182
+ finalBody = await utils.resolveBody(finalBody);
183
+ const fetchOptions = {
184
+ headers: { ...request.headers ?? {}, ...additionalHeaders, ...headers },
185
+ method: request.method.toUpperCase()
186
+ };
187
+ if (finalBody !== void 0) {
188
+ fetchOptions.body = finalBody;
189
+ }
190
+ fetchOptions.dispatcher = request.dispatcher ?? this.agent ?? void 0;
191
+ return { url, fetchOptions };
192
+ }
193
+ clearHashSweeper() {
194
+ clearInterval(this.hashTimer);
195
+ }
196
+ clearHandlerSweeper() {
197
+ clearInterval(this.handlerTimer);
198
+ }
199
+ static generateRouteData(endpoint, method) {
200
+ const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(endpoint);
201
+ const majorId = majorIdMatch?.[1] ?? "global";
202
+ const baseRoute = endpoint.replace(/\d{16,19}/g, ":id").replace(/\/reactions\/(.*)/, "/reactions/:reaction");
203
+ let exceptions = "";
204
+ if (method === "DELETE" /* Delete */ && baseRoute === "/channels/:id/messages/:id") {
205
+ const id = /\d{16,19}$/.exec(endpoint)[0];
206
+ const timestamp = snowflake.DiscordSnowflake.timestampFrom(id);
207
+ if (Date.now() - timestamp > 1e3 * 60 * 60 * 24 * 14) {
208
+ exceptions += "/Delete Old Message";
209
+ }
210
+ }
211
+ return {
212
+ majorParameter: majorId,
213
+ bucketRoute: baseRoute + exceptions,
214
+ original: endpoint
215
+ };
216
+ }
217
+ };
218
+ let RequestManager = _RequestManager;
219
+ _token = new WeakMap();
220
+
221
+ exports.RequestManager = RequestManager;
222
+ exports.RequestMethod = RequestMethod;
223
+ //# sourceMappingURL=RequestManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestManager.cjs","sources":["../../src/lib/RequestManager.ts"],"sourcesContent":["import { Blob } from 'node:buffer';\nimport { EventEmitter } from 'node:events';\nimport { Collection } from '@discordjs/collection';\nimport { DiscordSnowflake } from '@sapphire/snowflake';\nimport { FormData, type RequestInit, type BodyInit, type Dispatcher, Agent } from 'undici';\nimport type { RESTOptions, RestEvents, RequestOptions } from './REST';\nimport type { IHandler } from './handlers/IHandler';\nimport { SequentialHandler } from './handlers/SequentialHandler';\nimport { DefaultRestOptions, DefaultUserAgent, RESTEvents } from './utils/constants';\nimport { resolveBody } from './utils/utils';\n\n// Make this a lazy dynamic import as file-type is a pure ESM package\nconst getFileType = (): Promise<typeof import('file-type')> => {\n\tlet cached: Promise<typeof import('file-type')>;\n\treturn (cached ??= import('file-type'));\n};\n\n/**\n * Represents a file to be added to the request\n */\nexport interface RawFile {\n\t/**\n\t * The name of the file\n\t */\n\tname: string;\n\t/**\n\t * An explicit key to use for key of the formdata field for this file.\n\t * When not provided, the index of the file in the files array is used in the form `files[${index}]`.\n\t * If you wish to alter the placeholder snowflake, you must provide this property in the same form (`files[${placeholder}]`)\n\t */\n\tkey?: string;\n\t/**\n\t * The actual data for the file\n\t */\n\tdata: string | number | boolean | Buffer;\n\t/**\n\t * Content-Type of the file\n\t */\n\tcontentType?: string;\n}\n\n/**\n * Represents possible data to be given to an endpoint\n */\nexport interface RequestData {\n\t/**\n\t * Whether to append JSON data to form data instead of `payload_json` when sending files\n\t */\n\tappendToFormData?: boolean;\n\t/**\n\t * If this request needs the `Authorization` header\n\t *\n\t * @default true\n\t */\n\tauth?: boolean;\n\t/**\n\t * The authorization prefix to use for this request, useful if you use this with bearer tokens\n\t *\n\t * @default 'Bot'\n\t */\n\tauthPrefix?: 'Bot' | 'Bearer';\n\t/**\n\t * The body to send to this request.\n\t * If providing as BodyInit, set `passThroughBody: true`\n\t */\n\tbody?: BodyInit | unknown;\n\t/**\n\t * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} to use for the request.\n\t */\n\tdispatcher?: Agent;\n\t/**\n\t * Files to be attached to this request\n\t */\n\tfiles?: RawFile[] | undefined;\n\t/**\n\t * Additional headers to add to this request\n\t */\n\theaders?: Record<string, string>;\n\t/**\n\t * Whether to pass-through the body property directly to `fetch()`.\n\t * <warn>This only applies when files is NOT present</warn>\n\t */\n\tpassThroughBody?: boolean;\n\t/**\n\t * Query string parameters to append to the called endpoint\n\t */\n\tquery?: URLSearchParams;\n\t/**\n\t * Reason to show in the audit logs\n\t */\n\treason?: string;\n\t/**\n\t * If this request should be versioned\n\t *\n\t * @default true\n\t */\n\tversioned?: boolean;\n}\n\n/**\n * Possible headers for an API call\n */\nexport interface RequestHeaders {\n\tAuthorization?: string;\n\t'User-Agent': string;\n\t'X-Audit-Log-Reason'?: string;\n}\n\n/**\n * Possible API methods to be used when doing requests\n */\nexport const enum RequestMethod {\n\tDelete = 'DELETE',\n\tGet = 'GET',\n\tPatch = 'PATCH',\n\tPost = 'POST',\n\tPut = 'PUT',\n}\n\nexport type RouteLike = `/${string}`;\n\n/**\n * Internal request options\n *\n * @internal\n */\nexport interface InternalRequest extends RequestData {\n\tmethod: RequestMethod;\n\tfullRoute: RouteLike;\n}\n\nexport type HandlerRequestData = Pick<InternalRequest, 'files' | 'body' | 'auth'>;\n\n/**\n * Parsed route data for an endpoint\n *\n * @internal\n */\nexport interface RouteData {\n\tmajorParameter: string;\n\tbucketRoute: string;\n\toriginal: RouteLike;\n}\n\n/**\n * Represents a hash and its associated fields\n *\n * @internal\n */\nexport interface HashData {\n\tvalue: string;\n\tlastAccess: number;\n}\n\nexport interface RequestManager {\n\ton: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) &\n\t\t(<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);\n\n\tonce: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) &\n\t\t(<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);\n\n\temit: (<K extends keyof RestEvents>(event: K, ...args: RestEvents[K]) => boolean) &\n\t\t(<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, ...args: any[]) => boolean);\n\n\toff: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) &\n\t\t(<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);\n\n\tremoveAllListeners: (<K extends keyof RestEvents>(event?: K) => this) &\n\t\t(<S extends string | symbol>(event?: Exclude<S, keyof RestEvents>) => this);\n}\n\n/**\n * Represents the class that manages handlers for endpoints\n */\nexport class RequestManager extends EventEmitter {\n\t/**\n\t * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} for all requests\n\t * performed by this manager.\n\t */\n\tpublic agent: Dispatcher | null = null;\n\t/**\n\t * The number of requests remaining in the global bucket\n\t */\n\tpublic globalRemaining: number;\n\n\t/**\n\t * The promise used to wait out the global rate limit\n\t */\n\tpublic globalDelay: Promise<void> | null = null;\n\n\t/**\n\t * The timestamp at which the global bucket resets\n\t */\n\tpublic globalReset = -1;\n\n\t/**\n\t * API bucket hashes that are cached from provided routes\n\t */\n\tpublic readonly hashes = new Collection<string, HashData>();\n\n\t/**\n\t * Request handlers created from the bucket hash and the major parameters\n\t */\n\tpublic readonly handlers = new Collection<string, IHandler>();\n\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#token: string | null = null;\n\n\tprivate hashTimer!: NodeJS.Timer;\n\tprivate handlerTimer!: NodeJS.Timer;\n\n\tpublic readonly options: RESTOptions;\n\n\tpublic constructor(options: Partial<RESTOptions>) {\n\t\tsuper();\n\t\tthis.options = { ...DefaultRestOptions, ...options };\n\t\tthis.options.offset = Math.max(0, this.options.offset);\n\t\tthis.globalRemaining = this.options.globalRequestsPerSecond;\n\t\tthis.agent = options.agent ?? null;\n\n\t\t// Start sweepers\n\t\tthis.setupSweepers();\n\t}\n\n\tprivate setupSweepers() {\n\t\tconst validateMaxInterval = (interval: number) => {\n\t\t\tif (interval > 14_400_000) {\n\t\t\t\tthrow new Error('Cannot set an interval greater than 4 hours');\n\t\t\t}\n\t\t};\n\n\t\tif (this.options.hashSweepInterval !== 0 && this.options.hashSweepInterval !== Infinity) {\n\t\t\tvalidateMaxInterval(this.options.hashSweepInterval);\n\t\t\tthis.hashTimer = setInterval(() => {\n\t\t\t\tconst sweptHashes = new Collection<string, HashData>();\n\t\t\t\tconst currentDate = Date.now();\n\n\t\t\t\t// Begin sweeping hash based on lifetimes\n\t\t\t\tthis.hashes.sweep((v, k) => {\n\t\t\t\t\t// `-1` indicates a global hash\n\t\t\t\t\tif (v.lastAccess === -1) return false;\n\n\t\t\t\t\t// Check if lifetime has been exceeded\n\t\t\t\t\tconst shouldSweep = Math.floor(currentDate - v.lastAccess) > this.options.hashLifetime;\n\n\t\t\t\t\t// Add hash to collection of swept hashes\n\t\t\t\t\tif (shouldSweep) {\n\t\t\t\t\t\t// Add to swept hashes\n\t\t\t\t\t\tsweptHashes.set(k, v);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Emit debug information\n\t\t\t\t\tthis.emit(RESTEvents.Debug, `Hash ${v.value} for ${k} swept due to lifetime being exceeded`);\n\n\t\t\t\t\treturn shouldSweep;\n\t\t\t\t});\n\n\t\t\t\t// Fire event\n\t\t\t\tthis.emit(RESTEvents.HashSweep, sweptHashes);\n\t\t\t}, this.options.hashSweepInterval).unref();\n\t\t}\n\n\t\tif (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Infinity) {\n\t\t\tvalidateMaxInterval(this.options.handlerSweepInterval);\n\t\t\tthis.handlerTimer = setInterval(() => {\n\t\t\t\tconst sweptHandlers = new Collection<string, IHandler>();\n\n\t\t\t\t// Begin sweeping handlers based on activity\n\t\t\t\tthis.handlers.sweep((v, k) => {\n\t\t\t\t\tconst { inactive } = v;\n\n\t\t\t\t\t// Collect inactive handlers\n\t\t\t\t\tif (inactive) {\n\t\t\t\t\t\tsweptHandlers.set(k, v);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.emit(RESTEvents.Debug, `Handler ${v.id} for ${k} swept due to being inactive`);\n\t\t\t\t\treturn inactive;\n\t\t\t\t});\n\n\t\t\t\t// Fire event\n\t\t\t\tthis.emit(RESTEvents.HandlerSweep, sweptHandlers);\n\t\t\t}, this.options.handlerSweepInterval).unref();\n\t\t}\n\t}\n\n\t/**\n\t * Sets the default agent to use for requests performed by this manager\n\t *\n\t * @param agent - The agent to use\n\t */\n\tpublic setAgent(agent: Dispatcher) {\n\t\tthis.agent = agent;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the authorization token that should be used for requests\n\t *\n\t * @param token - The authorization token to use\n\t */\n\tpublic setToken(token: string) {\n\t\tthis.#token = token;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Queues a request to be sent\n\t *\n\t * @param request - All the information needed to make a request\n\t *\n\t * @returns The response from the api request\n\t */\n\tpublic async queueRequest(request: InternalRequest): Promise<Dispatcher.ResponseData> {\n\t\t// Generalize the endpoint to its route data\n\t\tconst routeId = RequestManager.generateRouteData(request.fullRoute, request.method);\n\t\t// Get the bucket hash for the generic route, or point to a global route otherwise\n\t\tconst hash = this.hashes.get(`${request.method}:${routeId.bucketRoute}`) ?? {\n\t\t\tvalue: `Global(${request.method}:${routeId.bucketRoute})`,\n\t\t\tlastAccess: -1,\n\t\t};\n\n\t\t// Get the request handler for the obtained hash, with its major parameter\n\t\tconst handler =\n\t\t\tthis.handlers.get(`${hash.value}:${routeId.majorParameter}`) ??\n\t\t\tthis.createHandler(hash.value, routeId.majorParameter);\n\n\t\t// Resolve the request into usable fetch options\n\t\tconst { url, fetchOptions } = await this.resolveRequest(request);\n\n\t\t// Queue the request\n\t\treturn handler.queueRequest(routeId, url, fetchOptions, {\n\t\t\tbody: request.body,\n\t\t\tfiles: request.files,\n\t\t\tauth: request.auth !== false,\n\t\t});\n\t}\n\n\t/**\n\t * Creates a new rate limit handler from a hash, based on the hash and the major parameter\n\t *\n\t * @param hash - The hash for the route\n\t * @param majorParameter - The major parameter for this handler\n\t *\n\t * @private\n\t */\n\tprivate createHandler(hash: string, majorParameter: string) {\n\t\t// Create the async request queue to handle requests\n\t\tconst queue = new SequentialHandler(this, hash, majorParameter);\n\t\t// Save the queue based on its id\n\t\tthis.handlers.set(queue.id, queue);\n\n\t\treturn queue;\n\t}\n\n\t/**\n\t * Formats the request data to a usable format for fetch\n\t *\n\t * @param request - The request data\n\t */\n\tprivate async resolveRequest(request: InternalRequest): Promise<{ url: string; fetchOptions: RequestOptions }> {\n\t\tconst { options } = this;\n\n\t\tlet query = '';\n\n\t\t// If a query option is passed, use it\n\t\tif (request.query) {\n\t\t\tconst resolvedQuery = request.query.toString();\n\t\t\tif (resolvedQuery !== '') {\n\t\t\t\tquery = `?${resolvedQuery}`;\n\t\t\t}\n\t\t}\n\n\t\t// Create the required headers\n\t\tconst headers: RequestHeaders = {\n\t\t\t...this.options.headers,\n\t\t\t'User-Agent': `${DefaultUserAgent} ${options.userAgentAppendix}`.trim(),\n\t\t};\n\n\t\t// If this request requires authorization (allowing non-\"authorized\" requests for webhooks)\n\t\tif (request.auth !== false) {\n\t\t\t// If we haven't received a token, throw an error\n\t\t\tif (!this.#token) {\n\t\t\t\tthrow new Error('Expected token to be set for this request, but none was present');\n\t\t\t}\n\n\t\t\theaders.Authorization = `${request.authPrefix ?? this.options.authPrefix} ${this.#token}`;\n\t\t}\n\n\t\t// If a reason was set, set it's appropriate header\n\t\tif (request.reason?.length) {\n\t\t\theaders['X-Audit-Log-Reason'] = encodeURIComponent(request.reason);\n\t\t}\n\n\t\t// Format the full request URL (api base, optional version, endpoint, optional querystring)\n\t\tconst url = `${options.api}${request.versioned === false ? '' : `/v${options.version}`}${\n\t\t\trequest.fullRoute\n\t\t}${query}`;\n\n\t\tlet finalBody: RequestInit['body'];\n\t\tlet additionalHeaders: Record<string, string> = {};\n\n\t\tif (request.files?.length) {\n\t\t\tconst formData = new FormData();\n\n\t\t\t// Attach all files to the request\n\t\t\tfor (const [index, file] of request.files.entries()) {\n\t\t\t\tconst fileKey = file.key ?? `files[${index}]`;\n\n\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/FormData/append#parameters\n\t\t\t\t// FormData.append only accepts a string or Blob.\n\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#parameters\n\t\t\t\t// The Blob constructor accepts TypedArray/ArrayBuffer, strings, and Blobs.\n\t\t\t\tif (Buffer.isBuffer(file.data)) {\n\t\t\t\t\t// Try to infer the content type from the buffer if one isn't passed\n\t\t\t\t\tconst { fileTypeFromBuffer } = await getFileType();\n\t\t\t\t\tconst contentType = file.contentType ?? (await fileTypeFromBuffer(file.data))?.mime;\n\t\t\t\t\tformData.append(fileKey, new Blob([file.data], { type: contentType }), file.name);\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n\t\t\t\t\tformData.append(fileKey, new Blob([`${file.data}`], { type: file.contentType }), file.name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If a JSON body was added as well, attach it to the form data, using payload_json unless otherwise specified\n\t\t\t// eslint-disable-next-line no-eq-null\n\t\t\tif (request.body != null) {\n\t\t\t\tif (request.appendToFormData) {\n\t\t\t\t\tfor (const [key, value] of Object.entries(request.body as Record<string, unknown>)) {\n\t\t\t\t\t\tformData.append(key, value);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tformData.append('payload_json', JSON.stringify(request.body));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the final body to the form data\n\t\t\tfinalBody = formData;\n\n\t\t\t// eslint-disable-next-line no-eq-null\n\t\t} else if (request.body != null) {\n\t\t\tif (request.passThroughBody) {\n\t\t\t\tfinalBody = request.body as BodyInit;\n\t\t\t} else {\n\t\t\t\t// Stringify the JSON data\n\t\t\t\tfinalBody = JSON.stringify(request.body);\n\t\t\t\t// Set the additional headers to specify the content-type\n\t\t\t\tadditionalHeaders = { 'Content-Type': 'application/json' };\n\t\t\t}\n\t\t}\n\n\t\tfinalBody = await resolveBody(finalBody);\n\n\t\tconst fetchOptions: RequestOptions = {\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\theaders: { ...(request.headers ?? {}), ...additionalHeaders, ...headers } as Record<string, string>,\n\t\t\tmethod: request.method.toUpperCase() as Dispatcher.HttpMethod,\n\t\t};\n\n\t\tif (finalBody !== undefined) {\n\t\t\tfetchOptions.body = finalBody as Exclude<RequestOptions['body'], undefined>;\n\t\t}\n\n\t\t// Prioritize setting an agent per request, use the agent for this instance otherwise.\n\t\tfetchOptions.dispatcher = request.dispatcher ?? this.agent ?? undefined!;\n\n\t\treturn { url, fetchOptions };\n\t}\n\n\t/**\n\t * Stops the hash sweeping interval\n\t */\n\tpublic clearHashSweeper() {\n\t\tclearInterval(this.hashTimer);\n\t}\n\n\t/**\n\t * Stops the request handler sweeping interval\n\t */\n\tpublic clearHandlerSweeper() {\n\t\tclearInterval(this.handlerTimer);\n\t}\n\n\t/**\n\t * Generates route data for an endpoint:method\n\t *\n\t * @param endpoint - The raw endpoint to generalize\n\t * @param method - The HTTP method this endpoint is called without\n\t *\n\t * @private\n\t */\n\tprivate static generateRouteData(endpoint: RouteLike, method: RequestMethod): RouteData {\n\t\tconst majorIdMatch = /^\\/(?:channels|guilds|webhooks)\\/(\\d{16,19})/.exec(endpoint);\n\n\t\t// Get the major id for this route - global otherwise\n\t\tconst majorId = majorIdMatch?.[1] ?? 'global';\n\n\t\tconst baseRoute = endpoint\n\t\t\t// Strip out all ids\n\t\t\t.replace(/\\d{16,19}/g, ':id')\n\t\t\t// Strip out reaction as they fall under the same bucket\n\t\t\t.replace(/\\/reactions\\/(.*)/, '/reactions/:reaction');\n\n\t\tlet exceptions = '';\n\n\t\t// Hard-Code Old Message Deletion Exception (2 week+ old messages are a different bucket)\n\t\t// https://github.com/discord/discord-api-docs/issues/1295\n\t\tif (method === RequestMethod.Delete && baseRoute === '/channels/:id/messages/:id') {\n\t\t\tconst id = /\\d{16,19}$/.exec(endpoint)![0]!;\n\t\t\tconst timestamp = DiscordSnowflake.timestampFrom(id);\n\t\t\tif (Date.now() - timestamp > 1000 * 60 * 60 * 24 * 14) {\n\t\t\t\texceptions += '/Delete Old Message';\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmajorParameter: majorId,\n\t\t\tbucketRoute: baseRoute + exceptions,\n\t\t\toriginal: endpoint,\n\t\t};\n\t}\n}\n"],"names":["EventEmitter","Collection","DefaultRestOptions","RESTEvents","SequentialHandler","DefaultUserAgent","FormData","Blob","resolveBody","DiscordSnowflake"],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import { EventEmitter } from 'node:events';
5
+ import { Collection } from '@discordjs/collection';
6
+ import { type BodyInit, type Dispatcher, Agent } from 'undici';
7
+ import type { RESTOptions, RestEvents } from './REST';
8
+ import type { IHandler } from './handlers/IHandler';
9
+ /**
10
+ * Represents a file to be added to the request
11
+ */
12
+ export interface RawFile {
13
+ /**
14
+ * The name of the file
15
+ */
16
+ name: string;
17
+ /**
18
+ * An explicit key to use for key of the formdata field for this file.
19
+ * When not provided, the index of the file in the files array is used in the form `files[${index}]`.
20
+ * If you wish to alter the placeholder snowflake, you must provide this property in the same form (`files[${placeholder}]`)
21
+ */
22
+ key?: string;
23
+ /**
24
+ * The actual data for the file
25
+ */
26
+ data: string | number | boolean | Buffer;
27
+ /**
28
+ * Content-Type of the file
29
+ */
30
+ contentType?: string;
31
+ }
32
+ /**
33
+ * Represents possible data to be given to an endpoint
34
+ */
35
+ export interface RequestData {
36
+ /**
37
+ * Whether to append JSON data to form data instead of `payload_json` when sending files
38
+ */
39
+ appendToFormData?: boolean;
40
+ /**
41
+ * If this request needs the `Authorization` header
42
+ *
43
+ * @default true
44
+ */
45
+ auth?: boolean;
46
+ /**
47
+ * The authorization prefix to use for this request, useful if you use this with bearer tokens
48
+ *
49
+ * @default 'Bot'
50
+ */
51
+ authPrefix?: 'Bot' | 'Bearer';
52
+ /**
53
+ * The body to send to this request.
54
+ * If providing as BodyInit, set `passThroughBody: true`
55
+ */
56
+ body?: BodyInit | unknown;
57
+ /**
58
+ * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} to use for the request.
59
+ */
60
+ dispatcher?: Agent;
61
+ /**
62
+ * Files to be attached to this request
63
+ */
64
+ files?: RawFile[] | undefined;
65
+ /**
66
+ * Additional headers to add to this request
67
+ */
68
+ headers?: Record<string, string>;
69
+ /**
70
+ * Whether to pass-through the body property directly to `fetch()`.
71
+ * <warn>This only applies when files is NOT present</warn>
72
+ */
73
+ passThroughBody?: boolean;
74
+ /**
75
+ * Query string parameters to append to the called endpoint
76
+ */
77
+ query?: URLSearchParams;
78
+ /**
79
+ * Reason to show in the audit logs
80
+ */
81
+ reason?: string;
82
+ /**
83
+ * If this request should be versioned
84
+ *
85
+ * @default true
86
+ */
87
+ versioned?: boolean;
88
+ }
89
+ /**
90
+ * Possible headers for an API call
91
+ */
92
+ export interface RequestHeaders {
93
+ Authorization?: string;
94
+ 'User-Agent': string;
95
+ 'X-Audit-Log-Reason'?: string;
96
+ }
97
+ /**
98
+ * Possible API methods to be used when doing requests
99
+ */
100
+ export declare const enum RequestMethod {
101
+ Delete = "DELETE",
102
+ Get = "GET",
103
+ Patch = "PATCH",
104
+ Post = "POST",
105
+ Put = "PUT"
106
+ }
107
+ export declare type RouteLike = `/${string}`;
108
+ /**
109
+ * Internal request options
110
+ *
111
+ * @internal
112
+ */
113
+ export interface InternalRequest extends RequestData {
114
+ method: RequestMethod;
115
+ fullRoute: RouteLike;
116
+ }
117
+ export declare type HandlerRequestData = Pick<InternalRequest, 'files' | 'body' | 'auth'>;
118
+ /**
119
+ * Parsed route data for an endpoint
120
+ *
121
+ * @internal
122
+ */
123
+ export interface RouteData {
124
+ majorParameter: string;
125
+ bucketRoute: string;
126
+ original: RouteLike;
127
+ }
128
+ /**
129
+ * Represents a hash and its associated fields
130
+ *
131
+ * @internal
132
+ */
133
+ export interface HashData {
134
+ value: string;
135
+ lastAccess: number;
136
+ }
137
+ export interface RequestManager {
138
+ on: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);
139
+ once: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);
140
+ emit: (<K extends keyof RestEvents>(event: K, ...args: RestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, ...args: any[]) => boolean);
141
+ off: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this);
142
+ removeAllListeners: (<K extends keyof RestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof RestEvents>) => this);
143
+ }
144
+ /**
145
+ * Represents the class that manages handlers for endpoints
146
+ */
147
+ export declare class RequestManager extends EventEmitter {
148
+ #private;
149
+ /**
150
+ * The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} for all requests
151
+ * performed by this manager.
152
+ */
153
+ agent: Dispatcher | null;
154
+ /**
155
+ * The number of requests remaining in the global bucket
156
+ */
157
+ globalRemaining: number;
158
+ /**
159
+ * The promise used to wait out the global rate limit
160
+ */
161
+ globalDelay: Promise<void> | null;
162
+ /**
163
+ * The timestamp at which the global bucket resets
164
+ */
165
+ globalReset: number;
166
+ /**
167
+ * API bucket hashes that are cached from provided routes
168
+ */
169
+ readonly hashes: Collection<string, HashData>;
170
+ /**
171
+ * Request handlers created from the bucket hash and the major parameters
172
+ */
173
+ readonly handlers: Collection<string, IHandler>;
174
+ private hashTimer;
175
+ private handlerTimer;
176
+ readonly options: RESTOptions;
177
+ constructor(options: Partial<RESTOptions>);
178
+ private setupSweepers;
179
+ /**
180
+ * Sets the default agent to use for requests performed by this manager
181
+ *
182
+ * @param agent - The agent to use
183
+ */
184
+ setAgent(agent: Dispatcher): this;
185
+ /**
186
+ * Sets the authorization token that should be used for requests
187
+ *
188
+ * @param token - The authorization token to use
189
+ */
190
+ setToken(token: string): this;
191
+ /**
192
+ * Queues a request to be sent
193
+ *
194
+ * @param request - All the information needed to make a request
195
+ *
196
+ * @returns The response from the api request
197
+ */
198
+ queueRequest(request: InternalRequest): Promise<Dispatcher.ResponseData>;
199
+ /**
200
+ * Creates a new rate limit handler from a hash, based on the hash and the major parameter
201
+ *
202
+ * @param hash - The hash for the route
203
+ * @param majorParameter - The major parameter for this handler
204
+ *
205
+ * @private
206
+ */
207
+ private createHandler;
208
+ /**
209
+ * Formats the request data to a usable format for fetch
210
+ *
211
+ * @param request - The request data
212
+ */
213
+ private resolveRequest;
214
+ /**
215
+ * Stops the hash sweeping interval
216
+ */
217
+ clearHashSweeper(): void;
218
+ /**
219
+ * Stops the request handler sweeping interval
220
+ */
221
+ clearHandlerSweeper(): void;
222
+ /**
223
+ * Generates route data for an endpoint:method
224
+ *
225
+ * @param endpoint - The raw endpoint to generalize
226
+ * @param method - The HTTP method this endpoint is called without
227
+ *
228
+ * @private
229
+ */
230
+ private static generateRouteData;
231
+ }
232
+ //# sourceMappingURL=RequestManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestManager.d.ts","sourceRoot":"","sources":["../../src/lib/RequestManager.ts"],"names":[],"mappings":"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"}