@discordjs/rest 1.1.0-dev.1660997017-8028813.0 → 1.2.0-dev.1661213496-2ecb862.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/lib/REST.cjs.map +1 -1
- package/dist/lib/REST.d.ts +1 -1
- package/dist/lib/REST.mjs.map +1 -1
- package/dist/lib/RequestManager.cjs.map +1 -1
- package/dist/lib/RequestManager.d.ts +4 -4
- package/dist/lib/RequestManager.mjs.map +1 -1
- package/dist/lib/handlers/IHandler.d.ts +14 -0
- package/dist/lib/handlers/IHandler.d.ts.map +1 -1
- package/dist/lib/handlers/SequentialHandler.cjs.map +1 -1
- package/dist/lib/handlers/SequentialHandler.d.ts +3 -8
- package/dist/lib/handlers/SequentialHandler.d.ts.map +1 -1
- package/dist/lib/handlers/SequentialHandler.mjs.map +1 -1
- package/package.json +17 -16
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
# [@discordjs/rest@1.1.0](https://github.com/discordjs/discord.js/compare/@discordjs/rest@1.0.1...@discordjs/rest@1.1.0) - (2022-08-22)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **website:** Show `constructor` information (#8540) ([e42fd16](https://github.com/discordjs/discord.js/commit/e42fd1636973b10dd7ed6fb4280ee1a4a8f82007))
|
|
10
|
+
- **website:** Render `@defaultValue` blocks (#8527) ([8028813](https://github.com/discordjs/discord.js/commit/8028813825e7708915ea892760c1003afd60df2f))
|
|
11
|
+
- **WebSocketShard:** Support new resume url (#8480) ([bc06cc6](https://github.com/discordjs/discord.js/commit/bc06cc638d2f57ab5c600e8cdb6afc8eb2180166))
|
|
12
|
+
|
|
13
|
+
## Refactor
|
|
14
|
+
|
|
15
|
+
- Docs design (#8487) ([4ab1d09](https://github.com/discordjs/discord.js/commit/4ab1d09997a18879a9eb9bda39df6f15aa22557e))
|
|
16
|
+
|
|
5
17
|
# [@discordjs/rest@0.6.0](https://github.com/discordjs/discord.js/compare/@discordjs/rest@0.5.0...@discordjs/rest@0.6.0) - (2022-07-17)
|
|
6
18
|
|
|
7
19
|
## Documentation
|
package/dist/lib/REST.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"REST.cjs","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":["EventEmitter","CDN","DefaultRestOptions","RequestManager","RESTEvents","RequestMethod","parseResponse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"REST.cjs","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":["EventEmitter","CDN","DefaultRestOptions","RequestManager","RESTEvents","RequestMethod","parseResponse"],"mappings":"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"}
|
package/dist/lib/REST.d.ts
CHANGED
package/dist/lib/REST.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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":";;;;;;AAQO,MAAM,IAAI,SAAS,YAAY,CAAC;AACvC,EAAE,WAAW,CAAC,OAAO,GAAG,EAAE,EAAE;AAC5B,IAAI,KAAK,EAAE,CAAC;AACZ,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAC9D,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9V,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;AAC/C,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC,QAAQ;AACtC,QAAQ,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC/C,KAAK,CAAC,CAAC;AACP,IAAI,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;AAClD,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC,QAAQ;AACtC,QAAQ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAChD,KAAK,CAAC,CAAC;AACP,GAAG;AACH,EAAE,QAAQ,GAAG;AACb,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;AACrC,GAAG;AACH,EAAE,QAAQ,CAAC,KAAK,EAAE;AAClB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,IAAI,OAAO,IAAI,CAAC;AAChB,GAAG;AACH,EAAE,QAAQ,CAAC,KAAK,EAAE;AAClB,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,IAAI,OAAO,IAAI,CAAC;AAChB,GAAG;AACH,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,GAAG,EAAE,EAAE;AAC/B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC;AAC9E,GAAG;AACH,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,EAAE,EAAE;AAClC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;AACjF,GAAG;AACH,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,EAAE,EAAE;AAChC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/E,GAAG;AACH,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,GAAG,EAAE,EAAE;AAC/B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC;AAC9E,GAAG;AACH,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,EAAE,EAAE;AACjC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;AAChF,GAAG;AACH,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE;AACzB,IAAI,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC7C,IAAI,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;AACnC,GAAG;AACH,EAAE,GAAG,CAAC,OAAO,EAAE;AACf,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AACrD,GAAG;AACH;;;;"}
|
|
@@ -1 +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 * @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 * @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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"}
|
|
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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"}
|
|
@@ -55,7 +55,7 @@ export interface RequestData {
|
|
|
55
55
|
*/
|
|
56
56
|
body?: BodyInit | unknown;
|
|
57
57
|
/**
|
|
58
|
-
* The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} to use for the request.
|
|
58
|
+
* The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} to use for the request.
|
|
59
59
|
*/
|
|
60
60
|
dispatcher?: Agent;
|
|
61
61
|
/**
|
|
@@ -147,7 +147,7 @@ export interface RequestManager {
|
|
|
147
147
|
export declare class RequestManager extends EventEmitter {
|
|
148
148
|
#private;
|
|
149
149
|
/**
|
|
150
|
-
* The {@link https://undici.nodejs.org/#/docs/api/Agent Agent} for all requests
|
|
150
|
+
* The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} for all requests
|
|
151
151
|
* performed by this manager.
|
|
152
152
|
*/
|
|
153
153
|
agent: Dispatcher | null;
|
|
@@ -202,7 +202,7 @@ export declare class RequestManager extends EventEmitter {
|
|
|
202
202
|
* @param hash - The hash for the route
|
|
203
203
|
* @param majorParameter - The major parameter for this handler
|
|
204
204
|
*
|
|
205
|
-
* @
|
|
205
|
+
* @internal
|
|
206
206
|
*/
|
|
207
207
|
private createHandler;
|
|
208
208
|
/**
|
|
@@ -225,7 +225,7 @@ export declare class RequestManager extends EventEmitter {
|
|
|
225
225
|
* @param endpoint - The raw endpoint to generalize
|
|
226
226
|
* @param method - The HTTP method this endpoint is called without
|
|
227
227
|
*
|
|
228
|
-
* @
|
|
228
|
+
* @internal
|
|
229
229
|
*/
|
|
230
230
|
private static generateRouteData;
|
|
231
231
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestManager.mjs","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 * @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":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RequestManager.mjs","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":[],"mappings":"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"}
|
|
@@ -2,8 +2,22 @@ import type { Dispatcher } from 'undici';
|
|
|
2
2
|
import type { RequestOptions } from '../REST';
|
|
3
3
|
import type { HandlerRequestData, RouteData } from '../RequestManager';
|
|
4
4
|
export interface IHandler {
|
|
5
|
+
/**
|
|
6
|
+
* Queues a request to be sent
|
|
7
|
+
*
|
|
8
|
+
* @param routeId - The generalized api route with literal ids for major parameters
|
|
9
|
+
* @param url - The url to do the request on
|
|
10
|
+
* @param options - All the information needed to make a request
|
|
11
|
+
* @param requestData - Extra data from the user's request needed for errors and additional processing
|
|
12
|
+
*/
|
|
5
13
|
queueRequest: (routeId: RouteData, url: string, options: RequestOptions, requestData: HandlerRequestData) => Promise<Dispatcher.ResponseData>;
|
|
14
|
+
/**
|
|
15
|
+
* If the bucket is currently inactive (no pending requests)
|
|
16
|
+
*/
|
|
6
17
|
get inactive(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The unique id of the handler
|
|
20
|
+
*/
|
|
7
21
|
readonly id: string;
|
|
8
22
|
}
|
|
9
23
|
//# sourceMappingURL=IHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/IHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACxB,YAAY,EAAE,CACb,OAAO,EAAE,SAAS,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,kBAAkB,KAC3B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"IHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/IHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACxB;;;;;;;OAOG;IACH,YAAY,EAAE,CACb,OAAO,EAAE,SAAS,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,kBAAkB,KAC3B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IACtC;;OAEG;IAEH,IAAI,QAAQ,IAAI,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SequentialHandler.cjs","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { request, type Dispatcher } from 'undici';\nimport type { IHandler } from './IHandler';\nimport type { RateLimitData, RequestOptions } from '../REST';\nimport type { HandlerRequestData, RequestManager, RouteData } from '../RequestManager';\nimport { DiscordAPIError, DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError';\nimport { HTTPError } from '../errors/HTTPError';\nimport { RateLimitError } from '../errors/RateLimitError';\nimport { RESTEvents } from '../utils/constants';\nimport { hasSublimit, parseHeader, parseResponse } from '../utils/utils';\n\n/**\n * Invalid request limiting is done on a per-IP basis, not a per-token basis.\n * The best we can do is track invalid counts process-wide (on the theory that\n * users could have multiple bots run from one process) rather than per-bot.\n * Therefore, store these at file scope here rather than in the client's\n * RESTManager object.\n */\nlet invalidCount = 0;\nlet invalidCountResetTime: number | null = null;\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle requests for a given bucket\n */\nexport class SequentialHandler implements IHandler {\n\t/**\n\t * The unique id of the handler\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * The time this rate limit bucket will reset\n\t */\n\tprivate reset = -1;\n\n\t/**\n\t * The remaining requests that can be made before we are rate limited\n\t */\n\tprivate remaining = 1;\n\n\t/**\n\t * The total number of requests that can be made before we are rate limited\n\t */\n\tprivate limit = Infinity;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitedQueue: AsyncQueue | null = null;\n\n\t/**\n\t * A promise wrapper for when the sublimited queue is finished being processed or null when not being processed\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitPromise: { promise: Promise<void>; resolve: () => void } | null = null;\n\n\t/**\n\t * Whether the sublimit queue needs to be shifted in the finally block\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#shiftSublimit = false;\n\n\t/**\n\t * @param manager - The request manager\n\t * @param hash - The hash that this RequestHandler handles\n\t * @param majorParameter - The major parameter for this handler\n\t */\n\tpublic constructor(\n\t\tprivate readonly manager: RequestManager,\n\t\tprivate readonly hash: string,\n\t\tprivate readonly majorParameter: string,\n\t) {\n\t\tthis.id = `${hash}:${majorParameter}`;\n\t}\n\n\t/**\n\t * If the bucket is currently inactive (no pending requests)\n\t */\n\tpublic get inactive(): boolean {\n\t\treturn (\n\t\t\tthis.#asyncQueue.remaining === 0 &&\n\t\t\t(this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) &&\n\t\t\t!this.limited\n\t\t);\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by the global limit\n\t */\n\tprivate get globalLimited(): boolean {\n\t\treturn this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by its limit\n\t */\n\tprivate get localLimited(): boolean {\n\t\treturn this.remaining <= 0 && Date.now() < this.reset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited\n\t */\n\tprivate get limited(): boolean {\n\t\treturn this.globalLimited || this.localLimited;\n\t}\n\n\t/**\n\t * The time until queued requests can continue\n\t */\n\tprivate get timeToReset(): number {\n\t\treturn this.reset + this.manager.options.offset - Date.now();\n\t}\n\n\t/**\n\t * Emits a debug message\n\t *\n\t * @param message - The message to debug\n\t */\n\tprivate debug(message: string) {\n\t\tthis.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);\n\t}\n\n\t/**\n\t * Delay all requests for the specified amount of time, handling global rate limits\n\t *\n\t * @param time - The amount of time to delay all requests for\n\t */\n\tprivate async globalDelayFor(time: number): Promise<void> {\n\t\tawait sleep(time, undefined, { ref: false });\n\t\tthis.manager.globalDelay = null;\n\t}\n\n\t/*\n\t * Determines whether the request should be queued or whether a RateLimitError should be thrown\n\t */\n\tprivate async onRateLimit(rateLimitData: RateLimitData) {\n\t\tconst { options } = this.manager;\n\t\tif (!options.rejectOnRateLimit) return;\n\n\t\tconst shouldThrow =\n\t\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\t\tif (shouldThrow) {\n\t\t\tthrow new RateLimitError(rateLimitData);\n\t\t}\n\t}\n\n\t/**\n\t * Queues a request to be sent\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The url to do the request on\n\t * @param options - All the information needed to make a request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t): Promise<Dispatcher.ResponseData> {\n\t\tlet queue = this.#asyncQueue;\n\t\tlet queueType = QueueType.Standard;\n\t\t// Separate sublimited requests when already sublimited\n\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\tqueueType = QueueType.Sublimit;\n\t\t}\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait();\n\t\t// This set handles retroactively sublimiting requests\n\t\tif (queueType === QueueType.Standard) {\n\t\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\t\t/**\n\t\t\t\t * Remove the request from the standard queue, it should never be possible to get here while processing the\n\t\t\t\t * sublimit queue so there is no need to worry about shifting the wrong request\n\t\t\t\t */\n\t\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\t\tconst wait = queue.wait();\n\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\tawait wait;\n\t\t\t} else if (this.#sublimitPromise) {\n\t\t\t\t// Stall requests while the sublimit queue gets processed\n\t\t\t\tawait this.#sublimitPromise.promise;\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\t// Make the request, and return the results\n\t\t\treturn await this.runRequest(routeId, url, options, requestData);\n\t\t} finally {\n\t\t\t// Allow the next request to fire\n\t\t\tqueue.shift();\n\t\t\tif (this.#shiftSublimit) {\n\t\t\t\tthis.#shiftSublimit = false;\n\t\t\t\tthis.#sublimitedQueue?.shift();\n\t\t\t}\n\t\t\t// If this request is the last request in a sublimit\n\t\t\tif (this.#sublimitedQueue?.remaining === 0) {\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitedQueue = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The method that actually makes the request to the api, and updates info about the bucket accordingly\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The fully resolved url to make the request to\n\t * @param options - The fetch options needed to make the request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t * @param retries - The number of retries this request has already attempted (recursion)\n\t */\n\tprivate async runRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<Dispatcher.ResponseData> {\n\t\t/*\n\t\t * After calculations have been done, pre-emptively stop further requests\n\t\t * Potentially loop until this task can run if e.g. the global rate limit is hit twice\n\t\t */\n\t\twhile (this.limited) {\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\t\t\tlet delay: Promise<void>;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t\t// If this is the first task to reach the global timeout, set the global delay\n\t\t\t\tif (!this.manager.globalDelay) {\n\t\t\t\t\t// The global delay function clears the global delay state when it is resolved\n\t\t\t\t\tthis.manager.globalDelay = this.globalDelayFor(timeout);\n\t\t\t\t}\n\t\t\t\tdelay = this.manager.globalDelay;\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t};\n\t\t\t// Let library users know they have hit a rate limit\n\t\t\tthis.manager.emit(RESTEvents.RateLimited, rateLimitData);\n\t\t\t// Determine whether a RateLimitError should be thrown\n\t\t\tawait this.onRateLimit(rateLimitData);\n\t\t\t// When not erroring, emit debug for what is happening\n\t\t\tif (isGlobal) {\n\t\t\t\tthis.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);\n\t\t\t} else {\n\t\t\t\tthis.debug(`Waiting ${timeout}ms for rate limit to pass`);\n\t\t\t}\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\t\t// As the request goes out, update the global usage information\n\t\tif (!this.manager.globalReset || this.manager.globalReset < Date.now()) {\n\t\t\tthis.manager.globalReset = Date.now() + 1000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref();\n\t\tlet res: Dispatcher.ResponseData;\n\n\t\ttry {\n\t\t\tres = await request(url, { ...options, signal: controller.signal });\n\t\t} catch (error: unknown) {\n\t\t\t// Retry the specified number of times for possible timed out requests\n\t\t\tif (error instanceof Error && error.name === 'AbortError' && retries !== this.manager.options.retries) {\n\t\t\t\treturn await this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\n\t\tif (this.manager.listenerCount(RESTEvents.Response)) {\n\t\t\tthis.manager.emit(\n\t\t\t\tRESTEvents.Response,\n\t\t\t\t{\n\t\t\t\t\tmethod,\n\t\t\t\t\tpath: routeId.original,\n\t\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\t\toptions,\n\t\t\t\t\tdata: requestData,\n\t\t\t\t\tretries,\n\t\t\t\t},\n\t\t\t\t{ ...res },\n\t\t\t);\n\t\t}\n\n\t\tconst status = res.statusCode;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = parseHeader(res.headers['x-ratelimit-limit']);\n\t\tconst remaining = parseHeader(res.headers['x-ratelimit-remaining']);\n\t\tconst reset = parseHeader(res.headers['x-ratelimit-reset-after']);\n\t\tconst hash = parseHeader(res.headers['x-ratelimit-bucket']);\n\t\tconst retry = parseHeader(res.headers['retry-after']);\n\n\t\t// Update the total number of requests that can be made before the rate limit resets\n\t\tthis.limit = limit ? Number(limit) : Infinity;\n\t\t// Update the number of remaining requests that can be made before the rate limit resets\n\t\tthis.remaining = remaining ? Number(remaining) : 1;\n\t\t// Update the time when this rate limit resets (reset-after is in seconds)\n\t\tthis.reset = reset ? Number(reset) * 1000 + Date.now() + this.manager.options.offset : Date.now();\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tif (retry) retryAfter = Number(retry) * 1000 + this.manager.options.offset;\n\n\t\t// Handle buckets via the hash header retroactively\n\t\tif (hash && hash !== this.hash) {\n\t\t\t// Let library users know when rate limit buckets have been updated\n\t\t\tthis.debug(['Received bucket hash update', ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join('\\n'));\n\t\t\t// This queue will eventually be eliminated via attrition\n\t\t\tthis.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });\n\t\t} else if (hash) {\n\t\t\t// Handle the case where hash value doesn't change\n\t\t\t// Fetch the hash data from the manager\n\t\t\tconst hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);\n\n\t\t\t// When fetched, update the last access of the hash\n\t\t\tif (hashData) {\n\t\t\t\thashData.lastAccess = Date.now();\n\t\t\t}\n\t\t}\n\n\t\t// Handle retryAfter, which means we have actually hit a rate limit\n\t\tlet sublimitTimeout: number | null = null;\n\t\tif (retryAfter > 0) {\n\t\t\tif (res.headers['x-ratelimit-global'] !== undefined) {\n\t\t\t\tthis.manager.globalRemaining = 0;\n\t\t\t\tthis.manager.globalReset = Date.now() + retryAfter;\n\t\t\t} else if (!this.localLimited) {\n\t\t\t\t/*\n\t\t\t\t * This is a sublimit (e.g. 2 channel name changes/10 minutes) since the headers don't indicate a\n\t\t\t\t * route-wide rate limit. Don't update remaining or reset to avoid rate limiting the whole\n\t\t\t\t * endpoint, just set a reset time on the request itself to avoid retrying too soon.\n\t\t\t\t */\n\t\t\t\tsublimitTimeout = retryAfter;\n\t\t\t}\n\t\t}\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\t\t\tinvalidCountResetTime = Date.now() + 1000 * 60 * 10;\n\t\t\t\tinvalidCount = 0;\n\t\t\t}\n\t\t\tinvalidCount++;\n\n\t\t\tconst emitInvalid =\n\t\t\t\tthis.manager.options.invalidRequestWarningInterval > 0 &&\n\t\t\t\tinvalidCount % this.manager.options.invalidRequestWarningInterval === 0;\n\t\t\tif (emitInvalid) {\n\t\t\t\t// Let library users know periodically about invalid requests\n\t\t\t\tthis.manager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\t\t\tcount: invalidCount,\n\t\t\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (status >= 200 && status < 300) {\n\t\t\treturn res;\n\t\t} else if (status === 429) {\n\t\t\t// A rate limit was hit - this may happen if the route isn't associated with an official bucket hash yet, or when first globally rate limited\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t}\n\t\t\tawait this.onRateLimit({\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod,\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t});\n\t\t\tthis.debug(\n\t\t\t\t[\n\t\t\t\t\t'Encountered unexpected 429 rate limit',\n\t\t\t\t\t` Global : ${isGlobal.toString()}`,\n\t\t\t\t\t` Method : ${method}`,\n\t\t\t\t\t` URL : ${url}`,\n\t\t\t\t\t` Bucket : ${routeId.bucketRoute}`,\n\t\t\t\t\t` Major parameter: ${routeId.majorParameter}`,\n\t\t\t\t\t` Hash : ${this.hash}`,\n\t\t\t\t\t` Limit : ${limit}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\t\t\t// If caused by a sublimit, wait it out here so other requests on the route can be handled\n\t\t\tif (sublimitTimeout) {\n\t\t\t\t// Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will\n\t\t\t\tconst firstSublimit = !this.#sublimitedQueue;\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\tthis.#sublimitedQueue = new AsyncQueue();\n\t\t\t\t\tvoid this.#sublimitedQueue.wait();\n\t\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\t}\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout, undefined, { ref: false });\n\t\t\t\tlet resolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((res) => (resolve = res));\n\t\t\t\tthis.#sublimitPromise = { promise, resolve: resolve! };\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\t// Re-queue this request so it can be shifted by the finally\n\t\t\t\t\tawait this.#asyncQueue.wait();\n\t\t\t\t\tthis.#shiftSublimit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Since this is not a server side issue, the next request should pass, so we don't bump the retries counter\n\t\t\treturn this.runRequest(routeId, url, options, requestData, retries);\n\t\t} else if (status >= 500 && status < 600) {\n\t\t\t// Retry the specified number of times for possible server side issues\n\t\t\tif (retries !== this.manager.options.retries) {\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\t\t\t// We are out of retries, throw an error\n\t\t\tthrow new HTTPError(res.constructor.name, status, method, url, requestData);\n\t\t} else {\n\t\t\t// Handle possible malformed requests\n\t\t\tif (status >= 400 && status < 500) {\n\t\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\t\tif (status === 401 && requestData.auth) {\n\t\t\t\t\tthis.manager.setToken(null!);\n\t\t\t\t}\n\t\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\t\t// throw the API error\n\t\t\t\tthrow new DiscordAPIError(data, 'code' in data ? data.code : data.error, status, method, url, requestData);\n\t\t\t}\n\t\t\treturn res;\n\t\t}\n\t}\n}\n"],"names":["AsyncQueue","RESTEvents","sleep","RateLimitError","hasSublimit","request","parseHeader","HTTPError","parseResponse","DiscordAPIError"],"mappings":";;;;;;;;;;;;;AAAA,IAAI,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK;AAC1C,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AACtB,IAAI,MAAM,SAAS,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;AACrC,CAAC,CAAC;AACF,IAAI,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK;AAC5C,EAAE,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,yBAAyB,CAAC,CAAC;AACxD,EAAE,OAAO,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC,CAAC;AACF,IAAI,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,KAAK;AAC3C,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AACrB,IAAI,MAAM,SAAS,CAAC,mDAAmD,CAAC,CAAC;AACzE,EAAE,MAAM,YAAY,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACvE,CAAC,CAAC;AACF,IAAI,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;AACnD,EAAE,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC;AACvD,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC5D,EAAE,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AACF,IAAI,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,CAAC;AASpE,IAAI,YAAY,GAAG,CAAC,CAAC;AACrB,IAAI,qBAAqB,GAAG,IAAI,CAAC;AAM1B,MAAM,iBAAiB,CAAC;AAC/B,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE;AAC7C,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;AAC3B,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AACrB,IAAI,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;AACzC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACpB,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;AACvB,IAAI,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;AAC1B,IAAI,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,IAAIA,qBAAU,EAAE,CAAC,CAAC;AACtD,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AAC/C,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AAC/C,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;AAC9C,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;AAC1C,GAAG;AACH,EAAE,IAAI,QAAQ,GAAG;AACjB,IAAI,OAAO,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,KAAK,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AACvL,GAAG;AACH,EAAE,IAAI,aAAa,GAAG;AACtB,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AACtF,GAAG;AACH,EAAE,IAAI,YAAY,GAAG;AACrB,IAAI,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;AAC1D,GAAG;AACH,EAAE,IAAI,OAAO,GAAG;AAChB,IAAI,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC;AACnD,GAAG;AACH,EAAE,IAAI,WAAW,GAAG;AACpB,IAAI,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACjE,GAAG;AACH,EAAE,KAAK,CAAC,OAAO,EAAE;AACjB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAACC,oBAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACxE,GAAG;AACH,EAAE,MAAM,cAAc,CAAC,IAAI,EAAE;AAC7B,IAAI,MAAMC,mBAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;AACpC,GAAG;AACH,EAAE,MAAM,WAAW,CAAC,aAAa,EAAE;AACnC,IAAI,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;AACrC,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB;AAClC,MAAM,OAAO;AACb,IAAI,MAAM,WAAW,GAAG,OAAO,OAAO,CAAC,iBAAiB,KAAK,UAAU,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC1N,IAAI,IAAI,WAAW,EAAE;AACrB,MAAM,MAAM,IAAIC,6BAAc,CAAC,aAAa,CAAC,CAAC;AAC9C,KAAK;AACL,GAAG;AACH,EAAE,MAAM,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE;AACzD,IAAI,IAAI,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAChD,IAAI,IAAI,SAAS,GAAG,CAAC,gBAAgB;AACrC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAIC,iBAAW,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;AACpH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;AACnD,MAAM,SAAS,GAAG,CAAC,gBAAgB;AACnC,KAAK;AACL,IAAI,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AACvB,IAAI,IAAI,SAAS,KAAK,CAAC,iBAAiB;AACxC,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAIA,iBAAW,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;AACtH,QAAQ,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;AACrD,QAAQ,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;AAClC,QAAQ,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;AAChD,QAAQ,MAAM,IAAI,CAAC;AACnB,OAAO,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE;AACvD,QAAQ,MAAM,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,OAAO,CAAC;AAC3D,OAAO;AACP,KAAK;AACL,IAAI,IAAI;AACR,MAAM,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AACvE,KAAK,SAAS;AACd,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACpB,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE;AAC9C,QAAQ,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;AAClD,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC;AACtD,OAAO;AACP,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,SAAS,KAAK,CAAC,EAAE;AACjE,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;AACxD,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACnD,OAAO;AACP,KAAK;AACL,GAAG;AACH,EAAE,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,GAAG,CAAC,EAAE;AACpE,IAAI,OAAO,IAAI,CAAC,OAAO,EAAE;AACzB,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC;AAC1C,MAAM,IAAI,MAAM,CAAC;AACjB,MAAM,IAAI,QAAQ,CAAC;AACnB,MAAM,IAAI,KAAK,CAAC;AAChB,MAAM,IAAI,QAAQ,EAAE;AACpB,QAAQ,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAC9D,QAAQ,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACvF,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;AACvC,UAAU,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;AACnE,SAAS;AACT,QAAQ,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AACzC,OAAO,MAAM;AACb,QAAQ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;AAC5B,QAAQ,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;AACpC,QAAQ,KAAK,GAAGF,mBAAK,CAAC,QAAQ,CAAC,CAAC;AAChC,OAAO;AACP,MAAM,MAAM,aAAa,GAAG;AAC5B,QAAQ,WAAW,EAAE,QAAQ;AAC7B,QAAQ,KAAK,EAAE,MAAM;AACrB,QAAQ,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;AACvC,QAAQ,IAAI,EAAE,IAAI,CAAC,IAAI;AACvB,QAAQ,GAAG;AACX,QAAQ,KAAK,EAAE,OAAO,CAAC,WAAW;AAClC,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;AAC3C,QAAQ,MAAM,EAAE,QAAQ;AACxB,OAAO,CAAC;AACR,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAACD,oBAAU,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC/D,MAAM,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;AAC5C,MAAM,IAAI,QAAQ,EAAE;AACpB,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,iDAAiD,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AACrF,OAAO,MAAM;AACb,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC;AACnE,OAAO;AACP,MAAM,MAAM,KAAK,CAAC;AAClB,KAAK;AACL,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE;AAC5E,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC;AAClD,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAClF,KAAK;AACL,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;AACnC,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;AAC3C,IAAI,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;AAC7C,IAAI,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;AAC/F,IAAI,IAAI,GAAG,CAAC;AACZ,IAAI,IAAI;AACR,MAAM,GAAG,GAAG,MAAMI,cAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAC1E,KAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE;AAC7G,QAAQ,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;AACpF,OAAO;AACP,MAAM,MAAM,KAAK,CAAC;AAClB,KAAK,SAAS;AACd,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;AAC5B,KAAK;AACL,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,CAACJ,oBAAU,CAAC,QAAQ,CAAC,EAAE;AACzD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI;AACvB,QAAQA,oBAAU,CAAC,QAAQ;AAC3B,QAAQ;AACR,UAAU,MAAM;AAChB,UAAU,IAAI,EAAE,OAAO,CAAC,QAAQ;AAChC,UAAU,KAAK,EAAE,OAAO,CAAC,WAAW;AACpC,UAAU,OAAO;AACjB,UAAU,IAAI,EAAE,WAAW;AAC3B,UAAU,OAAO;AACjB,SAAS;AACT,QAAQ,EAAE,GAAG,GAAG,EAAE;AAClB,OAAO,CAAC;AACR,KAAK;AACL,IAAI,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC;AAClC,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC;AACvB,IAAI,MAAM,KAAK,GAAGK,iBAAW,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAChE,IAAI,MAAM,SAAS,GAAGA,iBAAW,CAAC,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC;AACxE,IAAI,MAAM,KAAK,GAAGA,iBAAW,CAAC,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC;AACtE,IAAI,MAAM,IAAI,GAAGA,iBAAW,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAChE,IAAI,MAAM,KAAK,GAAGA,iBAAW,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAC1D,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAClD,IAAI,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AACvD,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACrG,IAAI,IAAI,KAAK;AACb,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;AACrE,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;AACpC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,6BAA6B,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACpH,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC3G,KAAK,MAAM,IAAI,IAAI,EAAE;AACrB,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnF,MAAM,IAAI,QAAQ,EAAE;AACpB,QAAQ,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACzC,OAAO;AACP,KAAK;AACL,IAAI,IAAI,eAAe,GAAG,IAAI,CAAC;AAC/B,IAAI,IAAI,UAAU,GAAG,CAAC,EAAE;AACxB,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,KAAK,CAAC,EAAE;AACxD,QAAQ,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC;AACzC,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC;AAC3D,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AACrC,QAAQ,eAAe,GAAG,UAAU,CAAC;AACrC,OAAO;AACP,KAAK;AACL,IAAI,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;AAC5D,MAAM,IAAI,CAAC,qBAAqB,IAAI,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE;AACxE,QAAQ,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;AAC3D,QAAQ,YAAY,GAAG,CAAC,CAAC;AACzB,OAAO;AACP,MAAM,YAAY,EAAE,CAAC;AACrB,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,6BAA6B,GAAG,CAAC,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,6BAA6B,KAAK,CAAC,CAAC;AAC5J,MAAM,IAAI,WAAW,EAAE;AACvB,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAACL,oBAAU,CAAC,qBAAqB,EAAE;AAC5D,UAAU,KAAK,EAAE,YAAY;AAC7B,UAAU,aAAa,EAAE,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE;AAC3D,SAAS,CAAC,CAAC;AACX,OAAO;AACP,KAAK;AACL,IAAI,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE;AACvC,MAAM,OAAO,GAAG,CAAC;AACjB,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG,EAAE;AAC/B,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC;AAC1C,MAAM,IAAI,MAAM,CAAC;AACjB,MAAM,IAAI,QAAQ,CAAC;AACnB,MAAM,IAAI,QAAQ,EAAE;AACpB,QAAQ,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAC9D,QAAQ,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACvF,OAAO,MAAM;AACb,QAAQ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;AAC5B,QAAQ,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;AACpC,OAAO;AACP,MAAM,MAAM,IAAI,CAAC,WAAW,CAAC;AAC7B,QAAQ,WAAW,EAAE,QAAQ;AAC7B,QAAQ,KAAK,EAAE,MAAM;AACrB,QAAQ,MAAM;AACd,QAAQ,IAAI,EAAE,IAAI,CAAC,IAAI;AACvB,QAAQ,GAAG;AACX,QAAQ,KAAK,EAAE,OAAO,CAAC,WAAW;AAClC,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;AAC3C,QAAQ,MAAM,EAAE,QAAQ;AACxB,OAAO,CAAC,CAAC;AACT,MAAM,IAAI,CAAC,KAAK;AAChB,QAAQ;AACR,UAAU,uCAAuC;AACjD,UAAU,CAAC,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;AACrD,UAAU,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;AACxC,UAAU,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;AACrC,UAAU,CAAC,mBAAmB,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;AACrD,UAAU,CAAC,mBAAmB,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;AACxD,UAAU,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3C,UAAU,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;AACxC,UAAU,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,CAAC;AAC9C,UAAU,CAAC,mBAAmB,EAAE,eAAe,GAAG,CAAC,EAAE,eAAe,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;AACnF,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACpB,OAAO,CAAC;AACR,MAAM,IAAI,eAAe,EAAE;AAC3B,QAAQ,MAAM,aAAa,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;AACpE,QAAQ,IAAI,aAAa,EAAE;AAC3B,UAAU,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAID,qBAAU,EAAE,CAAC,CAAC;AACjE,UAAU,KAAK,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3D,UAAU,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,SAAS;AACT,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;AACxD,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACnD,QAAQ,MAAME,mBAAK,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,QAAQ,IAAI,OAAO,CAAC;AACpB,QAAQ,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC;AAC9D,QAAQ,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACnE,QAAQ,IAAI,aAAa,EAAE;AAC3B,UAAU,MAAM,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;AACvD,UAAU,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;AACnD,SAAS;AACT,OAAO;AACP,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAC1E,KAAK,MAAM,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE;AAC9C,MAAM,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE;AACpD,QAAQ,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9E,OAAO;AACP,MAAM,MAAM,IAAIK,mBAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AAClF,KAAK,MAAM;AACX,MAAM,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE;AACzC,QAAQ,IAAI,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;AAChD,UAAU,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtC,SAAS;AACT,QAAQ,MAAM,IAAI,GAAG,MAAMC,mBAAa,CAAC,GAAG,CAAC,CAAC;AAC9C,QAAQ,MAAM,IAAIC,+BAAe,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AACnH,OAAO;AACP,MAAM,OAAO,GAAG,CAAC;AACjB,KAAK;AACL,GAAG;AACH,CAAC;AACD,WAAW,GAAG,IAAI,OAAO,EAAE,CAAC;AAC5B,gBAAgB,GAAG,IAAI,OAAO,EAAE,CAAC;AACjC,gBAAgB,GAAG,IAAI,OAAO,EAAE,CAAC;AACjC,cAAc,GAAG,IAAI,OAAO,EAAE;;;;"}
|
|
1
|
+
{"version":3,"file":"SequentialHandler.cjs","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { request, type Dispatcher } from 'undici';\nimport type { IHandler } from './IHandler';\nimport type { RateLimitData, RequestOptions } from '../REST';\nimport type { HandlerRequestData, RequestManager, RouteData } from '../RequestManager';\nimport { DiscordAPIError, DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError';\nimport { HTTPError } from '../errors/HTTPError';\nimport { RateLimitError } from '../errors/RateLimitError';\nimport { RESTEvents } from '../utils/constants';\nimport { hasSublimit, parseHeader, parseResponse } from '../utils/utils';\n\n/**\n * Invalid request limiting is done on a per-IP basis, not a per-token basis.\n * The best we can do is track invalid counts process-wide (on the theory that\n * users could have multiple bots run from one process) rather than per-bot.\n * Therefore, store these at file scope here rather than in the client's\n * RESTManager object.\n */\nlet invalidCount = 0;\nlet invalidCountResetTime: number | null = null;\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle requests for a given bucket\n */\nexport class SequentialHandler implements IHandler {\n\t/**\n\t * {@inheritDoc IHandler.id}\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * The time this rate limit bucket will reset\n\t */\n\tprivate reset = -1;\n\n\t/**\n\t * The remaining requests that can be made before we are rate limited\n\t */\n\tprivate remaining = 1;\n\n\t/**\n\t * The total number of requests that can be made before we are rate limited\n\t */\n\tprivate limit = Infinity;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitedQueue: AsyncQueue | null = null;\n\n\t/**\n\t * A promise wrapper for when the sublimited queue is finished being processed or null when not being processed\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitPromise: { promise: Promise<void>; resolve: () => void } | null = null;\n\n\t/**\n\t * Whether the sublimit queue needs to be shifted in the finally block\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#shiftSublimit = false;\n\n\t/**\n\t * @param manager - The request manager\n\t * @param hash - The hash that this RequestHandler handles\n\t * @param majorParameter - The major parameter for this handler\n\t */\n\tpublic constructor(\n\t\tprivate readonly manager: RequestManager,\n\t\tprivate readonly hash: string,\n\t\tprivate readonly majorParameter: string,\n\t) {\n\t\tthis.id = `${hash}:${majorParameter}`;\n\t}\n\n\t/**\n\t * {@inheritDoc IHandler.inactive}\n\t */\n\tpublic get inactive(): boolean {\n\t\treturn (\n\t\t\tthis.#asyncQueue.remaining === 0 &&\n\t\t\t(this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) &&\n\t\t\t!this.limited\n\t\t);\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by the global limit\n\t */\n\tprivate get globalLimited(): boolean {\n\t\treturn this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by its limit\n\t */\n\tprivate get localLimited(): boolean {\n\t\treturn this.remaining <= 0 && Date.now() < this.reset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited\n\t */\n\tprivate get limited(): boolean {\n\t\treturn this.globalLimited || this.localLimited;\n\t}\n\n\t/**\n\t * The time until queued requests can continue\n\t */\n\tprivate get timeToReset(): number {\n\t\treturn this.reset + this.manager.options.offset - Date.now();\n\t}\n\n\t/**\n\t * Emits a debug message\n\t *\n\t * @param message - The message to debug\n\t */\n\tprivate debug(message: string) {\n\t\tthis.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);\n\t}\n\n\t/**\n\t * Delay all requests for the specified amount of time, handling global rate limits\n\t *\n\t * @param time - The amount of time to delay all requests for\n\t */\n\tprivate async globalDelayFor(time: number): Promise<void> {\n\t\tawait sleep(time, undefined, { ref: false });\n\t\tthis.manager.globalDelay = null;\n\t}\n\n\t/*\n\t * Determines whether the request should be queued or whether a RateLimitError should be thrown\n\t */\n\tprivate async onRateLimit(rateLimitData: RateLimitData) {\n\t\tconst { options } = this.manager;\n\t\tif (!options.rejectOnRateLimit) return;\n\n\t\tconst shouldThrow =\n\t\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\t\tif (shouldThrow) {\n\t\t\tthrow new RateLimitError(rateLimitData);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc IHandler.queueRequest}\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t): Promise<Dispatcher.ResponseData> {\n\t\tlet queue = this.#asyncQueue;\n\t\tlet queueType = QueueType.Standard;\n\t\t// Separate sublimited requests when already sublimited\n\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\tqueueType = QueueType.Sublimit;\n\t\t}\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait();\n\t\t// This set handles retroactively sublimiting requests\n\t\tif (queueType === QueueType.Standard) {\n\t\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\t\t/**\n\t\t\t\t * Remove the request from the standard queue, it should never be possible to get here while processing the\n\t\t\t\t * sublimit queue so there is no need to worry about shifting the wrong request\n\t\t\t\t */\n\t\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\t\tconst wait = queue.wait();\n\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\tawait wait;\n\t\t\t} else if (this.#sublimitPromise) {\n\t\t\t\t// Stall requests while the sublimit queue gets processed\n\t\t\t\tawait this.#sublimitPromise.promise;\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\t// Make the request, and return the results\n\t\t\treturn await this.runRequest(routeId, url, options, requestData);\n\t\t} finally {\n\t\t\t// Allow the next request to fire\n\t\t\tqueue.shift();\n\t\t\tif (this.#shiftSublimit) {\n\t\t\t\tthis.#shiftSublimit = false;\n\t\t\t\tthis.#sublimitedQueue?.shift();\n\t\t\t}\n\t\t\t// If this request is the last request in a sublimit\n\t\t\tif (this.#sublimitedQueue?.remaining === 0) {\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitedQueue = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The method that actually makes the request to the api, and updates info about the bucket accordingly\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The fully resolved url to make the request to\n\t * @param options - The fetch options needed to make the request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t * @param retries - The number of retries this request has already attempted (recursion)\n\t */\n\tprivate async runRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<Dispatcher.ResponseData> {\n\t\t/*\n\t\t * After calculations have been done, pre-emptively stop further requests\n\t\t * Potentially loop until this task can run if e.g. the global rate limit is hit twice\n\t\t */\n\t\twhile (this.limited) {\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\t\t\tlet delay: Promise<void>;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t\t// If this is the first task to reach the global timeout, set the global delay\n\t\t\t\tif (!this.manager.globalDelay) {\n\t\t\t\t\t// The global delay function clears the global delay state when it is resolved\n\t\t\t\t\tthis.manager.globalDelay = this.globalDelayFor(timeout);\n\t\t\t\t}\n\t\t\t\tdelay = this.manager.globalDelay;\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t};\n\t\t\t// Let library users know they have hit a rate limit\n\t\t\tthis.manager.emit(RESTEvents.RateLimited, rateLimitData);\n\t\t\t// Determine whether a RateLimitError should be thrown\n\t\t\tawait this.onRateLimit(rateLimitData);\n\t\t\t// When not erroring, emit debug for what is happening\n\t\t\tif (isGlobal) {\n\t\t\t\tthis.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);\n\t\t\t} else {\n\t\t\t\tthis.debug(`Waiting ${timeout}ms for rate limit to pass`);\n\t\t\t}\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\t\t// As the request goes out, update the global usage information\n\t\tif (!this.manager.globalReset || this.manager.globalReset < Date.now()) {\n\t\t\tthis.manager.globalReset = Date.now() + 1000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref();\n\t\tlet res: Dispatcher.ResponseData;\n\n\t\ttry {\n\t\t\tres = await request(url, { ...options, signal: controller.signal });\n\t\t} catch (error: unknown) {\n\t\t\t// Retry the specified number of times for possible timed out requests\n\t\t\tif (error instanceof Error && error.name === 'AbortError' && retries !== this.manager.options.retries) {\n\t\t\t\treturn await this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\n\t\tif (this.manager.listenerCount(RESTEvents.Response)) {\n\t\t\tthis.manager.emit(\n\t\t\t\tRESTEvents.Response,\n\t\t\t\t{\n\t\t\t\t\tmethod,\n\t\t\t\t\tpath: routeId.original,\n\t\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\t\toptions,\n\t\t\t\t\tdata: requestData,\n\t\t\t\t\tretries,\n\t\t\t\t},\n\t\t\t\t{ ...res },\n\t\t\t);\n\t\t}\n\n\t\tconst status = res.statusCode;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = parseHeader(res.headers['x-ratelimit-limit']);\n\t\tconst remaining = parseHeader(res.headers['x-ratelimit-remaining']);\n\t\tconst reset = parseHeader(res.headers['x-ratelimit-reset-after']);\n\t\tconst hash = parseHeader(res.headers['x-ratelimit-bucket']);\n\t\tconst retry = parseHeader(res.headers['retry-after']);\n\n\t\t// Update the total number of requests that can be made before the rate limit resets\n\t\tthis.limit = limit ? Number(limit) : Infinity;\n\t\t// Update the number of remaining requests that can be made before the rate limit resets\n\t\tthis.remaining = remaining ? Number(remaining) : 1;\n\t\t// Update the time when this rate limit resets (reset-after is in seconds)\n\t\tthis.reset = reset ? Number(reset) * 1000 + Date.now() + this.manager.options.offset : Date.now();\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tif (retry) retryAfter = Number(retry) * 1000 + this.manager.options.offset;\n\n\t\t// Handle buckets via the hash header retroactively\n\t\tif (hash && hash !== this.hash) {\n\t\t\t// Let library users know when rate limit buckets have been updated\n\t\t\tthis.debug(['Received bucket hash update', ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join('\\n'));\n\t\t\t// This queue will eventually be eliminated via attrition\n\t\t\tthis.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });\n\t\t} else if (hash) {\n\t\t\t// Handle the case where hash value doesn't change\n\t\t\t// Fetch the hash data from the manager\n\t\t\tconst hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);\n\n\t\t\t// When fetched, update the last access of the hash\n\t\t\tif (hashData) {\n\t\t\t\thashData.lastAccess = Date.now();\n\t\t\t}\n\t\t}\n\n\t\t// Handle retryAfter, which means we have actually hit a rate limit\n\t\tlet sublimitTimeout: number | null = null;\n\t\tif (retryAfter > 0) {\n\t\t\tif (res.headers['x-ratelimit-global'] !== undefined) {\n\t\t\t\tthis.manager.globalRemaining = 0;\n\t\t\t\tthis.manager.globalReset = Date.now() + retryAfter;\n\t\t\t} else if (!this.localLimited) {\n\t\t\t\t/*\n\t\t\t\t * This is a sublimit (e.g. 2 channel name changes/10 minutes) since the headers don't indicate a\n\t\t\t\t * route-wide rate limit. Don't update remaining or reset to avoid rate limiting the whole\n\t\t\t\t * endpoint, just set a reset time on the request itself to avoid retrying too soon.\n\t\t\t\t */\n\t\t\t\tsublimitTimeout = retryAfter;\n\t\t\t}\n\t\t}\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\t\t\tinvalidCountResetTime = Date.now() + 1000 * 60 * 10;\n\t\t\t\tinvalidCount = 0;\n\t\t\t}\n\t\t\tinvalidCount++;\n\n\t\t\tconst emitInvalid =\n\t\t\t\tthis.manager.options.invalidRequestWarningInterval > 0 &&\n\t\t\t\tinvalidCount % this.manager.options.invalidRequestWarningInterval === 0;\n\t\t\tif (emitInvalid) {\n\t\t\t\t// Let library users know periodically about invalid requests\n\t\t\t\tthis.manager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\t\t\tcount: invalidCount,\n\t\t\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (status >= 200 && status < 300) {\n\t\t\treturn res;\n\t\t} else if (status === 429) {\n\t\t\t// A rate limit was hit - this may happen if the route isn't associated with an official bucket hash yet, or when first globally rate limited\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t}\n\t\t\tawait this.onRateLimit({\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod,\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t});\n\t\t\tthis.debug(\n\t\t\t\t[\n\t\t\t\t\t'Encountered unexpected 429 rate limit',\n\t\t\t\t\t` Global : ${isGlobal.toString()}`,\n\t\t\t\t\t` Method : ${method}`,\n\t\t\t\t\t` URL : ${url}`,\n\t\t\t\t\t` Bucket : ${routeId.bucketRoute}`,\n\t\t\t\t\t` Major parameter: ${routeId.majorParameter}`,\n\t\t\t\t\t` Hash : ${this.hash}`,\n\t\t\t\t\t` Limit : ${limit}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\t\t\t// If caused by a sublimit, wait it out here so other requests on the route can be handled\n\t\t\tif (sublimitTimeout) {\n\t\t\t\t// Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will\n\t\t\t\tconst firstSublimit = !this.#sublimitedQueue;\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\tthis.#sublimitedQueue = new AsyncQueue();\n\t\t\t\t\tvoid this.#sublimitedQueue.wait();\n\t\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\t}\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout, undefined, { ref: false });\n\t\t\t\tlet resolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((res) => (resolve = res));\n\t\t\t\tthis.#sublimitPromise = { promise, resolve: resolve! };\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\t// Re-queue this request so it can be shifted by the finally\n\t\t\t\t\tawait this.#asyncQueue.wait();\n\t\t\t\t\tthis.#shiftSublimit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Since this is not a server side issue, the next request should pass, so we don't bump the retries counter\n\t\t\treturn this.runRequest(routeId, url, options, requestData, retries);\n\t\t} else if (status >= 500 && status < 600) {\n\t\t\t// Retry the specified number of times for possible server side issues\n\t\t\tif (retries !== this.manager.options.retries) {\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\t\t\t// We are out of retries, throw an error\n\t\t\tthrow new HTTPError(res.constructor.name, status, method, url, requestData);\n\t\t} else {\n\t\t\t// Handle possible malformed requests\n\t\t\tif (status >= 400 && status < 500) {\n\t\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\t\tif (status === 401 && requestData.auth) {\n\t\t\t\t\tthis.manager.setToken(null!);\n\t\t\t\t}\n\t\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\t\t// throw the API error\n\t\t\t\tthrow new DiscordAPIError(data, 'code' in data ? data.code : data.error, status, method, url, requestData);\n\t\t\t}\n\t\t\treturn res;\n\t\t}\n\t}\n}\n"],"names":["AsyncQueue","RESTEvents","sleep","RateLimitError","hasSublimit","request","parseHeader","HTTPError","parseResponse","DiscordAPIError"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export declare class SequentialHandler implements IHandler {
|
|
|
11
11
|
private readonly hash;
|
|
12
12
|
private readonly majorParameter;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* {@inheritDoc IHandler.id}
|
|
15
15
|
*/
|
|
16
16
|
readonly id: string;
|
|
17
17
|
/**
|
|
@@ -33,7 +33,7 @@ export declare class SequentialHandler implements IHandler {
|
|
|
33
33
|
*/
|
|
34
34
|
constructor(manager: RequestManager, hash: string, majorParameter: string);
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* {@inheritDoc IHandler.inactive}
|
|
37
37
|
*/
|
|
38
38
|
get inactive(): boolean;
|
|
39
39
|
/**
|
|
@@ -66,12 +66,7 @@ export declare class SequentialHandler implements IHandler {
|
|
|
66
66
|
private globalDelayFor;
|
|
67
67
|
private onRateLimit;
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* @param routeId - The generalized api route with literal ids for major parameters
|
|
72
|
-
* @param url - The url to do the request on
|
|
73
|
-
* @param options - All the information needed to make a request
|
|
74
|
-
* @param requestData - Extra data from the user's request needed for errors and additional processing
|
|
69
|
+
* {@inheritDoc IHandler.queueRequest}
|
|
75
70
|
*/
|
|
76
71
|
queueRequest(routeId: RouteData, url: string, options: RequestOptions, requestData: HandlerRequestData): Promise<Dispatcher.ResponseData>;
|
|
77
72
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SequentialHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAsBvF;;GAEG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;;IAmDhD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc;IApDhC;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,KAAK,CAAM;IAEnB;;OAEG;IACH,OAAO,CAAC,SAAS,CAAK;IAEtB;;OAEG;IACH,OAAO,CAAC,KAAK,CAAY;IA0BzB;;;;OAIG;gBAEe,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IAKxC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAM7B;IAED;;OAEG;IACH,OAAO,KAAK,aAAa,GAExB;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAEvB;IAED;;OAEG;IACH,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACH,OAAO,KAAK,WAAW,GAEtB;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;;OAIG;YACW,cAAc;YAQd,WAAW;IAazB
|
|
1
|
+
{"version":3,"file":"SequentialHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAsBvF;;GAEG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;;IAmDhD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc;IApDhC;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,KAAK,CAAM;IAEnB;;OAEG;IACH,OAAO,CAAC,SAAS,CAAK;IAEtB;;OAEG;IACH,OAAO,CAAC,KAAK,CAAY;IA0BzB;;;;OAIG;gBAEe,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IAKxC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAM7B;IAED;;OAEG;IACH,OAAO,KAAK,aAAa,GAExB;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAEvB;IAED;;OAEG;IACH,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACH,OAAO,KAAK,WAAW,GAEtB;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;;OAIG;YACW,cAAc;YAQd,WAAW;IAazB;;OAEG;IACU,YAAY,CACxB,OAAO,EAAE,SAAS,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,kBAAkB,GAC7B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;IA4CnC;;;;;;;;OAQG;YACW,UAAU;CA+PxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SequentialHandler.mjs","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { request, type Dispatcher } from 'undici';\nimport type { IHandler } from './IHandler';\nimport type { RateLimitData, RequestOptions } from '../REST';\nimport type { HandlerRequestData, RequestManager, RouteData } from '../RequestManager';\nimport { DiscordAPIError, DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError';\nimport { HTTPError } from '../errors/HTTPError';\nimport { RateLimitError } from '../errors/RateLimitError';\nimport { RESTEvents } from '../utils/constants';\nimport { hasSublimit, parseHeader, parseResponse } from '../utils/utils';\n\n/**\n * Invalid request limiting is done on a per-IP basis, not a per-token basis.\n * The best we can do is track invalid counts process-wide (on the theory that\n * users could have multiple bots run from one process) rather than per-bot.\n * Therefore, store these at file scope here rather than in the client's\n * RESTManager object.\n */\nlet invalidCount = 0;\nlet invalidCountResetTime: number | null = null;\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle requests for a given bucket\n */\nexport class SequentialHandler implements IHandler {\n\t/**\n\t * The unique id of the handler\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * The time this rate limit bucket will reset\n\t */\n\tprivate reset = -1;\n\n\t/**\n\t * The remaining requests that can be made before we are rate limited\n\t */\n\tprivate remaining = 1;\n\n\t/**\n\t * The total number of requests that can be made before we are rate limited\n\t */\n\tprivate limit = Infinity;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitedQueue: AsyncQueue | null = null;\n\n\t/**\n\t * A promise wrapper for when the sublimited queue is finished being processed or null when not being processed\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitPromise: { promise: Promise<void>; resolve: () => void } | null = null;\n\n\t/**\n\t * Whether the sublimit queue needs to be shifted in the finally block\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#shiftSublimit = false;\n\n\t/**\n\t * @param manager - The request manager\n\t * @param hash - The hash that this RequestHandler handles\n\t * @param majorParameter - The major parameter for this handler\n\t */\n\tpublic constructor(\n\t\tprivate readonly manager: RequestManager,\n\t\tprivate readonly hash: string,\n\t\tprivate readonly majorParameter: string,\n\t) {\n\t\tthis.id = `${hash}:${majorParameter}`;\n\t}\n\n\t/**\n\t * If the bucket is currently inactive (no pending requests)\n\t */\n\tpublic get inactive(): boolean {\n\t\treturn (\n\t\t\tthis.#asyncQueue.remaining === 0 &&\n\t\t\t(this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) &&\n\t\t\t!this.limited\n\t\t);\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by the global limit\n\t */\n\tprivate get globalLimited(): boolean {\n\t\treturn this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by its limit\n\t */\n\tprivate get localLimited(): boolean {\n\t\treturn this.remaining <= 0 && Date.now() < this.reset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited\n\t */\n\tprivate get limited(): boolean {\n\t\treturn this.globalLimited || this.localLimited;\n\t}\n\n\t/**\n\t * The time until queued requests can continue\n\t */\n\tprivate get timeToReset(): number {\n\t\treturn this.reset + this.manager.options.offset - Date.now();\n\t}\n\n\t/**\n\t * Emits a debug message\n\t *\n\t * @param message - The message to debug\n\t */\n\tprivate debug(message: string) {\n\t\tthis.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);\n\t}\n\n\t/**\n\t * Delay all requests for the specified amount of time, handling global rate limits\n\t *\n\t * @param time - The amount of time to delay all requests for\n\t */\n\tprivate async globalDelayFor(time: number): Promise<void> {\n\t\tawait sleep(time, undefined, { ref: false });\n\t\tthis.manager.globalDelay = null;\n\t}\n\n\t/*\n\t * Determines whether the request should be queued or whether a RateLimitError should be thrown\n\t */\n\tprivate async onRateLimit(rateLimitData: RateLimitData) {\n\t\tconst { options } = this.manager;\n\t\tif (!options.rejectOnRateLimit) return;\n\n\t\tconst shouldThrow =\n\t\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\t\tif (shouldThrow) {\n\t\t\tthrow new RateLimitError(rateLimitData);\n\t\t}\n\t}\n\n\t/**\n\t * Queues a request to be sent\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The url to do the request on\n\t * @param options - All the information needed to make a request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t): Promise<Dispatcher.ResponseData> {\n\t\tlet queue = this.#asyncQueue;\n\t\tlet queueType = QueueType.Standard;\n\t\t// Separate sublimited requests when already sublimited\n\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\tqueueType = QueueType.Sublimit;\n\t\t}\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait();\n\t\t// This set handles retroactively sublimiting requests\n\t\tif (queueType === QueueType.Standard) {\n\t\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\t\t/**\n\t\t\t\t * Remove the request from the standard queue, it should never be possible to get here while processing the\n\t\t\t\t * sublimit queue so there is no need to worry about shifting the wrong request\n\t\t\t\t */\n\t\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\t\tconst wait = queue.wait();\n\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\tawait wait;\n\t\t\t} else if (this.#sublimitPromise) {\n\t\t\t\t// Stall requests while the sublimit queue gets processed\n\t\t\t\tawait this.#sublimitPromise.promise;\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\t// Make the request, and return the results\n\t\t\treturn await this.runRequest(routeId, url, options, requestData);\n\t\t} finally {\n\t\t\t// Allow the next request to fire\n\t\t\tqueue.shift();\n\t\t\tif (this.#shiftSublimit) {\n\t\t\t\tthis.#shiftSublimit = false;\n\t\t\t\tthis.#sublimitedQueue?.shift();\n\t\t\t}\n\t\t\t// If this request is the last request in a sublimit\n\t\t\tif (this.#sublimitedQueue?.remaining === 0) {\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitedQueue = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The method that actually makes the request to the api, and updates info about the bucket accordingly\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The fully resolved url to make the request to\n\t * @param options - The fetch options needed to make the request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t * @param retries - The number of retries this request has already attempted (recursion)\n\t */\n\tprivate async runRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<Dispatcher.ResponseData> {\n\t\t/*\n\t\t * After calculations have been done, pre-emptively stop further requests\n\t\t * Potentially loop until this task can run if e.g. the global rate limit is hit twice\n\t\t */\n\t\twhile (this.limited) {\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\t\t\tlet delay: Promise<void>;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t\t// If this is the first task to reach the global timeout, set the global delay\n\t\t\t\tif (!this.manager.globalDelay) {\n\t\t\t\t\t// The global delay function clears the global delay state when it is resolved\n\t\t\t\t\tthis.manager.globalDelay = this.globalDelayFor(timeout);\n\t\t\t\t}\n\t\t\t\tdelay = this.manager.globalDelay;\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t};\n\t\t\t// Let library users know they have hit a rate limit\n\t\t\tthis.manager.emit(RESTEvents.RateLimited, rateLimitData);\n\t\t\t// Determine whether a RateLimitError should be thrown\n\t\t\tawait this.onRateLimit(rateLimitData);\n\t\t\t// When not erroring, emit debug for what is happening\n\t\t\tif (isGlobal) {\n\t\t\t\tthis.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);\n\t\t\t} else {\n\t\t\t\tthis.debug(`Waiting ${timeout}ms for rate limit to pass`);\n\t\t\t}\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\t\t// As the request goes out, update the global usage information\n\t\tif (!this.manager.globalReset || this.manager.globalReset < Date.now()) {\n\t\t\tthis.manager.globalReset = Date.now() + 1000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref();\n\t\tlet res: Dispatcher.ResponseData;\n\n\t\ttry {\n\t\t\tres = await request(url, { ...options, signal: controller.signal });\n\t\t} catch (error: unknown) {\n\t\t\t// Retry the specified number of times for possible timed out requests\n\t\t\tif (error instanceof Error && error.name === 'AbortError' && retries !== this.manager.options.retries) {\n\t\t\t\treturn await this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\n\t\tif (this.manager.listenerCount(RESTEvents.Response)) {\n\t\t\tthis.manager.emit(\n\t\t\t\tRESTEvents.Response,\n\t\t\t\t{\n\t\t\t\t\tmethod,\n\t\t\t\t\tpath: routeId.original,\n\t\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\t\toptions,\n\t\t\t\t\tdata: requestData,\n\t\t\t\t\tretries,\n\t\t\t\t},\n\t\t\t\t{ ...res },\n\t\t\t);\n\t\t}\n\n\t\tconst status = res.statusCode;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = parseHeader(res.headers['x-ratelimit-limit']);\n\t\tconst remaining = parseHeader(res.headers['x-ratelimit-remaining']);\n\t\tconst reset = parseHeader(res.headers['x-ratelimit-reset-after']);\n\t\tconst hash = parseHeader(res.headers['x-ratelimit-bucket']);\n\t\tconst retry = parseHeader(res.headers['retry-after']);\n\n\t\t// Update the total number of requests that can be made before the rate limit resets\n\t\tthis.limit = limit ? Number(limit) : Infinity;\n\t\t// Update the number of remaining requests that can be made before the rate limit resets\n\t\tthis.remaining = remaining ? Number(remaining) : 1;\n\t\t// Update the time when this rate limit resets (reset-after is in seconds)\n\t\tthis.reset = reset ? Number(reset) * 1000 + Date.now() + this.manager.options.offset : Date.now();\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tif (retry) retryAfter = Number(retry) * 1000 + this.manager.options.offset;\n\n\t\t// Handle buckets via the hash header retroactively\n\t\tif (hash && hash !== this.hash) {\n\t\t\t// Let library users know when rate limit buckets have been updated\n\t\t\tthis.debug(['Received bucket hash update', ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join('\\n'));\n\t\t\t// This queue will eventually be eliminated via attrition\n\t\t\tthis.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });\n\t\t} else if (hash) {\n\t\t\t// Handle the case where hash value doesn't change\n\t\t\t// Fetch the hash data from the manager\n\t\t\tconst hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);\n\n\t\t\t// When fetched, update the last access of the hash\n\t\t\tif (hashData) {\n\t\t\t\thashData.lastAccess = Date.now();\n\t\t\t}\n\t\t}\n\n\t\t// Handle retryAfter, which means we have actually hit a rate limit\n\t\tlet sublimitTimeout: number | null = null;\n\t\tif (retryAfter > 0) {\n\t\t\tif (res.headers['x-ratelimit-global'] !== undefined) {\n\t\t\t\tthis.manager.globalRemaining = 0;\n\t\t\t\tthis.manager.globalReset = Date.now() + retryAfter;\n\t\t\t} else if (!this.localLimited) {\n\t\t\t\t/*\n\t\t\t\t * This is a sublimit (e.g. 2 channel name changes/10 minutes) since the headers don't indicate a\n\t\t\t\t * route-wide rate limit. Don't update remaining or reset to avoid rate limiting the whole\n\t\t\t\t * endpoint, just set a reset time on the request itself to avoid retrying too soon.\n\t\t\t\t */\n\t\t\t\tsublimitTimeout = retryAfter;\n\t\t\t}\n\t\t}\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\t\t\tinvalidCountResetTime = Date.now() + 1000 * 60 * 10;\n\t\t\t\tinvalidCount = 0;\n\t\t\t}\n\t\t\tinvalidCount++;\n\n\t\t\tconst emitInvalid =\n\t\t\t\tthis.manager.options.invalidRequestWarningInterval > 0 &&\n\t\t\t\tinvalidCount % this.manager.options.invalidRequestWarningInterval === 0;\n\t\t\tif (emitInvalid) {\n\t\t\t\t// Let library users know periodically about invalid requests\n\t\t\t\tthis.manager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\t\t\tcount: invalidCount,\n\t\t\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (status >= 200 && status < 300) {\n\t\t\treturn res;\n\t\t} else if (status === 429) {\n\t\t\t// A rate limit was hit - this may happen if the route isn't associated with an official bucket hash yet, or when first globally rate limited\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t}\n\t\t\tawait this.onRateLimit({\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod,\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t});\n\t\t\tthis.debug(\n\t\t\t\t[\n\t\t\t\t\t'Encountered unexpected 429 rate limit',\n\t\t\t\t\t` Global : ${isGlobal.toString()}`,\n\t\t\t\t\t` Method : ${method}`,\n\t\t\t\t\t` URL : ${url}`,\n\t\t\t\t\t` Bucket : ${routeId.bucketRoute}`,\n\t\t\t\t\t` Major parameter: ${routeId.majorParameter}`,\n\t\t\t\t\t` Hash : ${this.hash}`,\n\t\t\t\t\t` Limit : ${limit}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\t\t\t// If caused by a sublimit, wait it out here so other requests on the route can be handled\n\t\t\tif (sublimitTimeout) {\n\t\t\t\t// Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will\n\t\t\t\tconst firstSublimit = !this.#sublimitedQueue;\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\tthis.#sublimitedQueue = new AsyncQueue();\n\t\t\t\t\tvoid this.#sublimitedQueue.wait();\n\t\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\t}\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout, undefined, { ref: false });\n\t\t\t\tlet resolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((res) => (resolve = res));\n\t\t\t\tthis.#sublimitPromise = { promise, resolve: resolve! };\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\t// Re-queue this request so it can be shifted by the finally\n\t\t\t\t\tawait this.#asyncQueue.wait();\n\t\t\t\t\tthis.#shiftSublimit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Since this is not a server side issue, the next request should pass, so we don't bump the retries counter\n\t\t\treturn this.runRequest(routeId, url, options, requestData, retries);\n\t\t} else if (status >= 500 && status < 600) {\n\t\t\t// Retry the specified number of times for possible server side issues\n\t\t\tif (retries !== this.manager.options.retries) {\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\t\t\t// We are out of retries, throw an error\n\t\t\tthrow new HTTPError(res.constructor.name, status, method, url, requestData);\n\t\t} else {\n\t\t\t// Handle possible malformed requests\n\t\t\tif (status >= 400 && status < 500) {\n\t\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\t\tif (status === 401 && requestData.auth) {\n\t\t\t\t\tthis.manager.setToken(null!);\n\t\t\t\t}\n\t\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\t\t// throw the API error\n\t\t\t\tthrow new DiscordAPIError(data, 'code' in data ? data.code : data.error, status, method, url, requestData);\n\t\t\t}\n\t\t\treturn res;\n\t\t}\n\t}\n}\n"],"names":["sleep"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SequentialHandler.mjs","sources":["../../../src/lib/handlers/SequentialHandler.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { request, type Dispatcher } from 'undici';\nimport type { IHandler } from './IHandler';\nimport type { RateLimitData, RequestOptions } from '../REST';\nimport type { HandlerRequestData, RequestManager, RouteData } from '../RequestManager';\nimport { DiscordAPIError, DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError';\nimport { HTTPError } from '../errors/HTTPError';\nimport { RateLimitError } from '../errors/RateLimitError';\nimport { RESTEvents } from '../utils/constants';\nimport { hasSublimit, parseHeader, parseResponse } from '../utils/utils';\n\n/**\n * Invalid request limiting is done on a per-IP basis, not a per-token basis.\n * The best we can do is track invalid counts process-wide (on the theory that\n * users could have multiple bots run from one process) rather than per-bot.\n * Therefore, store these at file scope here rather than in the client's\n * RESTManager object.\n */\nlet invalidCount = 0;\nlet invalidCountResetTime: number | null = null;\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle requests for a given bucket\n */\nexport class SequentialHandler implements IHandler {\n\t/**\n\t * {@inheritDoc IHandler.id}\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * The time this rate limit bucket will reset\n\t */\n\tprivate reset = -1;\n\n\t/**\n\t * The remaining requests that can be made before we are rate limited\n\t */\n\tprivate remaining = 1;\n\n\t/**\n\t * The total number of requests that can be made before we are rate limited\n\t */\n\tprivate limit = Infinity;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitedQueue: AsyncQueue | null = null;\n\n\t/**\n\t * A promise wrapper for when the sublimited queue is finished being processed or null when not being processed\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#sublimitPromise: { promise: Promise<void>; resolve: () => void } | null = null;\n\n\t/**\n\t * Whether the sublimit queue needs to be shifted in the finally block\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility\n\t#shiftSublimit = false;\n\n\t/**\n\t * @param manager - The request manager\n\t * @param hash - The hash that this RequestHandler handles\n\t * @param majorParameter - The major parameter for this handler\n\t */\n\tpublic constructor(\n\t\tprivate readonly manager: RequestManager,\n\t\tprivate readonly hash: string,\n\t\tprivate readonly majorParameter: string,\n\t) {\n\t\tthis.id = `${hash}:${majorParameter}`;\n\t}\n\n\t/**\n\t * {@inheritDoc IHandler.inactive}\n\t */\n\tpublic get inactive(): boolean {\n\t\treturn (\n\t\t\tthis.#asyncQueue.remaining === 0 &&\n\t\t\t(this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) &&\n\t\t\t!this.limited\n\t\t);\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by the global limit\n\t */\n\tprivate get globalLimited(): boolean {\n\t\treturn this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited by its limit\n\t */\n\tprivate get localLimited(): boolean {\n\t\treturn this.remaining <= 0 && Date.now() < this.reset;\n\t}\n\n\t/**\n\t * If the rate limit bucket is currently limited\n\t */\n\tprivate get limited(): boolean {\n\t\treturn this.globalLimited || this.localLimited;\n\t}\n\n\t/**\n\t * The time until queued requests can continue\n\t */\n\tprivate get timeToReset(): number {\n\t\treturn this.reset + this.manager.options.offset - Date.now();\n\t}\n\n\t/**\n\t * Emits a debug message\n\t *\n\t * @param message - The message to debug\n\t */\n\tprivate debug(message: string) {\n\t\tthis.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);\n\t}\n\n\t/**\n\t * Delay all requests for the specified amount of time, handling global rate limits\n\t *\n\t * @param time - The amount of time to delay all requests for\n\t */\n\tprivate async globalDelayFor(time: number): Promise<void> {\n\t\tawait sleep(time, undefined, { ref: false });\n\t\tthis.manager.globalDelay = null;\n\t}\n\n\t/*\n\t * Determines whether the request should be queued or whether a RateLimitError should be thrown\n\t */\n\tprivate async onRateLimit(rateLimitData: RateLimitData) {\n\t\tconst { options } = this.manager;\n\t\tif (!options.rejectOnRateLimit) return;\n\n\t\tconst shouldThrow =\n\t\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\t\tif (shouldThrow) {\n\t\t\tthrow new RateLimitError(rateLimitData);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc IHandler.queueRequest}\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t): Promise<Dispatcher.ResponseData> {\n\t\tlet queue = this.#asyncQueue;\n\t\tlet queueType = QueueType.Standard;\n\t\t// Separate sublimited requests when already sublimited\n\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\tqueueType = QueueType.Sublimit;\n\t\t}\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait();\n\t\t// This set handles retroactively sublimiting requests\n\t\tif (queueType === QueueType.Standard) {\n\t\t\tif (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) {\n\t\t\t\t/**\n\t\t\t\t * Remove the request from the standard queue, it should never be possible to get here while processing the\n\t\t\t\t * sublimit queue so there is no need to worry about shifting the wrong request\n\t\t\t\t */\n\t\t\t\tqueue = this.#sublimitedQueue!;\n\t\t\t\tconst wait = queue.wait();\n\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\tawait wait;\n\t\t\t} else if (this.#sublimitPromise) {\n\t\t\t\t// Stall requests while the sublimit queue gets processed\n\t\t\t\tawait this.#sublimitPromise.promise;\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\t// Make the request, and return the results\n\t\t\treturn await this.runRequest(routeId, url, options, requestData);\n\t\t} finally {\n\t\t\t// Allow the next request to fire\n\t\t\tqueue.shift();\n\t\t\tif (this.#shiftSublimit) {\n\t\t\t\tthis.#shiftSublimit = false;\n\t\t\t\tthis.#sublimitedQueue?.shift();\n\t\t\t}\n\t\t\t// If this request is the last request in a sublimit\n\t\t\tif (this.#sublimitedQueue?.remaining === 0) {\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitedQueue = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The method that actually makes the request to the api, and updates info about the bucket accordingly\n\t *\n\t * @param routeId - The generalized api route with literal ids for major parameters\n\t * @param url - The fully resolved url to make the request to\n\t * @param options - The fetch options needed to make the request\n\t * @param requestData - Extra data from the user's request needed for errors and additional processing\n\t * @param retries - The number of retries this request has already attempted (recursion)\n\t */\n\tprivate async runRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<Dispatcher.ResponseData> {\n\t\t/*\n\t\t * After calculations have been done, pre-emptively stop further requests\n\t\t * Potentially loop until this task can run if e.g. the global rate limit is hit twice\n\t\t */\n\t\twhile (this.limited) {\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\t\t\tlet delay: Promise<void>;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t\t// If this is the first task to reach the global timeout, set the global delay\n\t\t\t\tif (!this.manager.globalDelay) {\n\t\t\t\t\t// The global delay function clears the global delay state when it is resolved\n\t\t\t\t\tthis.manager.globalDelay = this.globalDelayFor(timeout);\n\t\t\t\t}\n\t\t\t\tdelay = this.manager.globalDelay;\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t};\n\t\t\t// Let library users know they have hit a rate limit\n\t\t\tthis.manager.emit(RESTEvents.RateLimited, rateLimitData);\n\t\t\t// Determine whether a RateLimitError should be thrown\n\t\t\tawait this.onRateLimit(rateLimitData);\n\t\t\t// When not erroring, emit debug for what is happening\n\t\t\tif (isGlobal) {\n\t\t\t\tthis.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);\n\t\t\t} else {\n\t\t\t\tthis.debug(`Waiting ${timeout}ms for rate limit to pass`);\n\t\t\t}\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\t\t// As the request goes out, update the global usage information\n\t\tif (!this.manager.globalReset || this.manager.globalReset < Date.now()) {\n\t\t\tthis.manager.globalReset = Date.now() + 1000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref();\n\t\tlet res: Dispatcher.ResponseData;\n\n\t\ttry {\n\t\t\tres = await request(url, { ...options, signal: controller.signal });\n\t\t} catch (error: unknown) {\n\t\t\t// Retry the specified number of times for possible timed out requests\n\t\t\tif (error instanceof Error && error.name === 'AbortError' && retries !== this.manager.options.retries) {\n\t\t\t\treturn await this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\n\t\tif (this.manager.listenerCount(RESTEvents.Response)) {\n\t\t\tthis.manager.emit(\n\t\t\t\tRESTEvents.Response,\n\t\t\t\t{\n\t\t\t\t\tmethod,\n\t\t\t\t\tpath: routeId.original,\n\t\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\t\toptions,\n\t\t\t\t\tdata: requestData,\n\t\t\t\t\tretries,\n\t\t\t\t},\n\t\t\t\t{ ...res },\n\t\t\t);\n\t\t}\n\n\t\tconst status = res.statusCode;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = parseHeader(res.headers['x-ratelimit-limit']);\n\t\tconst remaining = parseHeader(res.headers['x-ratelimit-remaining']);\n\t\tconst reset = parseHeader(res.headers['x-ratelimit-reset-after']);\n\t\tconst hash = parseHeader(res.headers['x-ratelimit-bucket']);\n\t\tconst retry = parseHeader(res.headers['retry-after']);\n\n\t\t// Update the total number of requests that can be made before the rate limit resets\n\t\tthis.limit = limit ? Number(limit) : Infinity;\n\t\t// Update the number of remaining requests that can be made before the rate limit resets\n\t\tthis.remaining = remaining ? Number(remaining) : 1;\n\t\t// Update the time when this rate limit resets (reset-after is in seconds)\n\t\tthis.reset = reset ? Number(reset) * 1000 + Date.now() + this.manager.options.offset : Date.now();\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tif (retry) retryAfter = Number(retry) * 1000 + this.manager.options.offset;\n\n\t\t// Handle buckets via the hash header retroactively\n\t\tif (hash && hash !== this.hash) {\n\t\t\t// Let library users know when rate limit buckets have been updated\n\t\t\tthis.debug(['Received bucket hash update', ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join('\\n'));\n\t\t\t// This queue will eventually be eliminated via attrition\n\t\t\tthis.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });\n\t\t} else if (hash) {\n\t\t\t// Handle the case where hash value doesn't change\n\t\t\t// Fetch the hash data from the manager\n\t\t\tconst hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);\n\n\t\t\t// When fetched, update the last access of the hash\n\t\t\tif (hashData) {\n\t\t\t\thashData.lastAccess = Date.now();\n\t\t\t}\n\t\t}\n\n\t\t// Handle retryAfter, which means we have actually hit a rate limit\n\t\tlet sublimitTimeout: number | null = null;\n\t\tif (retryAfter > 0) {\n\t\t\tif (res.headers['x-ratelimit-global'] !== undefined) {\n\t\t\t\tthis.manager.globalRemaining = 0;\n\t\t\t\tthis.manager.globalReset = Date.now() + retryAfter;\n\t\t\t} else if (!this.localLimited) {\n\t\t\t\t/*\n\t\t\t\t * This is a sublimit (e.g. 2 channel name changes/10 minutes) since the headers don't indicate a\n\t\t\t\t * route-wide rate limit. Don't update remaining or reset to avoid rate limiting the whole\n\t\t\t\t * endpoint, just set a reset time on the request itself to avoid retrying too soon.\n\t\t\t\t */\n\t\t\t\tsublimitTimeout = retryAfter;\n\t\t\t}\n\t\t}\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\t\t\tinvalidCountResetTime = Date.now() + 1000 * 60 * 10;\n\t\t\t\tinvalidCount = 0;\n\t\t\t}\n\t\t\tinvalidCount++;\n\n\t\t\tconst emitInvalid =\n\t\t\t\tthis.manager.options.invalidRequestWarningInterval > 0 &&\n\t\t\t\tinvalidCount % this.manager.options.invalidRequestWarningInterval === 0;\n\t\t\tif (emitInvalid) {\n\t\t\t\t// Let library users know periodically about invalid requests\n\t\t\t\tthis.manager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\t\t\tcount: invalidCount,\n\t\t\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (status >= 200 && status < 300) {\n\t\t\treturn res;\n\t\t} else if (status === 429) {\n\t\t\t// A rate limit was hit - this may happen if the route isn't associated with an official bucket hash yet, or when first globally rate limited\n\t\t\tconst isGlobal = this.globalLimited;\n\t\t\tlet limit: number;\n\t\t\tlet timeout: number;\n\n\t\t\tif (isGlobal) {\n\t\t\t\t// Set RateLimitData based on the global limit\n\t\t\t\tlimit = this.manager.options.globalRequestsPerSecond;\n\t\t\t\ttimeout = this.manager.globalReset + this.manager.options.offset - Date.now();\n\t\t\t} else {\n\t\t\t\t// Set RateLimitData based on the route-specific limit\n\t\t\t\tlimit = this.limit;\n\t\t\t\ttimeout = this.timeToReset;\n\t\t\t}\n\t\t\tawait this.onRateLimit({\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tlimit,\n\t\t\t\tmethod,\n\t\t\t\thash: this.hash,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\tglobal: isGlobal,\n\t\t\t});\n\t\t\tthis.debug(\n\t\t\t\t[\n\t\t\t\t\t'Encountered unexpected 429 rate limit',\n\t\t\t\t\t` Global : ${isGlobal.toString()}`,\n\t\t\t\t\t` Method : ${method}`,\n\t\t\t\t\t` URL : ${url}`,\n\t\t\t\t\t` Bucket : ${routeId.bucketRoute}`,\n\t\t\t\t\t` Major parameter: ${routeId.majorParameter}`,\n\t\t\t\t\t` Hash : ${this.hash}`,\n\t\t\t\t\t` Limit : ${limit}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\t\t\t// If caused by a sublimit, wait it out here so other requests on the route can be handled\n\t\t\tif (sublimitTimeout) {\n\t\t\t\t// Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will\n\t\t\t\tconst firstSublimit = !this.#sublimitedQueue;\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\tthis.#sublimitedQueue = new AsyncQueue();\n\t\t\t\t\tvoid this.#sublimitedQueue.wait();\n\t\t\t\t\tthis.#asyncQueue.shift();\n\t\t\t\t}\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout, undefined, { ref: false });\n\t\t\t\tlet resolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((res) => (resolve = res));\n\t\t\t\tthis.#sublimitPromise = { promise, resolve: resolve! };\n\t\t\t\tif (firstSublimit) {\n\t\t\t\t\t// Re-queue this request so it can be shifted by the finally\n\t\t\t\t\tawait this.#asyncQueue.wait();\n\t\t\t\t\tthis.#shiftSublimit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Since this is not a server side issue, the next request should pass, so we don't bump the retries counter\n\t\t\treturn this.runRequest(routeId, url, options, requestData, retries);\n\t\t} else if (status >= 500 && status < 600) {\n\t\t\t// Retry the specified number of times for possible server side issues\n\t\t\tif (retries !== this.manager.options.retries) {\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\t\t\t// We are out of retries, throw an error\n\t\t\tthrow new HTTPError(res.constructor.name, status, method, url, requestData);\n\t\t} else {\n\t\t\t// Handle possible malformed requests\n\t\t\tif (status >= 400 && status < 500) {\n\t\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\t\tif (status === 401 && requestData.auth) {\n\t\t\t\t\tthis.manager.setToken(null!);\n\t\t\t\t}\n\t\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\t\t// throw the API error\n\t\t\t\tthrow new DiscordAPIError(data, 'code' in data ? data.code : data.error, status, method, url, requestData);\n\t\t\t}\n\t\t\treturn res;\n\t\t}\n\t}\n}\n"],"names":["sleep"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discordjs/rest",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-dev.1661213496-2ecb862.0",
|
|
4
4
|
"description": "The REST API for discord.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "vitest run",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"lint": "prettier --check . && TIMING=1 eslint src __tests__ --ext mjs,js,ts",
|
|
9
9
|
"format": "prettier --write . && TIMING=1 eslint src __tests__ --ext mjs,js,ts --fix",
|
|
10
10
|
"fmt": "yarn format",
|
|
11
|
-
"docs": "downlevel-dts
|
|
11
|
+
"docs": "downlevel-dts dist docs/dist --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
|
|
12
12
|
"prepack": "yarn lint && yarn test && yarn build",
|
|
13
13
|
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/rest/*'",
|
|
14
14
|
"release": "cliff-jumper"
|
|
@@ -52,33 +52,34 @@
|
|
|
52
52
|
},
|
|
53
53
|
"homepage": "https://discord.js.org",
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@discordjs/collection": "^1.0
|
|
56
|
-
"@sapphire/async-queue": "^1.
|
|
55
|
+
"@discordjs/collection": "^1.1.0",
|
|
56
|
+
"@sapphire/async-queue": "^1.5.0",
|
|
57
57
|
"@sapphire/snowflake": "^3.2.2",
|
|
58
|
-
"discord-api-types": "^0.37.
|
|
58
|
+
"discord-api-types": "^0.37.4",
|
|
59
59
|
"file-type": "^17.1.6",
|
|
60
60
|
"tslib": "^2.4.0",
|
|
61
|
-
"undici": "^5.
|
|
61
|
+
"undici": "^5.9.1"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@discordjs/docgen": "^0.12.1",
|
|
65
|
-
"@favware/cliff-jumper": "^1.8.
|
|
66
|
-
"@microsoft/api-extractor": "^7.29.
|
|
67
|
-
"@types/node": "^16.11.
|
|
68
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
69
|
-
"@typescript-eslint/parser": "^5.
|
|
70
|
-
"@vitest/coverage-c8": "^0.22.
|
|
65
|
+
"@favware/cliff-jumper": "^1.8.7",
|
|
66
|
+
"@microsoft/api-extractor": "^7.29.3",
|
|
67
|
+
"@types/node": "^16.11.52",
|
|
68
|
+
"@typescript-eslint/eslint-plugin": "^5.34.0",
|
|
69
|
+
"@typescript-eslint/parser": "^5.34.0",
|
|
70
|
+
"@vitest/coverage-c8": "^0.22.1",
|
|
71
71
|
"downlevel-dts": "^0.10.0",
|
|
72
72
|
"eslint": "^8.22.0",
|
|
73
73
|
"eslint-config-marine": "^9.4.1",
|
|
74
74
|
"eslint-config-prettier": "^8.5.0",
|
|
75
|
-
"eslint-import-resolver-typescript": "^3.
|
|
75
|
+
"eslint-import-resolver-typescript": "^3.5.0",
|
|
76
76
|
"eslint-plugin-import": "^2.26.0",
|
|
77
|
+
"eslint-plugin-tsdoc": "^0.2.16",
|
|
77
78
|
"prettier": "^2.7.1",
|
|
78
|
-
"rollup-plugin-typescript2": "0.
|
|
79
|
+
"rollup-plugin-typescript2": "^0.33.0",
|
|
79
80
|
"typescript": "^4.7.4",
|
|
80
|
-
"unbuild": "^0.8.
|
|
81
|
-
"vitest": "^0.22.
|
|
81
|
+
"unbuild": "^0.8.9",
|
|
82
|
+
"vitest": "^0.22.1"
|
|
82
83
|
},
|
|
83
84
|
"engines": {
|
|
84
85
|
"node": ">=16.9.0"
|