@discordjs/rest 1.2.0-dev.1661213496-2ecb862.0 → 1.2.0-dev.1662250232-d08a57c.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 (65) hide show
  1. package/dist/index.d.ts +839 -9
  2. package/dist/index.js +1009 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +965 -9
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +14 -21
  7. package/dist/index.cjs +0 -31
  8. package/dist/index.cjs.map +0 -1
  9. package/dist/index.d.ts.map +0 -1
  10. package/dist/lib/CDN.cjs +0 -87
  11. package/dist/lib/CDN.cjs.map +0 -1
  12. package/dist/lib/CDN.d.ts +0 -199
  13. package/dist/lib/CDN.d.ts.map +0 -1
  14. package/dist/lib/CDN.mjs +0 -83
  15. package/dist/lib/CDN.mjs.map +0 -1
  16. package/dist/lib/REST.cjs +0 -61
  17. package/dist/lib/REST.cjs.map +0 -1
  18. package/dist/lib/REST.d.ts +0 -279
  19. package/dist/lib/REST.d.ts.map +0 -1
  20. package/dist/lib/REST.mjs +0 -57
  21. package/dist/lib/REST.mjs.map +0 -1
  22. package/dist/lib/RequestManager.cjs +0 -223
  23. package/dist/lib/RequestManager.cjs.map +0 -1
  24. package/dist/lib/RequestManager.d.ts +0 -232
  25. package/dist/lib/RequestManager.d.ts.map +0 -1
  26. package/dist/lib/RequestManager.mjs +0 -218
  27. package/dist/lib/RequestManager.mjs.map +0 -1
  28. package/dist/lib/errors/DiscordAPIError.cjs +0 -55
  29. package/dist/lib/errors/DiscordAPIError.cjs.map +0 -1
  30. package/dist/lib/errors/DiscordAPIError.d.ts +0 -53
  31. package/dist/lib/errors/DiscordAPIError.d.ts.map +0 -1
  32. package/dist/lib/errors/DiscordAPIError.mjs +0 -51
  33. package/dist/lib/errors/DiscordAPIError.mjs.map +0 -1
  34. package/dist/lib/errors/HTTPError.cjs +0 -17
  35. package/dist/lib/errors/HTTPError.cjs.map +0 -1
  36. package/dist/lib/errors/HTTPError.d.ts +0 -21
  37. package/dist/lib/errors/HTTPError.d.ts.map +0 -1
  38. package/dist/lib/errors/HTTPError.mjs +0 -13
  39. package/dist/lib/errors/HTTPError.mjs.map +0 -1
  40. package/dist/lib/errors/RateLimitError.cjs +0 -23
  41. package/dist/lib/errors/RateLimitError.cjs.map +0 -1
  42. package/dist/lib/errors/RateLimitError.d.ts +0 -17
  43. package/dist/lib/errors/RateLimitError.d.ts.map +0 -1
  44. package/dist/lib/errors/RateLimitError.mjs +0 -19
  45. package/dist/lib/errors/RateLimitError.mjs.map +0 -1
  46. package/dist/lib/handlers/IHandler.d.ts +0 -23
  47. package/dist/lib/handlers/IHandler.d.ts.map +0 -1
  48. package/dist/lib/handlers/SequentialHandler.cjs +0 -305
  49. package/dist/lib/handlers/SequentialHandler.cjs.map +0 -1
  50. package/dist/lib/handlers/SequentialHandler.d.ts +0 -83
  51. package/dist/lib/handlers/SequentialHandler.d.ts.map +0 -1
  52. package/dist/lib/handlers/SequentialHandler.mjs +0 -301
  53. package/dist/lib/handlers/SequentialHandler.mjs.map +0 -1
  54. package/dist/lib/utils/constants.cjs +0 -49
  55. package/dist/lib/utils/constants.cjs.map +0 -1
  56. package/dist/lib/utils/constants.d.ts +0 -21
  57. package/dist/lib/utils/constants.d.ts.map +0 -1
  58. package/dist/lib/utils/constants.mjs +0 -49
  59. package/dist/lib/utils/constants.mjs.map +0 -1
  60. package/dist/lib/utils/utils.cjs +0 -111
  61. package/dist/lib/utils/utils.cjs.map +0 -1
  62. package/dist/lib/utils/utils.d.ts +0 -32
  63. package/dist/lib/utils/utils.d.ts.map +0 -1
  64. package/dist/lib/utils/utils.mjs +0 -103
  65. package/dist/lib/utils/utils.mjs.map +0 -1
@@ -1,279 +0,0 @@
1
- /// <reference types="node" />
2
- import { EventEmitter } from 'node:events';
3
- import type { Collection } from '@discordjs/collection';
4
- import type { request, Dispatcher } from 'undici';
5
- import { CDN } from './CDN';
6
- import { HandlerRequestData, InternalRequest, RequestData, RequestManager, RouteLike } from './RequestManager';
7
- import type { HashData } from './RequestManager';
8
- import type { IHandler } from './handlers/IHandler';
9
- /**
10
- * Options to be passed when creating the REST instance
11
- */
12
- export interface RESTOptions {
13
- /**
14
- * The agent to set globally
15
- */
16
- agent: Dispatcher;
17
- /**
18
- * The base api path, without version
19
- * @defaultValue `'https://discord.com/api'`
20
- */
21
- api: string;
22
- /**
23
- * The authorization prefix to use for requests, useful if you want to use
24
- * bearer tokens
25
- *
26
- * @defaultValue `'Bot'`
27
- */
28
- authPrefix: 'Bot' | 'Bearer';
29
- /**
30
- * The cdn path
31
- *
32
- * @defaultValue 'https://cdn.discordapp.com'
33
- */
34
- cdn: string;
35
- /**
36
- * Additional headers to send for all API requests
37
- *
38
- * @defaultValue `{}`
39
- */
40
- headers: Record<string, string>;
41
- /**
42
- * The number of invalid REST requests (those that return 401, 403, or 429) in a 10 minute window between emitted warnings (0 for no warnings).
43
- * That is, if set to 500, warnings will be emitted at invalid request number 500, 1000, 1500, and so on.
44
- *
45
- * @defaultValue `0`
46
- */
47
- invalidRequestWarningInterval: number;
48
- /**
49
- * How many requests to allow sending per second (Infinity for unlimited, 50 for the standard global limit used by Discord)
50
- *
51
- * @defaultValue `50`
52
- */
53
- globalRequestsPerSecond: number;
54
- /**
55
- * The extra offset to add to rate limits in milliseconds
56
- *
57
- * @defaultValue `50`
58
- */
59
- offset: number;
60
- /**
61
- * Determines how rate limiting and pre-emptive throttling should be handled.
62
- * When an array of strings, each element is treated as a prefix for the request route
63
- * (e.g. `/channels` to match any route starting with `/channels` such as `/channels/:id/messages`)
64
- * for which to throw {@link RateLimitError}s. All other request routes will be queued normally
65
- *
66
- * @defaultValue `null`
67
- */
68
- rejectOnRateLimit: string[] | RateLimitQueueFilter | null;
69
- /**
70
- * The number of retries for errors with the 500 code, or errors
71
- * that timeout
72
- *
73
- * @defaultValue `3`
74
- */
75
- retries: number;
76
- /**
77
- * The time to wait in milliseconds before a request is aborted
78
- *
79
- * @defaultValue `15_000`
80
- */
81
- timeout: number;
82
- /**
83
- * Extra information to add to the user agent
84
- *
85
- * @defaultValue `Node.js ${process.version}`
86
- */
87
- userAgentAppendix: string;
88
- /**
89
- * The version of the API to use
90
- *
91
- * @defaultValue `'10'`
92
- */
93
- version: string;
94
- /**
95
- * The amount of time in milliseconds that passes between each hash sweep. (defaults to 4h)
96
- *
97
- * @defaultValue `14_400_000`
98
- */
99
- hashSweepInterval: number;
100
- /**
101
- * The maximum amount of time a hash can exist in milliseconds without being hit with a request (defaults to 24h)
102
- *
103
- * @defaultValue `86_400_000`
104
- */
105
- hashLifetime: number;
106
- /**
107
- * The amount of time in milliseconds that passes between each hash sweep. (defaults to 1h)
108
- *
109
- * @defaultValue `3_600_000`
110
- */
111
- handlerSweepInterval: number;
112
- }
113
- /**
114
- * Data emitted on `RESTEvents.RateLimited`
115
- */
116
- export interface RateLimitData {
117
- /**
118
- * The time, in milliseconds, until the request-lock is reset
119
- */
120
- timeToReset: number;
121
- /**
122
- * The amount of requests we can perform before locking requests
123
- */
124
- limit: number;
125
- /**
126
- * The HTTP method being performed
127
- */
128
- method: string;
129
- /**
130
- * The bucket hash for this request
131
- */
132
- hash: string;
133
- /**
134
- * The full URL for this request
135
- */
136
- url: string;
137
- /**
138
- * The route being hit in this request
139
- */
140
- route: string;
141
- /**
142
- * The major parameter of the route
143
- *
144
- * For example, in `/channels/x`, this will be `x`.
145
- * If there is no major parameter (e.g: `/bot/gateway`) this will be `global`.
146
- */
147
- majorParameter: string;
148
- /**
149
- * Whether the rate limit that was reached was the global limit
150
- */
151
- global: boolean;
152
- }
153
- /**
154
- * A function that determines whether the rate limit hit should throw an Error
155
- */
156
- export declare type RateLimitQueueFilter = (rateLimitData: RateLimitData) => boolean | Promise<boolean>;
157
- export interface APIRequest {
158
- /**
159
- * The HTTP method used in this request
160
- */
161
- method: string;
162
- /**
163
- * The full path used to make the request
164
- */
165
- path: RouteLike;
166
- /**
167
- * The API route identifying the ratelimit for this request
168
- */
169
- route: string;
170
- /**
171
- * Additional HTTP options for this request
172
- */
173
- options: RequestOptions;
174
- /**
175
- * The data that was used to form the body of this request
176
- */
177
- data: HandlerRequestData;
178
- /**
179
- * The number of times this request has been attempted
180
- */
181
- retries: number;
182
- }
183
- export interface InvalidRequestWarningData {
184
- /**
185
- * Number of invalid requests that have been made in the window
186
- */
187
- count: number;
188
- /**
189
- * Time in milliseconds remaining before the count resets
190
- */
191
- remainingTime: number;
192
- }
193
- export interface RestEvents {
194
- invalidRequestWarning: [invalidRequestInfo: InvalidRequestWarningData];
195
- restDebug: [info: string];
196
- rateLimited: [rateLimitInfo: RateLimitData];
197
- response: [request: APIRequest, response: Dispatcher.ResponseData];
198
- newListener: [name: string, listener: (...args: any) => void];
199
- removeListener: [name: string, listener: (...args: any) => void];
200
- hashSweep: [sweptHashes: Collection<string, HashData>];
201
- handlerSweep: [sweptHandlers: Collection<string, IHandler>];
202
- }
203
- export interface REST {
204
- 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);
205
- 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);
206
- emit: (<K extends keyof RestEvents>(event: K, ...args: RestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, ...args: any[]) => boolean);
207
- 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);
208
- removeAllListeners: (<K extends keyof RestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof RestEvents>) => this);
209
- }
210
- export declare type RequestOptions = Exclude<Parameters<typeof request>[1], undefined>;
211
- export declare class REST extends EventEmitter {
212
- readonly cdn: CDN;
213
- readonly requestManager: RequestManager;
214
- constructor(options?: Partial<RESTOptions>);
215
- /**
216
- * Gets the agent set for this instance
217
- */
218
- getAgent(): Dispatcher | null;
219
- /**
220
- * Sets the default agent to use for requests performed by this instance
221
- *
222
- * @param agent - Sets the agent to use
223
- */
224
- setAgent(agent: Dispatcher): this;
225
- /**
226
- * Sets the authorization token that should be used for requests
227
- *
228
- * @param token - The authorization token to use
229
- */
230
- setToken(token: string): this;
231
- /**
232
- * Runs a get request from the api
233
- *
234
- * @param fullRoute - The full route to query
235
- * @param options - Optional request options
236
- */
237
- get(fullRoute: RouteLike, options?: RequestData): Promise<unknown>;
238
- /**
239
- * Runs a delete request from the api
240
- *
241
- * @param fullRoute - The full route to query
242
- * @param options - Optional request options
243
- */
244
- delete(fullRoute: RouteLike, options?: RequestData): Promise<unknown>;
245
- /**
246
- * Runs a post request from the api
247
- *
248
- * @param fullRoute - The full route to query
249
- * @param options - Optional request options
250
- */
251
- post(fullRoute: RouteLike, options?: RequestData): Promise<unknown>;
252
- /**
253
- * Runs a put request from the api
254
- *
255
- * @param fullRoute - The full route to query
256
- * @param options - Optional request options
257
- */
258
- put(fullRoute: RouteLike, options?: RequestData): Promise<unknown>;
259
- /**
260
- * Runs a patch request from the api
261
- *
262
- * @param fullRoute - The full route to query
263
- * @param options - Optional request options
264
- */
265
- patch(fullRoute: RouteLike, options?: RequestData): Promise<unknown>;
266
- /**
267
- * Runs a request from the api
268
- *
269
- * @param options - Request options
270
- */
271
- request(options: InternalRequest): Promise<unknown>;
272
- /**
273
- * Runs a request from the API, yielding the raw Response object
274
- *
275
- * @param options - Request options
276
- */
277
- raw(options: InternalRequest): Promise<Dispatcher.ResponseData>;
278
- }
279
- //# sourceMappingURL=REST.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"REST.d.ts","sourceRoot":"","sources":["../../src/lib/REST.ts"],"names":[],"mappings":"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"}
package/dist/lib/REST.mjs DELETED
@@ -1,57 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import { CDN } from './CDN.mjs';
3
- import { RequestManager, RequestMethod } from './RequestManager.mjs';
4
- import { DefaultRestOptions, RESTEvents } from './utils/constants.mjs';
5
- import { parseResponse } from './utils/utils.mjs';
6
-
7
- class REST extends EventEmitter {
8
- constructor(options = {}) {
9
- super();
10
- this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn);
11
- 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));
12
- this.on("newListener", (name, listener) => {
13
- if (name === RESTEvents.Response)
14
- this.requestManager.on(name, listener);
15
- });
16
- this.on("removeListener", (name, listener) => {
17
- if (name === RESTEvents.Response)
18
- this.requestManager.off(name, listener);
19
- });
20
- }
21
- getAgent() {
22
- return this.requestManager.agent;
23
- }
24
- setAgent(agent) {
25
- this.requestManager.setAgent(agent);
26
- return this;
27
- }
28
- setToken(token) {
29
- this.requestManager.setToken(token);
30
- return this;
31
- }
32
- get(fullRoute, options = {}) {
33
- return this.request({ ...options, fullRoute, method: RequestMethod.Get });
34
- }
35
- delete(fullRoute, options = {}) {
36
- return this.request({ ...options, fullRoute, method: RequestMethod.Delete });
37
- }
38
- post(fullRoute, options = {}) {
39
- return this.request({ ...options, fullRoute, method: RequestMethod.Post });
40
- }
41
- put(fullRoute, options = {}) {
42
- return this.request({ ...options, fullRoute, method: RequestMethod.Put });
43
- }
44
- patch(fullRoute, options = {}) {
45
- return this.request({ ...options, fullRoute, method: RequestMethod.Patch });
46
- }
47
- async request(options) {
48
- const response = await this.raw(options);
49
- return parseResponse(response);
50
- }
51
- raw(options) {
52
- return this.requestManager.queueRequest(options);
53
- }
54
- }
55
-
56
- export { REST };
57
- //# sourceMappingURL=REST.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"REST.mjs","sources":["../../src/lib/REST.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { Collection } from '@discordjs/collection';\nimport type { request, Dispatcher } from 'undici';\nimport { CDN } from './CDN';\nimport {\n\tHandlerRequestData,\n\tInternalRequest,\n\tRequestData,\n\tRequestManager,\n\tRequestMethod,\n\tRouteLike,\n} from './RequestManager';\nimport type { HashData } from './RequestManager';\nimport type { IHandler } from './handlers/IHandler';\nimport { DefaultRestOptions, RESTEvents } from './utils/constants';\nimport { parseResponse } from './utils/utils';\n\n/**\n * Options to be passed when creating the REST instance\n */\nexport interface RESTOptions {\n\t/**\n\t * The agent to set globally\n\t */\n\tagent: Dispatcher;\n\t/**\n\t * The base api path, without version\n\t * @defaultValue `'https://discord.com/api'`\n\t */\n\tapi: string;\n\t/**\n\t * The authorization prefix to use for requests, useful if you want to use\n\t * bearer tokens\n\t *\n\t * @defaultValue `'Bot'`\n\t */\n\tauthPrefix: 'Bot' | 'Bearer';\n\t/**\n\t * The cdn path\n\t *\n\t * @defaultValue 'https://cdn.discordapp.com'\n\t */\n\tcdn: string;\n\t/**\n\t * Additional headers to send for all API requests\n\t *\n\t * @defaultValue `{}`\n\t */\n\theaders: Record<string, string>;\n\t/**\n\t * The number of invalid REST requests (those that return 401, 403, or 429) in a 10 minute window between emitted warnings (0 for no warnings).\n\t * That is, if set to 500, warnings will be emitted at invalid request number 500, 1000, 1500, and so on.\n\t *\n\t * @defaultValue `0`\n\t */\n\tinvalidRequestWarningInterval: number;\n\t/**\n\t * How many requests to allow sending per second (Infinity for unlimited, 50 for the standard global limit used by Discord)\n\t *\n\t * @defaultValue `50`\n\t */\n\tglobalRequestsPerSecond: number;\n\t/**\n\t * The extra offset to add to rate limits in milliseconds\n\t *\n\t * @defaultValue `50`\n\t */\n\toffset: number;\n\t/**\n\t * Determines how rate limiting and pre-emptive throttling should be handled.\n\t * When an array of strings, each element is treated as a prefix for the request route\n\t * (e.g. `/channels` to match any route starting with `/channels` such as `/channels/:id/messages`)\n\t * for which to throw {@link RateLimitError}s. All other request routes will be queued normally\n\t *\n\t * @defaultValue `null`\n\t */\n\trejectOnRateLimit: string[] | RateLimitQueueFilter | null;\n\t/**\n\t * The number of retries for errors with the 500 code, or errors\n\t * that timeout\n\t *\n\t * @defaultValue `3`\n\t */\n\tretries: number;\n\t/**\n\t * The time to wait in milliseconds before a request is aborted\n\t *\n\t * @defaultValue `15_000`\n\t */\n\ttimeout: number;\n\t/**\n\t * Extra information to add to the user agent\n\t *\n\t * @defaultValue `Node.js ${process.version}`\n\t */\n\tuserAgentAppendix: string;\n\t/**\n\t * The version of the API to use\n\t *\n\t * @defaultValue `'10'`\n\t */\n\tversion: string;\n\t/**\n\t * The amount of time in milliseconds that passes between each hash sweep. (defaults to 4h)\n\t *\n\t * @defaultValue `14_400_000`\n\t */\n\thashSweepInterval: number;\n\t/**\n\t * The maximum amount of time a hash can exist in milliseconds without being hit with a request (defaults to 24h)\n\t *\n\t * @defaultValue `86_400_000`\n\t */\n\thashLifetime: number;\n\t/**\n\t * The amount of time in milliseconds that passes between each hash sweep. (defaults to 1h)\n\t *\n\t * @defaultValue `3_600_000`\n\t */\n\thandlerSweepInterval: number;\n}\n\n/**\n * Data emitted on `RESTEvents.RateLimited`\n */\nexport interface RateLimitData {\n\t/**\n\t * The time, in milliseconds, until the request-lock is reset\n\t */\n\ttimeToReset: number;\n\t/**\n\t * The amount of requests we can perform before locking requests\n\t */\n\tlimit: number;\n\t/**\n\t * The HTTP method being performed\n\t */\n\tmethod: string;\n\t/**\n\t * The bucket hash for this request\n\t */\n\thash: string;\n\t/**\n\t * The full URL for this request\n\t */\n\turl: string;\n\t/**\n\t * The route being hit in this request\n\t */\n\troute: string;\n\t/**\n\t * The major parameter of the route\n\t *\n\t * For example, in `/channels/x`, this will be `x`.\n\t * If there is no major parameter (e.g: `/bot/gateway`) this will be `global`.\n\t */\n\tmajorParameter: string;\n\t/**\n\t * Whether the rate limit that was reached was the global limit\n\t */\n\tglobal: boolean;\n}\n\n/**\n * A function that determines whether the rate limit hit should throw an Error\n */\nexport type RateLimitQueueFilter = (rateLimitData: RateLimitData) => boolean | Promise<boolean>;\n\nexport interface APIRequest {\n\t/**\n\t * The HTTP method used in this request\n\t */\n\tmethod: string;\n\t/**\n\t * The full path used to make the request\n\t */\n\tpath: RouteLike;\n\t/**\n\t * The API route identifying the ratelimit for this request\n\t */\n\troute: string;\n\t/**\n\t * Additional HTTP options for this request\n\t */\n\toptions: RequestOptions;\n\t/**\n\t * The data that was used to form the body of this request\n\t */\n\tdata: HandlerRequestData;\n\t/**\n\t * The number of times this request has been attempted\n\t */\n\tretries: number;\n}\n\nexport interface InvalidRequestWarningData {\n\t/**\n\t * Number of invalid requests that have been made in the window\n\t */\n\tcount: number;\n\t/**\n\t * Time in milliseconds remaining before the count resets\n\t */\n\tremainingTime: number;\n}\n\nexport interface RestEvents {\n\tinvalidRequestWarning: [invalidRequestInfo: InvalidRequestWarningData];\n\trestDebug: [info: string];\n\trateLimited: [rateLimitInfo: RateLimitData];\n\tresponse: [request: APIRequest, response: Dispatcher.ResponseData];\n\tnewListener: [name: string, listener: (...args: any) => void];\n\tremoveListener: [name: string, listener: (...args: any) => void];\n\thashSweep: [sweptHashes: Collection<string, HashData>];\n\thandlerSweep: [sweptHandlers: Collection<string, IHandler>];\n}\n\nexport interface REST {\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\nexport type RequestOptions = Exclude<Parameters<typeof request>[1], undefined>;\n\nexport class REST extends EventEmitter {\n\tpublic readonly cdn: CDN;\n\tpublic readonly requestManager: RequestManager;\n\n\tpublic constructor(options: Partial<RESTOptions> = {}) {\n\t\tsuper();\n\t\tthis.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn);\n\t\tthis.requestManager = new RequestManager(options)\n\t\t\t.on(RESTEvents.Debug, this.emit.bind(this, RESTEvents.Debug))\n\t\t\t.on(RESTEvents.RateLimited, this.emit.bind(this, RESTEvents.RateLimited))\n\t\t\t.on(RESTEvents.InvalidRequestWarning, this.emit.bind(this, RESTEvents.InvalidRequestWarning))\n\t\t\t.on(RESTEvents.HashSweep, this.emit.bind(this, RESTEvents.HashSweep));\n\n\t\tthis.on('newListener', (name, listener) => {\n\t\t\tif (name === RESTEvents.Response) this.requestManager.on(name, listener);\n\t\t});\n\t\tthis.on('removeListener', (name, listener) => {\n\t\t\tif (name === RESTEvents.Response) this.requestManager.off(name, listener);\n\t\t});\n\t}\n\n\t/**\n\t * Gets the agent set for this instance\n\t */\n\tpublic getAgent() {\n\t\treturn this.requestManager.agent;\n\t}\n\n\t/**\n\t * Sets the default agent to use for requests performed by this instance\n\t *\n\t * @param agent - Sets the agent to use\n\t */\n\tpublic setAgent(agent: Dispatcher) {\n\t\tthis.requestManager.setAgent(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.requestManager.setToken(token);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Runs a get request from the api\n\t *\n\t * @param fullRoute - The full route to query\n\t * @param options - Optional request options\n\t */\n\tpublic get(fullRoute: RouteLike, options: RequestData = {}) {\n\t\treturn this.request({ ...options, fullRoute, method: RequestMethod.Get });\n\t}\n\n\t/**\n\t * Runs a delete request from the api\n\t *\n\t * @param fullRoute - The full route to query\n\t * @param options - Optional request options\n\t */\n\tpublic delete(fullRoute: RouteLike, options: RequestData = {}) {\n\t\treturn this.request({ ...options, fullRoute, method: RequestMethod.Delete });\n\t}\n\n\t/**\n\t * Runs a post request from the api\n\t *\n\t * @param fullRoute - The full route to query\n\t * @param options - Optional request options\n\t */\n\tpublic post(fullRoute: RouteLike, options: RequestData = {}) {\n\t\treturn this.request({ ...options, fullRoute, method: RequestMethod.Post });\n\t}\n\n\t/**\n\t * Runs a put request from the api\n\t *\n\t * @param fullRoute - The full route to query\n\t * @param options - Optional request options\n\t */\n\tpublic put(fullRoute: RouteLike, options: RequestData = {}) {\n\t\treturn this.request({ ...options, fullRoute, method: RequestMethod.Put });\n\t}\n\n\t/**\n\t * Runs a patch request from the api\n\t *\n\t * @param fullRoute - The full route to query\n\t * @param options - Optional request options\n\t */\n\tpublic patch(fullRoute: RouteLike, options: RequestData = {}) {\n\t\treturn this.request({ ...options, fullRoute, method: RequestMethod.Patch });\n\t}\n\n\t/**\n\t * Runs a request from the api\n\t *\n\t * @param options - Request options\n\t */\n\tpublic async request(options: InternalRequest) {\n\t\tconst response = await this.raw(options);\n\t\treturn parseResponse(response);\n\t}\n\n\t/**\n\t * Runs a request from the API, yielding the raw Response object\n\t *\n\t * @param options - Request options\n\t */\n\tpublic raw(options: InternalRequest) {\n\t\treturn this.requestManager.queueRequest(options);\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -1,223 +0,0 @@
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
@@ -1 +0,0 @@
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 * @defaultValue `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 * @defaultValue `'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 * @defaultValue `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 * @internal\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 * @internal\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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"}