@discordjs/rest 3.0.0-move-client-init.1761650119-a4c0a246f → 3.0.0-pr-11006.1765450794-e636950b2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/web.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/web.ts","../src/environment.ts","../src/lib/CDN.ts","../src/lib/utils/constants.ts","../src/lib/errors/DiscordAPIError.ts","../src/lib/errors/HTTPError.ts","../src/lib/errors/RateLimitError.ts","../src/lib/REST.ts","../src/lib/utils/types.ts","../src/lib/utils/utils.ts","../src/lib/handlers/Shared.ts","../src/lib/handlers/BurstHandler.ts","../src/lib/handlers/SequentialHandler.ts","../src/shared.ts"],"sourcesContent":["import { setDefaultStrategy } from './environment.js';\n\n// This cast is needed because of a mismatch between the version of undici-types provided by @types/node and undici\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nsetDefaultStrategy(fetch as typeof import('undici').fetch);\n\nexport * from './shared.js';\n","import type { RESTOptions } from './shared.js';\n\nlet defaultStrategy: RESTOptions['makeRequest'];\n\nexport function setDefaultStrategy(newStrategy: RESTOptions['makeRequest']) {\n\tdefaultStrategy = newStrategy;\n}\n\nexport function getDefaultStrategy() {\n\treturn defaultStrategy;\n}\n","/* eslint-disable jsdoc/check-param-names */\nimport { CDNRoutes } from 'discord-api-types/v10';\nimport {\n\tALLOWED_EXTENSIONS,\n\tALLOWED_SIZES,\n\tALLOWED_STICKER_EXTENSIONS,\n\tDefaultRestOptions,\n\ttype ImageExtension,\n\ttype ImageSize,\n\ttype StickerExtension,\n} from './utils/constants.js';\n\n/**\n * The options used for image URLs.\n */\nexport interface BaseImageURLOptions {\n\t/**\n\t * The extension to use for the image URL.\n\t *\n\t * @defaultValue `'webp'`\n\t */\n\textension?: ImageExtension;\n\t/**\n\t * The size specified in the image URL.\n\t */\n\tsize?: ImageSize;\n}\n\nexport interface EmojiURLOptionsWebp extends BaseImageURLOptions {\n\t/**\n\t * Whether to use the `animated` query parameter.\n\t */\n\tanimated?: boolean;\n\textension?: 'webp';\n}\n\nexport interface EmojiURLOptionsNotWebp extends BaseImageURLOptions {\n\textension: Exclude<ImageExtension, 'webp'>;\n}\n\n/**\n * The options used for emoji URLs.\n */\nexport type EmojiURLOptions = EmojiURLOptionsNotWebp | EmojiURLOptionsWebp;\n\n/**\n * The options used for image URLs that may be animated.\n */\nexport interface ImageURLOptions extends BaseImageURLOptions {\n\t/**\n\t * Whether to prefer the static asset.\n\t */\n\tforceStatic?: boolean;\n}\n\n/**\n * The options to use when making a CDN URL\n */\ninterface MakeURLOptions {\n\t/**\n\t * The allowed extensions that can be used\n\t */\n\tallowedExtensions?: readonly string[];\n\t/**\n\t * Whether to use the `animated` query parameter\n\t */\n\tanimated?: boolean;\n\t/**\n\t * The base URL.\n\t *\n\t * @defaultValue `DefaultRestOptions.cdn`\n\t */\n\tbase?: string;\n\t/**\n\t * The extension to use for the image URL\n\t *\n\t * @defaultValue `'webp'`\n\t */\n\textension?: string | undefined;\n\t/**\n\t * The size specified in the image URL\n\t */\n\tsize?: ImageSize;\n}\n\n/**\n * Options for initializing the {@link CDN} class.\n */\nexport interface CDNOptions {\n\t/**\n\t * The base URL for the CDN.\n\t *\n\t * @defaultValue `DefaultRestOptions.cdn`\n\t */\n\tcdn?: string | undefined;\n\t/**\n\t * The base URL for the media proxy.\n\t *\n\t * @defaultValue `DefaultRestOptions.mediaProxy`\n\t */\n\tmediaProxy?: string | undefined;\n}\n\n/**\n * The CDN link builder\n */\nexport class CDN {\n\tprivate readonly cdn: string;\n\n\tprivate readonly mediaProxy: string;\n\n\tpublic constructor({ cdn, mediaProxy }: CDNOptions = {}) {\n\t\tthis.cdn = cdn ?? DefaultRestOptions.cdn;\n\t\tthis.mediaProxy = mediaProxy ?? DefaultRestOptions.mediaProxy;\n\t}\n\n\t/**\n\t * Generates an app asset URL for a client's asset.\n\t *\n\t * @param clientId - The client id that has the asset\n\t * @param assetHash - The hash provided by Discord for this asset\n\t * @param options - Optional options for the asset\n\t */\n\tpublic appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);\n\t}\n\n\t/**\n\t * Generates an app icon URL for a client's icon.\n\t *\n\t * @param clientId - The client id that has the icon\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates an avatar URL, e.g. for a user or a webhook.\n\t *\n\t * @param id - The id that has the icon\n\t * @param avatarHash - The hash provided by Discord for this avatar\n\t * @param options - Optional options for the avatar\n\t */\n\tpublic avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);\n\t}\n\n\t/**\n\t * Generates a user avatar decoration preset URL.\n\t *\n\t * @param asset - The avatar decoration hash\n\t */\n\tpublic avatarDecoration(asset: string): string {\n\t\treturn this.makeURL(`/avatar-decoration-presets/${asset}`, { extension: 'png' });\n\t}\n\n\t/**\n\t * Generates a banner URL, e.g. for a user or a guild.\n\t *\n\t * @param id - The id that has the banner splash\n\t * @param bannerHash - The hash provided by Discord for this banner\n\t * @param options - Optional options for the banner\n\t */\n\tpublic banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);\n\t}\n\n\t/**\n\t * Generates an icon URL for a channel, e.g. a group DM.\n\t *\n\t * @param channelId - The channel id that has the icon\n\t * @param iconHash - The hash provided by Discord for this channel\n\t * @param options - Optional options for the icon\n\t */\n\tpublic channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a default avatar URL\n\t *\n\t * @param index - The default avatar index\n\t * @remarks\n\t * To calculate the index for a user do `(userId >> 22) % 6`,\n\t * or `discriminator % 5` if they're using the legacy username system.\n\t */\n\tpublic defaultAvatar(index: number): string {\n\t\treturn this.makeURL(`/embed/avatars/${index}`, { extension: 'png' });\n\t}\n\n\t/**\n\t * Generates a discovery splash URL for a guild's discovery splash.\n\t *\n\t * @param guildId - The guild id that has the discovery splash\n\t * @param splashHash - The hash provided by Discord for this splash\n\t * @param options - Optional options for the splash\n\t */\n\tpublic discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);\n\t}\n\n\t/**\n\t * Generates an emoji's URL.\n\t *\n\t * @param emojiId - The emoji id\n\t * @param options - Optional options for the emoji\n\t */\n\tpublic emoji(emojiId: string, options?: Readonly<EmojiURLOptions>): string {\n\t\treturn this.makeURL(`/emojis/${emojiId}`, options);\n\t}\n\n\t/**\n\t * Generates a guild member avatar URL.\n\t *\n\t * @param guildId - The id of the guild\n\t * @param userId - The id of the user\n\t * @param avatarHash - The hash provided by Discord for this avatar\n\t * @param options - Optional options for the avatar\n\t */\n\tpublic guildMemberAvatar(\n\t\tguildId: string,\n\t\tuserId: string,\n\t\tavatarHash: string,\n\t\toptions?: Readonly<ImageURLOptions>,\n\t): string {\n\t\treturn this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);\n\t}\n\n\t/**\n\t * Generates a guild member banner URL.\n\t *\n\t * @param guildId - The id of the guild\n\t * @param userId - The id of the user\n\t * @param bannerHash - The hash provided by Discord for this banner\n\t * @param options - Optional options for the banner\n\t */\n\tpublic guildMemberBanner(\n\t\tguildId: string,\n\t\tuserId: string,\n\t\tbannerHash: string,\n\t\toptions?: Readonly<ImageURLOptions>,\n\t): string {\n\t\treturn this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banners/${bannerHash}`, bannerHash, options);\n\t}\n\n\t/**\n\t * Generates an icon URL, e.g. for a guild.\n\t *\n\t * @param id - The id that has the icon splash\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);\n\t}\n\n\t/**\n\t * Generates a URL for the icon of a role\n\t *\n\t * @param roleId - The id of the role that has the icon\n\t * @param roleIconHash - The hash provided by Discord for this role icon\n\t * @param options - Optional options for the role icon\n\t */\n\tpublic roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a guild invite splash URL for a guild's invite splash.\n\t *\n\t * @param guildId - The guild id that has the invite splash\n\t * @param splashHash - The hash provided by Discord for this splash\n\t * @param options - Optional options for the splash\n\t */\n\tpublic splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/splashes/${guildId}/${splashHash}`, options);\n\t}\n\n\t/**\n\t * Generates a sticker URL.\n\t *\n\t * @param stickerId - The sticker id\n\t * @param extension - The extension of the sticker\n\t * @privateRemarks\n\t * Stickers cannot have a `.webp` extension, so we default to a `.png`.\n\t * Sticker GIFs do not use the CDN base URL.\n\t */\n\tpublic sticker(stickerId: string, extension: StickerExtension = 'png'): string {\n\t\treturn this.makeURL(`/stickers/${stickerId}`, {\n\t\t\tallowedExtensions: ALLOWED_STICKER_EXTENSIONS,\n\t\t\tbase: extension === 'gif' ? this.mediaProxy : this.cdn,\n\t\t\textension,\n\t\t});\n\t}\n\n\t/**\n\t * Generates a sticker pack banner URL.\n\t *\n\t * @param bannerId - The banner id\n\t * @param options - Optional options for the banner\n\t */\n\tpublic stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);\n\t}\n\n\t/**\n\t * Generates a team icon URL for a team's icon.\n\t *\n\t * @param teamId - The team id that has the icon\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a cover image for a guild scheduled event.\n\t *\n\t * @param scheduledEventId - The scheduled event id\n\t * @param coverHash - The hash provided by discord for this cover image\n\t * @param options - Optional options for the cover image\n\t */\n\tpublic guildScheduledEventCover(\n\t\tscheduledEventId: string,\n\t\tcoverHash: string,\n\t\toptions?: Readonly<BaseImageURLOptions>,\n\t): string {\n\t\treturn this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);\n\t}\n\n\t/**\n\t * Generates a URL for a soundboard sound.\n\t *\n\t * @param soundId - The soundboard sound id\n\t */\n\tpublic soundboardSound(soundId: string): string {\n\t\treturn `${this.cdn}${CDNRoutes.soundboardSound(soundId)}`;\n\t}\n\n\t/**\n\t * Generates a URL for a guild tag badge.\n\t *\n\t * @param guildId - The guild id\n\t * @param badgeHash - The hash of the badge\n\t * @param options - Optional options for the badge\n\t */\n\tpublic guildTagBadge(guildId: string, badgeHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/guild-tag-badges/${guildId}/${badgeHash}`, options);\n\t}\n\n\t/**\n\t * Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.\n\t *\n\t * @param route - The base cdn route\n\t * @param hash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the link\n\t */\n\tprivate dynamicMakeURL(\n\t\troute: string,\n\t\thash: string,\n\t\t{ forceStatic = false, ...options }: Readonly<ImageURLOptions> = {},\n\t): string {\n\t\treturn this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, animated: true } : options);\n\t}\n\n\t/**\n\t * Constructs the URL for the resource\n\t *\n\t * @param route - The base cdn route\n\t * @param options - The extension/size options for the link\n\t */\n\tprivate makeURL(\n\t\troute: string,\n\t\t{\n\t\t\tallowedExtensions = ALLOWED_EXTENSIONS,\n\t\t\tbase = this.cdn,\n\t\t\textension = 'webp',\n\t\t\tsize,\n\t\t\tanimated,\n\t\t}: Readonly<MakeURLOptions> = {},\n\t): string {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\textension = String(extension).toLowerCase();\n\n\t\tif (!allowedExtensions.includes(extension)) {\n\t\t\tthrow new RangeError(`Invalid extension provided: ${extension}\\nMust be one of: ${allowedExtensions.join(', ')}`);\n\t\t}\n\n\t\tif (size && !ALLOWED_SIZES.includes(size)) {\n\t\t\tthrow new RangeError(`Invalid size provided: ${size}\\nMust be one of: ${ALLOWED_SIZES.join(', ')}`);\n\t\t}\n\n\t\tconst url = new URL(`${base}${route}.${extension}`);\n\n\t\tif (animated !== undefined) {\n\t\t\turl.searchParams.set('animated', String(animated));\n\t\t}\n\n\t\tif (size) {\n\t\t\turl.searchParams.set('size', String(size));\n\t\t}\n\n\t\treturn url.toString();\n\t}\n}\n","import { getUserAgentAppendix } from '@discordjs/util';\nimport type { ImageSize } from 'discord-api-types/v10';\nimport { APIVersion } from 'discord-api-types/v10';\nimport { getDefaultStrategy } from '../../environment.js';\nimport type { RESTOptions, ResponseLike } from './types.js';\n\nexport type { ImageSize } from 'discord-api-types/v10';\n\nexport const DefaultUserAgent =\n\t`DiscordBot (https://discord.js.org, 3.0.0-move-client-init.1761650119-a4c0a246f)` as `DiscordBot (https://discord.js.org, ${string})`;\n\n/**\n * The default string to append onto the user agent.\n */\nexport const DefaultUserAgentAppendix = getUserAgentAppendix();\n\nexport const DefaultRestOptions = {\n\tagent: null,\n\tapi: 'https://discord.com/api',\n\tauthPrefix: 'Bot',\n\tcdn: 'https://cdn.discordapp.com',\n\theaders: {},\n\tinvalidRequestWarningInterval: 0,\n\tglobalRequestsPerSecond: 50,\n\toffset: 50,\n\trejectOnRateLimit: null,\n\tretries: 3,\n\tretryBackoff: 0,\n\ttimeout: 15_000,\n\tuserAgentAppendix: DefaultUserAgentAppendix,\n\tversion: APIVersion,\n\thashSweepInterval: 14_400_000, // 4 Hours\n\thashLifetime: 86_400_000, // 24 Hours\n\thandlerSweepInterval: 3_600_000, // 1 Hour\n\tasync makeRequest(...args): Promise<ResponseLike> {\n\t\treturn getDefaultStrategy()(...args);\n\t},\n\tmediaProxy: 'https://media.discordapp.net',\n} as const satisfies Required<RESTOptions>;\n\n/**\n * The events that the REST manager emits\n */\nexport enum RESTEvents {\n\tDebug = 'restDebug',\n\tHandlerSweep = 'handlerSweep',\n\tHashSweep = 'hashSweep',\n\tInvalidRequestWarning = 'invalidRequestWarning',\n\tRateLimited = 'rateLimited',\n\tResponse = 'response',\n}\n\nexport const ALLOWED_EXTENSIONS = ['webp', 'png', 'jpg', 'jpeg', 'gif'] as const satisfies readonly string[];\nexport const ALLOWED_STICKER_EXTENSIONS = ['png', 'json', 'gif'] as const satisfies readonly string[];\nexport const ALLOWED_SIZES: readonly number[] = [\n\t16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096,\n] satisfies readonly ImageSize[];\n\nexport type ImageExtension = (typeof ALLOWED_EXTENSIONS)[number];\nexport type StickerExtension = (typeof ALLOWED_STICKER_EXTENSIONS)[number];\n\nexport const OverwrittenMimeTypes = {\n\t// https://github.com/discordjs/discord.js/issues/8557\n\t'image/apng': 'image/png',\n} as const satisfies Readonly<Record<string, string>>;\n\nexport const BurstHandlerMajorIdKey = 'burst';\n\nexport const AUTH_UUID_NAMESPACE = 'acc82a4c-f887-417b-a69c-f74096ff7e59';\n","import type { InternalRequest, RawFile } from '../utils/types.js';\n\nexport interface DiscordErrorFieldInformation {\n\tcode: string;\n\tmessage: string;\n}\n\nexport interface DiscordErrorGroupWrapper {\n\t_errors: DiscordError[];\n}\n\nexport type DiscordError =\n\t| DiscordErrorFieldInformation\n\t| DiscordErrorGroupWrapper\n\t| string\n\t| { [k: string]: DiscordError };\n\nexport interface DiscordErrorData {\n\tcode: number;\n\terrors?: DiscordError;\n\tmessage: string;\n}\n\nexport interface OAuthErrorData {\n\terror: string;\n\terror_description?: string;\n}\n\nexport interface RequestBody {\n\tfiles: RawFile[] | undefined;\n\tjson: unknown | undefined;\n}\n\nfunction isErrorGroupWrapper(error: DiscordError): error is DiscordErrorGroupWrapper {\n\treturn Reflect.has(error as Record<string, unknown>, '_errors');\n}\n\nfunction isErrorResponse(error: DiscordError): error is DiscordErrorFieldInformation {\n\treturn typeof Reflect.get(error as Record<string, unknown>, 'message') === 'string';\n}\n\n/**\n * Represents an API error returned by Discord\n */\nexport class DiscordAPIError extends Error {\n\tpublic requestBody: RequestBody;\n\n\t/**\n\t * @param rawError - The error reported by Discord\n\t * @param code - The error code reported by Discord\n\t * @param status - The status code of the response\n\t * @param method - The method of the request that errored\n\t * @param url - The url of the request that errored\n\t * @param bodyData - The unparsed data for the request that errored\n\t */\n\tpublic constructor(\n\t\tpublic rawError: DiscordErrorData | OAuthErrorData,\n\t\tpublic code: number | string,\n\t\tpublic status: number,\n\t\tpublic method: string,\n\t\tpublic url: string,\n\t\tbodyData: Pick<InternalRequest, 'body' | 'files'>,\n\t) {\n\t\tsuper(DiscordAPIError.getMessage(rawError));\n\n\t\tthis.requestBody = { files: bodyData.files, json: bodyData.body };\n\t}\n\n\t/**\n\t * The name of the error\n\t */\n\tpublic override get name(): string {\n\t\treturn `${DiscordAPIError.name}[${this.code}]`;\n\t}\n\n\tprivate static getMessage(error: DiscordErrorData | OAuthErrorData) {\n\t\tlet flattened = '';\n\t\tif ('code' in error) {\n\t\t\tif (error.errors) {\n\t\t\t\tflattened = [...this.flattenDiscordError(error.errors)].join('\\n');\n\t\t\t}\n\n\t\t\treturn error.message && flattened\n\t\t\t\t? `${error.message}\\n${flattened}`\n\t\t\t\t: error.message || flattened || 'Unknown Error';\n\t\t}\n\n\t\treturn error.error_description ?? 'No Description';\n\t}\n\n\tprivate static *flattenDiscordError(obj: DiscordError, key = ''): IterableIterator<string> {\n\t\tif (isErrorResponse(obj)) {\n\t\t\treturn yield `${key.length ? `${key}[${obj.code}]` : `${obj.code}`}: ${obj.message}`.trim();\n\t\t}\n\n\t\tfor (const [otherKey, val] of Object.entries(obj)) {\n\t\t\tconst nextKey = otherKey.startsWith('_')\n\t\t\t\t? key\n\t\t\t\t: key\n\t\t\t\t\t? Number.isNaN(Number(otherKey))\n\t\t\t\t\t\t? `${key}.${otherKey}`\n\t\t\t\t\t\t: `${key}[${otherKey}]`\n\t\t\t\t\t: otherKey;\n\n\t\t\tif (typeof val === 'string') {\n\t\t\t\tyield val;\n\t\t\t} else if (isErrorGroupWrapper(val)) {\n\t\t\t\tfor (const error of val._errors) {\n\t\t\t\t\tyield* this.flattenDiscordError(error, nextKey);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tyield* this.flattenDiscordError(val, nextKey);\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { InternalRequest } from '../utils/types.js';\nimport type { RequestBody } from './DiscordAPIError.js';\n\n/**\n * Represents a HTTP error\n */\nexport class HTTPError extends Error {\n\tpublic requestBody: RequestBody;\n\n\tpublic override name = HTTPError.name;\n\n\t/**\n\t * @param status - The status code of the response\n\t * @param statusText - The status text of the response\n\t * @param method - The method of the request that errored\n\t * @param url - The url of the request that errored\n\t * @param bodyData - The unparsed data for the request that errored\n\t */\n\tpublic constructor(\n\t\tpublic status: number,\n\t\tstatusText: string,\n\t\tpublic method: string,\n\t\tpublic url: string,\n\t\tbodyData: Pick<InternalRequest, 'body' | 'files'>,\n\t) {\n\t\tsuper(statusText);\n\t\tthis.requestBody = { files: bodyData.files, json: bodyData.body };\n\t}\n}\n","import type { RateLimitData } from '../utils/types.js';\n\nexport class RateLimitError extends Error implements RateLimitData {\n\tpublic timeToReset: number;\n\n\tpublic limit: number;\n\n\tpublic method: string;\n\n\tpublic hash: string;\n\n\tpublic url: string;\n\n\tpublic route: string;\n\n\tpublic majorParameter: string;\n\n\tpublic global: boolean;\n\n\tpublic retryAfter: number;\n\n\tpublic sublimitTimeout: number;\n\n\tpublic scope: RateLimitData['scope'];\n\n\tpublic constructor(data: RateLimitData) {\n\t\tsuper();\n\t\tthis.timeToReset = data.timeToReset;\n\t\tthis.limit = data.limit;\n\t\tthis.method = data.method;\n\t\tthis.hash = data.hash;\n\t\tthis.url = data.url;\n\t\tthis.route = data.route;\n\t\tthis.majorParameter = data.majorParameter;\n\t\tthis.global = data.global;\n\t\tthis.retryAfter = data.retryAfter;\n\t\tthis.sublimitTimeout = data.sublimitTimeout;\n\t\tthis.scope = data.scope;\n\t}\n\n\t/**\n\t * The name of the error\n\t */\n\tpublic override get name(): string {\n\t\treturn `${RateLimitError.name}[${this.route}]`;\n\t}\n}\n","import { Collection } from '@discordjs/collection';\nimport { DiscordSnowflake } from '@sapphire/snowflake';\nimport { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';\nimport { filetypeinfo } from 'magic-bytes.js';\nimport type { RequestInit, BodyInit, Dispatcher } from 'undici';\nimport { v5 as uuidV5 } from 'uuid';\nimport { CDN } from './CDN.js';\nimport { BurstHandler } from './handlers/BurstHandler.js';\nimport { SequentialHandler } from './handlers/SequentialHandler.js';\nimport type { IHandler } from './interfaces/Handler.js';\nimport {\n\tAUTH_UUID_NAMESPACE,\n\tBurstHandlerMajorIdKey,\n\tDefaultRestOptions,\n\tDefaultUserAgent,\n\tOverwrittenMimeTypes,\n\tRESTEvents,\n} from './utils/constants.js';\nimport { RequestMethod } from './utils/types.js';\nimport type {\n\tRESTOptions,\n\tResponseLike,\n\tRestEvents,\n\tHashData,\n\tInternalRequest,\n\tRouteLike,\n\tRequestHeaders,\n\tRouteData,\n\tRequestData,\n\tAuthData,\n} from './utils/types.js';\nimport { isBufferLike, parseResponse } from './utils/utils.js';\n\n/**\n * Represents the class that manages handlers for endpoints\n */\nexport class REST extends AsyncEventEmitter<RestEvents> {\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\n\tpublic readonly cdn: CDN;\n\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#token: string | null = null;\n\n\tprivate hashTimer!: NodeJS.Timeout | number;\n\n\tprivate handlerTimer!: NodeJS.Timeout | number;\n\n\tpublic readonly options: RESTOptions;\n\n\tpublic constructor(options: Partial<RESTOptions> = {}) {\n\t\tsuper();\n\t\tthis.cdn = new CDN(options);\n\t\tthis.options = { ...DefaultRestOptions, ...options };\n\t\tthis.globalRemaining = Math.max(1, 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\t// eslint-disable-next-line unicorn/consistent-function-scoping\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 !== Number.POSITIVE_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((val, key) => {\n\t\t\t\t\t// `-1` indicates a global hash\n\t\t\t\t\tif (val.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 - val.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(key, val);\n\n\t\t\t\t\t\t// Emit debug information\n\t\t\t\t\t\tthis.emit(RESTEvents.Debug, `[REST] Hash ${val.value} for ${key} swept due to lifetime being exceeded`);\n\t\t\t\t\t}\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);\n\n\t\t\tthis.hashTimer.unref?.();\n\t\t}\n\n\t\tif (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Number.POSITIVE_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((val, key) => {\n\t\t\t\t\tconst { inactive } = val;\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(key, val);\n\t\t\t\t\t\tthis.emit(RESTEvents.Debug, `[REST] Handler ${val.id} for ${key} swept due to being inactive`);\n\t\t\t\t\t}\n\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);\n\n\t\t\tthis.handlerTimer.unref?.();\n\t\t}\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 async 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 async 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 async 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 async 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 async 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.queueRequest(options);\n\t\treturn parseResponse(response);\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 * @returns The response from the api request\n\t */\n\tpublic async queueRequest(request: InternalRequest): Promise<ResponseLike> {\n\t\t// Generalize the endpoint to its route data\n\t\tconst routeId = REST.generateRouteData(request.fullRoute, request.method);\n\t\tconst customAuth = typeof request.auth === 'object' && request.auth.token !== this.#token;\n\t\tconst auth = customAuth ? uuidV5((request.auth as AuthData).token, AUTH_UUID_NAMESPACE) : request.auth !== false;\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}${customAuth ? `:${auth}` : ''}`) ?? {\n\t\t\tvalue: `Global(${request.method}:${routeId.bucketRoute}${customAuth ? `:${auth}` : ''})`,\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,\n\t\t\tsignal: request.signal,\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 * @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 =\n\t\t\tmajorParameter === BurstHandlerMajorIdKey\n\t\t\t\t? new BurstHandler(this, hash, majorParameter)\n\t\t\t\t: 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<{ fetchOptions: RequestInit; url: string }> {\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\tif (typeof request.auth === 'object') {\n\t\t\t\theaders.Authorization = `${request.auth.prefix ?? this.options.authPrefix} ${request.auth.token}`;\n\t\t\t} else {\n\t\t\t\t// If we haven't received a token, throw an error\n\t\t\t\tif (!this.#token) {\n\t\t\t\t\tthrow new Error('Expected token to be set for this request, but none was present');\n\t\t\t\t}\n\n\t\t\t\theaders.Authorization = `${this.options.authPrefix} ${this.#token}`;\n\t\t\t}\n\t\t}\n\n\t\t// If a reason was set, set its 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/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/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 (isBufferLike(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\tlet contentType = file.contentType;\n\n\t\t\t\t\tif (!contentType) {\n\t\t\t\t\t\tconst [parsedType] = filetypeinfo(file.data);\n\n\t\t\t\t\t\tif (parsedType) {\n\t\t\t\t\t\t\tcontentType =\n\t\t\t\t\t\t\t\tOverwrittenMimeTypes[parsedType.mime as keyof typeof OverwrittenMimeTypes] ??\n\t\t\t\t\t\t\t\tparsedType.mime ??\n\t\t\t\t\t\t\t\t'application/octet-stream';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\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\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, eqeqeq\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, eqeqeq\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\tconst method = request.method.toUpperCase();\n\n\t\t// The non null assertions in the following block are due to exactOptionalPropertyTypes, they have been tested to work with undefined\n\t\tconst fetchOptions: RequestInit = {\n\t\t\t// Set body to null on get / head requests. This does not follow fetch spec (likely because it causes subtle bugs) but is aligned with what request was doing\n\t\t\tbody: ['GET', 'HEAD'].includes(method) ? null : finalBody!,\n\t\t\theaders: { ...request.headers, ...additionalHeaders, ...headers } as Record<string, string>,\n\t\t\tmethod,\n\t\t\t// Prioritize setting an agent per request, use the agent for this instance otherwise.\n\t\t\tdispatcher: request.dispatcher ?? this.agent ?? undefined!,\n\t\t};\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 * @internal\n\t */\n\tprivate static generateRouteData(endpoint: RouteLike, method: RequestMethod): RouteData {\n\t\tif (endpoint.startsWith('/interactions/') && endpoint.endsWith('/callback')) {\n\t\t\treturn {\n\t\t\t\tmajorParameter: BurstHandlerMajorIdKey,\n\t\t\t\tbucketRoute: '/interactions/:id/:token/callback',\n\t\t\t\toriginal: endpoint,\n\t\t\t};\n\t\t}\n\n\t\tconst majorIdMatch = /(?:^\\/webhooks\\/(\\d{17,19}\\/[^/?]+))|(?:^\\/(?:channels|guilds|webhooks)\\/(\\d{17,19}))/.exec(\n\t\t\tendpoint,\n\t\t);\n\n\t\t// Get the major id or id + token for this route - global otherwise\n\t\tconst majorId = majorIdMatch?.[2] ?? majorIdMatch?.[1] ?? 'global';\n\n\t\tconst baseRoute = endpoint\n\t\t\t// Strip out all ids\n\t\t\t.replaceAll(/\\d{17,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\t\t\t// Strip out webhook tokens\n\t\t\t.replace(/\\/webhooks\\/:id\\/[^/?]+/, '/webhooks/:id/:token');\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{17,19}$/.exec(endpoint)![0]!;\n\t\t\tconst timestamp = DiscordSnowflake.timestampFrom(id);\n\t\t\tif (Date.now() - timestamp > 1_000 * 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","import type { Readable } from 'node:stream';\nimport type { ReadableStream } from 'node:stream/web';\nimport type { Collection } from '@discordjs/collection';\nimport type { Awaitable } from '@discordjs/util';\nimport type { Agent, Dispatcher, RequestInit, BodyInit, Response } from 'undici';\nimport type { IHandler } from '../interfaces/Handler.js';\n\nexport interface RestEvents {\n\thandlerSweep: [sweptHandlers: Collection<string, IHandler>];\n\thashSweep: [sweptHashes: Collection<string, HashData>];\n\tinvalidRequestWarning: [invalidRequestInfo: InvalidRequestWarningData];\n\trateLimited: [rateLimitInfo: RateLimitData];\n\tresponse: [request: APIRequest, response: ResponseLike];\n\trestDebug: [info: string];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface RestEventsMap extends RestEvents {}\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 | null;\n\t/**\n\t * The base api path, without version\n\t *\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: 'Bearer' | 'Bot';\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 * 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 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\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 4h)\n\t *\n\t * @defaultValue `14_400_000`\n\t */\n\thashSweepInterval: number;\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 * The method called to perform the actual HTTP request given a url and web `fetch` options\n\t * For example, to use global fetch, simply provide `makeRequest: fetch`\n\t */\n\tmakeRequest(url: string, init: RequestInit): Promise<ResponseLike>;\n\t/**\n\t * The media proxy path\n\t *\n\t * @defaultValue `'https://media.discordapp.net'`\n\t */\n\tmediaProxy: string;\n\t/**\n\t * The extra offset to add to rate limits in milliseconds\n\t *\n\t * @defaultValue `50`\n\t */\n\toffset: GetRateLimitOffsetFunction | 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: RateLimitQueueFilter | string[] | 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 exponentially add before retrying a 5xx or aborted request\n\t *\n\t * @defaultValue `0`\n\t */\n\tretryBackoff: GetRetryBackoffFunction | 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: GetTimeoutFunction | number;\n\t/**\n\t * Extra information to add to the user agent\n\t *\n\t * @defaultValue DefaultUserAgentAppendix\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}\n\n/**\n * Data emitted on `RESTEvents.RateLimited`\n */\nexport interface RateLimitData {\n\t/**\n\t * Whether the rate limit that was reached was the global limit\n\t */\n\tglobal: boolean;\n\t/**\n\t * The bucket hash for this request\n\t */\n\thash: string;\n\t/**\n\t * The amount of requests we can perform before locking requests\n\t */\n\tlimit: number;\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 * The HTTP method being performed\n\t */\n\tmethod: string;\n\t/**\n\t * The time, in milliseconds, that will need to pass before this specific request can be retried\n\t */\n\tretryAfter: number;\n\t/**\n\t * The route being hit in this request\n\t */\n\troute: string;\n\t/**\n\t * The scope of the rate limit that was hit.\n\t *\n\t * This can be `user` for rate limits that are per client, `global` for rate limits that affect all clients or `shared` for rate limits that\n\t * are shared per resource.\n\t */\n\tscope: 'global' | 'shared' | 'user';\n\t/**\n\t * The time, in milliseconds, that will need to pass before the sublimit lock for the route resets, and requests that fall under a sublimit\n\t * can be retried\n\t *\n\t * This is only present on certain sublimits, and `0` otherwise\n\t */\n\tsublimitTimeout: number;\n\t/**\n\t * The time, in milliseconds, until the route's request-lock is reset\n\t */\n\ttimeToReset: number;\n\t/**\n\t * The full URL for this request\n\t */\n\turl: string;\n}\n\n/**\n * A function that determines whether the rate limit hit should throw an Error\n */\nexport type RateLimitQueueFilter = (rateLimitData: RateLimitData) => Awaitable<boolean>;\n\n/**\n * A function that determines the rate limit offset for a given request.\n */\nexport type GetRateLimitOffsetFunction = (route: string) => number;\n\n/**\n * A function that determines the backoff for a retry for a given request.\n *\n * @param route - The route that has encountered a server-side error\n * @param statusCode - The status code received or `null` if aborted\n * @param retryCount - The number of retries that have been attempted so far. The first call will be `0`\n * @param requestBody - The body that was sent with the request\n * @returns The delay for the current request or `null` to throw an error instead of retrying\n */\nexport type GetRetryBackoffFunction = (\n\troute: string,\n\tstatusCode: number | null,\n\tretryCount: number,\n\trequestBody: unknown,\n) => number | null;\n\n/**\n * A function that determines the timeout for a given request.\n *\n * @param route - The route that is being processed\n * @param body - The body that will be sent with the request\n */\nexport type GetTimeoutFunction = (route: string, body: unknown) => number;\n\nexport interface APIRequest {\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 HTTP method used in this request\n\t */\n\tmethod: string;\n\t/**\n\t * Additional HTTP options for this request\n\t */\n\toptions: RequestInit;\n\t/**\n\t * The full path used to make the request\n\t */\n\tpath: RouteLike;\n\t/**\n\t * The number of times this request has been attempted\n\t */\n\tretries: number;\n\t/**\n\t * The API route identifying the ratelimit for this request\n\t */\n\troute: string;\n}\n\nexport interface ResponseLike\n\textends Pick<Response, 'arrayBuffer' | 'bodyUsed' | 'headers' | 'json' | 'ok' | 'status' | 'statusText' | 'text'> {\n\tbody: Readable | ReadableStream | null;\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\n/**\n * Represents a file to be added to the request\n */\nexport interface RawFile {\n\t/**\n\t * Content-Type of the file\n\t */\n\tcontentType?: string;\n\t/**\n\t * The actual data for the file\n\t */\n\tdata: Buffer | Uint8Array | boolean | number | 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 name of the file\n\t */\n\tname: string;\n}\n\nexport interface AuthData {\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 `REST.options.authPrefix`\n\t */\n\tprefix?: 'Bearer' | 'Bot';\n\t/**\n\t * The authorization token to use for this request\n\t */\n\ttoken: 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 * Alternate authorization data to use for this request only, or `false` to disable the Authorization header.\n\t * When making a request to a route that includes a token (such as interactions or webhooks), set to `false`\n\t * to avoid accidentally unsetting the instance token if a 401 is encountered.\n\t *\n\t * @defaultValue `true`\n\t */\n\tauth?: AuthData | boolean | undefined;\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 | undefined;\n\t/**\n\t * The signal to abort the queue entry or the REST call, where applicable\n\t */\n\tsignal?: AbortSignal | undefined;\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 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 */\nexport interface InternalRequest extends RequestData {\n\tfullRoute: RouteLike;\n\tmethod: RequestMethod;\n}\n\nexport interface HandlerRequestData extends Pick<InternalRequest, 'body' | 'files' | 'signal'> {\n\tauth: boolean | string;\n}\n\n/**\n * Parsed route data for an endpoint\n */\nexport interface RouteData {\n\tbucketRoute: string;\n\tmajorParameter: string;\n\toriginal: RouteLike;\n}\n\n/**\n * Represents a hash and its associated fields\n */\nexport interface HashData {\n\tlastAccess: number;\n\tvalue: string;\n}\n","import type { RESTPatchAPIChannelJSONBody, Snowflake } from 'discord-api-types/v10';\nimport type { REST } from '../REST.js';\nimport { RateLimitError } from '../errors/RateLimitError.js';\nimport { RequestMethod } from './types.js';\nimport type {\n\tGetRateLimitOffsetFunction,\n\tGetRetryBackoffFunction,\n\tGetTimeoutFunction,\n\tRateLimitData,\n\tResponseLike,\n} from './types.js';\n\nfunction serializeSearchParam(value: unknown): string | null {\n\t// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check\n\tswitch (typeof value) {\n\t\tcase 'string':\n\t\t\treturn value;\n\t\tcase 'number':\n\t\tcase 'bigint':\n\t\tcase 'boolean':\n\t\t\treturn value.toString();\n\t\tcase 'object':\n\t\t\tif (value === null) return null;\n\t\t\tif (value instanceof Date) {\n\t\t\t\treturn Number.isNaN(value.getTime()) ? null : value.toISOString();\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\tif (typeof value.toString === 'function' && value.toString !== Object.prototype.toString) return value.toString();\n\t\t\treturn null;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Creates and populates an URLSearchParams instance from an object, stripping\n * out null and undefined values, while also coercing non-strings to strings.\n *\n * @param options - The options to use\n * @returns A populated URLSearchParams instance\n */\nexport function makeURLSearchParams<OptionsType extends object>(options?: Readonly<OptionsType>) {\n\tconst params = new URLSearchParams();\n\tif (!options) return params;\n\n\tfor (const [key, value] of Object.entries(options)) {\n\t\tconst serialized = serializeSearchParam(value);\n\t\tif (serialized !== null) params.append(key, serialized);\n\t}\n\n\treturn params;\n}\n\n/**\n * Converts the response to usable data\n *\n * @param res - The fetch response\n */\nexport async function parseResponse(res: ResponseLike): Promise<unknown> {\n\tif (res.headers.get('Content-Type')?.startsWith('application/json')) {\n\t\treturn res.json();\n\t}\n\n\treturn res.arrayBuffer();\n}\n\n/**\n * Check whether a request falls under a sublimit\n *\n * @param bucketRoute - The buckets route identifier\n * @param body - The options provided as JSON data\n * @param method - The HTTP method that will be used to make the request\n * @returns Whether the request falls under a sublimit\n */\nexport function hasSublimit(bucketRoute: string, body?: unknown, method?: string): boolean {\n\t// TODO: Update for new sublimits\n\t// Currently known sublimits:\n\t// Editing channel `name` or `topic`\n\tif (bucketRoute === '/channels/:id') {\n\t\tif (typeof body !== 'object' || body === null) return false;\n\t\t// This should never be a POST body, but just in case\n\t\tif (method !== RequestMethod.Patch) return false;\n\t\tconst castedBody = body as RESTPatchAPIChannelJSONBody;\n\t\treturn ['name', 'topic'].some((key) => Reflect.has(castedBody, key));\n\t}\n\n\t// If we are checking if a request has a sublimit on a route not checked above, sublimit all requests to avoid a flood of 429s\n\treturn true;\n}\n\n/**\n * Check whether an error indicates that a retry can be attempted\n *\n * @param error - The error thrown by the network request\n * @returns Whether the error indicates a retry should be attempted\n */\nexport function shouldRetry(error: Error | NodeJS.ErrnoException) {\n\t// Retry for possible timed out requests\n\tif (error.name === 'AbortError') return true;\n\t// Downlevel ECONNRESET to retry as it may be recoverable\n\treturn ('code' in error && error.code === 'ECONNRESET') || error.message.includes('ECONNRESET');\n}\n\n/**\n * Determines whether the request should be queued or whether a RateLimitError should be thrown\n *\n * @internal\n */\nexport async function onRateLimit(manager: REST, rateLimitData: RateLimitData) {\n\tconst { options } = manager;\n\tif (!options.rejectOnRateLimit) return;\n\n\tconst shouldThrow =\n\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\tif (shouldThrow) {\n\t\tthrow new RateLimitError(rateLimitData);\n\t}\n}\n\n/**\n * Calculates the default avatar index for a given user id.\n *\n * @param userId - The user id to calculate the default avatar index for\n */\nexport function calculateUserDefaultAvatarIndex(userId: Snowflake) {\n\treturn Number(BigInt(userId) >> 22n) % 6;\n}\n\n/**\n * Sleeps for a given amount of time.\n *\n * @param ms - The amount of time (in milliseconds) to sleep for\n */\nexport async function sleep(ms: number): Promise<void> {\n\treturn new Promise<void>((resolve) => {\n\t\tsetTimeout(() => resolve(), ms);\n\t});\n}\n\n/**\n * Verifies that a value is a buffer-like object.\n *\n * @param value - The value to check\n */\nexport function isBufferLike(value: unknown): value is ArrayBuffer | Buffer | Uint8Array | Uint8ClampedArray {\n\treturn value instanceof ArrayBuffer || value instanceof Uint8Array || value instanceof Uint8ClampedArray;\n}\n\n/**\n * Normalizes the offset for rate limits. Applies a Math.max(0, N) to prevent negative offsets,\n * also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeRateLimitOffset(offset: GetRateLimitOffsetFunction | number, route: string): number {\n\tif (typeof offset === 'number') {\n\t\treturn Math.max(0, offset);\n\t}\n\n\tconst result = offset(route);\n\treturn Math.max(0, result);\n}\n\n/**\n * Normalizes the retry backoff used to add delay to retrying 5xx and aborted requests.\n * Applies a Math.max(0, N) to prevent negative backoffs, also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeRetryBackoff(\n\tretryBackoff: GetRetryBackoffFunction | number,\n\troute: string,\n\tstatusCode: number | null,\n\tretryCount: number,\n\trequestBody: unknown,\n): number | null {\n\tif (typeof retryBackoff === 'number') {\n\t\treturn Math.max(0, retryBackoff) * (1 << retryCount);\n\t}\n\n\t// No need to Math.max as we'll only set the sleep timer if the value is > 0 (and not equal)\n\treturn retryBackoff(route, statusCode, retryCount, requestBody);\n}\n\n/**\n * Normalizes the timeout for aborting requests. Applies a Math.max(0, N) to prevent negative timeouts,\n * also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeTimeout(timeout: GetTimeoutFunction | number, route: string, requestBody: unknown): number {\n\tif (typeof timeout === 'number') {\n\t\treturn Math.max(0, timeout);\n\t}\n\n\tconst result = timeout(route, requestBody);\n\treturn Math.max(0, result);\n}\n","import type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError.js';\nimport { DiscordAPIError } from '../errors/DiscordAPIError.js';\nimport { HTTPError } from '../errors/HTTPError.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { ResponseLike, HandlerRequestData, RouteData } from '../utils/types.js';\nimport { normalizeRetryBackoff, normalizeTimeout, parseResponse, shouldRetry, sleep } from '../utils/utils.js';\n\nlet authFalseWarningEmitted = false;\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\n/**\n * Increment the invalid request count and emit warning if necessary\n *\n * @internal\n */\nexport function incrementInvalidCount(manager: REST) {\n\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\tinvalidCountResetTime = Date.now() + 1_000 * 60 * 10;\n\t\tinvalidCount = 0;\n\t}\n\n\tinvalidCount++;\n\n\tconst emitInvalid =\n\t\tmanager.options.invalidRequestWarningInterval > 0 &&\n\t\tinvalidCount % manager.options.invalidRequestWarningInterval === 0;\n\tif (emitInvalid) {\n\t\t// Let library users know periodically about invalid requests\n\t\tmanager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\tcount: invalidCount,\n\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t});\n\t}\n}\n\n/**\n * Performs the actual network request for a request handler\n *\n * @param manager - The manager that holds options and emits informational events\n * @param routeId - The generalized api route with literal ids for major parameters\n * @param url - The fully resolved url to make the request to\n * @param options - The fetch options needed to make the request\n * @param requestData - Extra data from the user's request needed for errors and additional processing\n * @param retries - The number of retries this request has already attempted (recursion occurs on the handler)\n * @returns The respond from the network or `null` when the request should be retried\n * @internal\n */\nexport async function makeNetworkRequest(\n\tmanager: REST,\n\trouteId: RouteData,\n\turl: string,\n\toptions: RequestInit,\n\trequestData: HandlerRequestData,\n\tretries: number,\n) {\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(\n\t\t() => controller.abort(),\n\t\tnormalizeTimeout(manager.options.timeout, routeId.bucketRoute, requestData.body),\n\t);\n\tif (requestData.signal) {\n\t\t// If the user signal was aborted, abort the controller, else abort the local signal.\n\t\t// The reason why we don't re-use the user's signal, is because users may use the same signal for multiple\n\t\t// requests, and we do not want to cause unexpected side-effects.\n\t\tif (requestData.signal.aborted) controller.abort();\n\t\telse requestData.signal.addEventListener('abort', () => controller.abort());\n\t}\n\n\tlet res: ResponseLike;\n\ttry {\n\t\tres = await manager.options.makeRequest(url, { ...options, signal: controller.signal });\n\t} catch (error: unknown) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\t// Retry the specified number of times if needed\n\t\tif (shouldRetry(error) && retries !== manager.options.retries) {\n\t\t\tconst backoff = normalizeRetryBackoff(\n\t\t\t\tmanager.options.retryBackoff,\n\t\t\t\trouteId.bucketRoute,\n\t\t\t\tnull,\n\t\t\t\tretries,\n\t\t\t\trequestData.body,\n\t\t\t);\n\t\t\tif (backoff === null) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (backoff > 0) {\n\t\t\t\tawait sleep(backoff);\n\t\t\t}\n\n\t\t\t// Retry is handled by the handler upon receiving null\n\t\t\treturn null;\n\t\t}\n\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\n\tif (manager.listenerCount(RESTEvents.Response)) {\n\t\tmanager.emit(\n\t\t\tRESTEvents.Response,\n\t\t\t{\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\tpath: routeId.original,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\toptions,\n\t\t\t\tdata: requestData,\n\t\t\t\tretries,\n\t\t\t},\n\t\t\tres instanceof Response ? res.clone() : { ...res },\n\t\t);\n\t}\n\n\treturn res;\n}\n\n/**\n * Handles 5xx and 4xx errors (not 429's) conventionally. 429's should be handled before calling this function\n *\n * @param manager - The manager that holds options and emits informational events\n * @param res - The response received from {@link makeNetworkRequest}\n * @param method - The method used to make the request\n * @param url - The fully resolved url to make the request to\n * @param requestData - Extra data from the user's request needed for errors and additional processing\n * @param retries - The number of retries this request has already attempted (recursion occurs on the handler)\n * @param routeId - The generalized API route with literal ids for major parameters\n * @returns The response if the status code is not handled or null to request a retry\n */\nexport async function handleErrors(\n\tmanager: REST,\n\tres: ResponseLike,\n\tmethod: string,\n\turl: string,\n\trequestData: HandlerRequestData,\n\tretries: number,\n\trouteId: RouteData,\n) {\n\tconst status = res.status;\n\tif (status >= 500 && status < 600) {\n\t\t// Retry the specified number of times for possible server side issues\n\t\tif (retries !== manager.options.retries) {\n\t\t\tconst backoff = normalizeRetryBackoff(\n\t\t\t\tmanager.options.retryBackoff,\n\t\t\t\trouteId.bucketRoute,\n\t\t\t\tstatus,\n\t\t\t\tretries,\n\t\t\t\trequestData.body,\n\t\t\t);\n\t\t\tif (backoff === null) {\n\t\t\t\tthrow new HTTPError(status, res.statusText, method, url, requestData);\n\t\t\t}\n\n\t\t\tif (backoff > 0) {\n\t\t\t\tawait sleep(backoff);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t// We are out of retries, throw an error\n\t\tthrow new HTTPError(status, res.statusText, method, url, requestData);\n\t} else {\n\t\t// Handle possible malformed requests\n\t\tif (status >= 400 && status < 500) {\n\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\tconst isDiscordError = 'code' in data;\n\n\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\tif (status === 401 && requestData.auth === true) {\n\t\t\t\tif (isDiscordError && data.code !== 0 && !authFalseWarningEmitted) {\n\t\t\t\t\tconst errorText = `Encountered HTTP 401 with error ${data.code}: ${data.message}. Your token will be removed from this REST instance. If you are using @discordjs/rest directly, consider adding 'auth: false' to the request. Open an issue with your library if not.`;\n\t\t\t\t\t// Use emitWarning if possible, probably not available in edge / web\n\t\t\t\t\tif (typeof globalThis.process !== 'undefined' && typeof globalThis.process.emitWarning === 'function') {\n\t\t\t\t\t\tglobalThis.process.emitWarning(errorText);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(errorText);\n\t\t\t\t\t}\n\n\t\t\t\t\tauthFalseWarningEmitted = true;\n\t\t\t\t}\n\n\t\t\t\tmanager.setToken(null!);\n\t\t\t}\n\n\t\t\t// throw the API error\n\t\t\tthrow new DiscordAPIError(data, isDiscordError ? data.code : data.error, status, method, url, requestData);\n\t\t}\n\n\t\treturn res;\n\t}\n}\n","import type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { IHandler } from '../interfaces/Handler.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { ResponseLike, HandlerRequestData, RouteData, RateLimitData } from '../utils/types.js';\nimport { normalizeRateLimitOffset, onRateLimit, sleep } from '../utils/utils.js';\nimport { handleErrors, incrementInvalidCount, makeNetworkRequest } from './Shared.js';\n\n/**\n * The structure used to handle burst requests for a given bucket.\n * Burst requests have no ratelimit handling but allow for pre- and post-processing\n * of data in the same manner as sequentially queued requests.\n *\n * @remarks\n * This queue may still emit a rate limit error if an unexpected 429 is hit\n */\nexport class BurstHandler implements IHandler {\n\t/**\n\t * {@inheritdoc IHandler.id}\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * {@inheritDoc IHandler.inactive}\n\t */\n\tpublic inactive = 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: REST,\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 * 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 * {@inheritDoc IHandler.queueRequest}\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t): Promise<ResponseLike> {\n\t\treturn this.runRequest(routeId, url, options, requestData);\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<ResponseLike> {\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst res = await makeNetworkRequest(this.manager, routeId, url, options, requestData, retries);\n\n\t\t// Retry requested\n\t\tif (res === null) {\n\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t}\n\n\t\tconst status = res.status;\n\t\tlet retryAfter = 0;\n\t\tconst retry = res.headers.get('Retry-After');\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\t\tif (retry) retryAfter = Number(retry) * 1_000 + offset;\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tincrementInvalidCount(this.manager);\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// Unexpected ratelimit\n\t\t\tconst isGlobal = res.headers.has('X-RateLimit-Global');\n\t\t\tconst scope = (res.headers.get('X-RateLimit-Scope') ?? 'user') as RateLimitData['scope'];\n\n\t\t\tawait onRateLimit(this.manager, {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit: Number.POSITIVE_INFINITY,\n\t\t\t\ttimeToReset: retryAfter,\n\t\t\t\tretryAfter,\n\t\t\t\tsublimitTimeout: 0,\n\t\t\t\tscope,\n\t\t\t});\n\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}`,\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 : ${Number.POSITIVE_INFINITY}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : None`,\n\t\t\t\t\t` Scope : ${scope}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\n\t\t\t// We are bypassing all other limits, but an encountered limit should be respected (it's probably a non-punished rate limit anyways)\n\t\t\tawait sleep(retryAfter);\n\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 {\n\t\t\tconst handled = await handleErrors(this.manager, res, method, url, requestData, retries, routeId);\n\t\t\tif (handled === null) {\n\t\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\treturn handled;\n\t\t}\n\t}\n}\n","import { AsyncQueue } from '@sapphire/async-queue';\nimport type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { IHandler } from '../interfaces/Handler.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { RateLimitData, ResponseLike, HandlerRequestData, RouteData } from '../utils/types.js';\nimport { hasSublimit, normalizeRateLimitOffset, onRateLimit, sleep } from '../utils/utils.js';\nimport { handleErrors, incrementInvalidCount, makeNetworkRequest } from './Shared.js';\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle sequential 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 = Number.POSITIVE_INFINITY;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\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#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#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: REST,\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 getTimeToReset(routeId: RouteData): number {\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\t\treturn this.reset + 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);\n\t\tthis.manager.globalDelay = null;\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t): Promise<ResponseLike> {\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\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait({ signal: requestData.signal });\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\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\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<ResponseLike> {\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\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\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 + 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\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\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\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.getTimeToReset(routeId);\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit,\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tretryAfter: timeout,\n\t\t\t\tsublimitTimeout: 0,\n\t\t\t\tscope: 'user',\n\t\t\t};\n\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 onRateLimit(this.manager, rateLimitData);\n\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\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\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() + 1_000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst res = await makeNetworkRequest(this.manager, routeId, url, options, requestData, retries);\n\n\t\t// Retry requested\n\t\tif (res === null) {\n\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t}\n\n\t\tconst status = res.status;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = res.headers.get('X-RateLimit-Limit');\n\t\tconst remaining = res.headers.get('X-RateLimit-Remaining');\n\t\tconst reset = res.headers.get('X-RateLimit-Reset-After');\n\t\tconst hash = res.headers.get('X-RateLimit-Bucket');\n\t\tconst retry = res.headers.get('Retry-After');\n\t\tconst scope = (res.headers.get('X-RateLimit-Scope') ?? 'user') as RateLimitData['scope'];\n\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\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) : Number.POSITIVE_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) * 1_000 + Date.now() + 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) * 1_000 + 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(\n\t\t\t\t`${method}:${routeId.bucketRoute}${typeof requestData.auth === 'string' ? `:${requestData.auth}` : ''}`,\n\t\t\t\t{ value: hash, lastAccess: Date.now() },\n\t\t\t);\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(\n\t\t\t\t`${method}:${routeId.bucketRoute}${typeof requestData.auth === 'string' ? `:${requestData.auth}` : ''}`,\n\t\t\t);\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.has('X-RateLimit-Global')) {\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\tincrementInvalidCount(this.manager);\n\t\t}\n\n\t\tif (res.ok) {\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\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\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 + 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.getTimeToReset(routeId);\n\t\t\t}\n\n\t\t\tawait onRateLimit(this.manager, {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit,\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tretryAfter,\n\t\t\t\tsublimitTimeout: sublimitTimeout ?? 0,\n\t\t\t\tscope,\n\t\t\t});\n\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\t` Scope : ${scope}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\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\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout);\n\t\t\t\tlet resolve: () => void;\n\t\t\t\t// eslint-disable-next-line promise/param-names, no-promise-executor-return\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\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 {\n\t\t\tconst handled = await handleErrors(this.manager, res, method, url, requestData, retries, routeId);\n\t\t\tif (handled === null) {\n\t\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\treturn handled;\n\t\t}\n\t}\n}\n","export * from './lib/CDN.js';\nexport * from './lib/errors/DiscordAPIError.js';\nexport * from './lib/errors/HTTPError.js';\nexport * from './lib/errors/RateLimitError.js';\nexport type * from './lib/interfaces/Handler.js';\nexport * from './lib/REST.js';\nexport * from './lib/utils/constants.js';\nexport * from './lib/utils/types.js';\nexport { calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse } from './lib/utils/utils.js';\n\n/**\n * The {@link https://github.com/discordjs/discord.js/blob/main/packages/rest#readme | @discordjs/rest} version\n * that you are currently using.\n */\n// This needs to explicitly be `string` so it is not typed as a \"const string\" that gets injected by esbuild\nexport const version = '3.0.0-move-client-init.1761650119-a4c0a246f' as string;\n"],"mappings":"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","names":["import_v10","RESTEvents","RequestMethod","limit","offset","res","uuidV5"]}
1
+ {"version":3,"sources":["../src/web.ts","../src/environment.ts","../src/lib/CDN.ts","../src/lib/utils/constants.ts","../src/lib/errors/DiscordAPIError.ts","../src/lib/errors/HTTPError.ts","../src/lib/errors/RateLimitError.ts","../src/lib/REST.ts","../src/lib/utils/types.ts","../src/lib/utils/utils.ts","../src/lib/handlers/Shared.ts","../src/lib/handlers/BurstHandler.ts","../src/lib/handlers/SequentialHandler.ts","../src/shared.ts"],"sourcesContent":["import { setDefaultStrategy } from './environment.js';\n\n// This cast is needed because of a mismatch between the version of undici-types provided by @types/node and undici\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nsetDefaultStrategy(fetch as typeof import('undici').fetch);\n\nexport * from './shared.js';\n","import type { RESTOptions } from './shared.js';\n\nlet defaultStrategy: RESTOptions['makeRequest'];\n\nexport function setDefaultStrategy(newStrategy: RESTOptions['makeRequest']) {\n\tdefaultStrategy = newStrategy;\n}\n\nexport function getDefaultStrategy() {\n\treturn defaultStrategy;\n}\n","/* eslint-disable jsdoc/check-param-names */\nimport { CDNRoutes } from 'discord-api-types/v10';\nimport {\n\tALLOWED_EXTENSIONS,\n\tALLOWED_SIZES,\n\tALLOWED_STICKER_EXTENSIONS,\n\tDefaultRestOptions,\n\ttype ImageExtension,\n\ttype ImageSize,\n\ttype StickerExtension,\n} from './utils/constants.js';\n\n/**\n * The options used for image URLs.\n */\nexport interface BaseImageURLOptions {\n\t/**\n\t * The extension to use for the image URL.\n\t *\n\t * @defaultValue `'webp'`\n\t */\n\textension?: ImageExtension;\n\t/**\n\t * The size specified in the image URL.\n\t */\n\tsize?: ImageSize;\n}\n\nexport interface EmojiURLOptionsWebp extends BaseImageURLOptions {\n\t/**\n\t * Whether to use the `animated` query parameter.\n\t */\n\tanimated?: boolean;\n\textension?: 'webp';\n}\n\nexport interface EmojiURLOptionsNotWebp extends BaseImageURLOptions {\n\textension: Exclude<ImageExtension, 'webp'>;\n}\n\n/**\n * The options used for emoji URLs.\n */\nexport type EmojiURLOptions = EmojiURLOptionsNotWebp | EmojiURLOptionsWebp;\n\n/**\n * The options used for image URLs that may be animated.\n */\nexport interface ImageURLOptions extends BaseImageURLOptions {\n\t/**\n\t * Whether to prefer the static asset.\n\t */\n\tforceStatic?: boolean;\n}\n\n/**\n * The options to use when making a CDN URL\n */\ninterface MakeURLOptions {\n\t/**\n\t * The allowed extensions that can be used\n\t */\n\tallowedExtensions?: readonly string[];\n\t/**\n\t * Whether to use the `animated` query parameter\n\t */\n\tanimated?: boolean;\n\t/**\n\t * The base URL.\n\t *\n\t * @defaultValue `DefaultRestOptions.cdn`\n\t */\n\tbase?: string;\n\t/**\n\t * The extension to use for the image URL\n\t *\n\t * @defaultValue `'webp'`\n\t */\n\textension?: string | undefined;\n\t/**\n\t * The size specified in the image URL\n\t */\n\tsize?: ImageSize;\n}\n\n/**\n * Options for initializing the {@link CDN} class.\n */\nexport interface CDNOptions {\n\t/**\n\t * The base URL for the CDN.\n\t *\n\t * @defaultValue `DefaultRestOptions.cdn`\n\t */\n\tcdn?: string | undefined;\n\t/**\n\t * The base URL for the media proxy.\n\t *\n\t * @defaultValue `DefaultRestOptions.mediaProxy`\n\t */\n\tmediaProxy?: string | undefined;\n}\n\n/**\n * The CDN link builder\n */\nexport class CDN {\n\tprivate readonly cdn: string;\n\n\tprivate readonly mediaProxy: string;\n\n\tpublic constructor({ cdn, mediaProxy }: CDNOptions = {}) {\n\t\tthis.cdn = cdn ?? DefaultRestOptions.cdn;\n\t\tthis.mediaProxy = mediaProxy ?? DefaultRestOptions.mediaProxy;\n\t}\n\n\t/**\n\t * Generates an app asset URL for a client's asset.\n\t *\n\t * @param clientId - The client id that has the asset\n\t * @param assetHash - The hash provided by Discord for this asset\n\t * @param options - Optional options for the asset\n\t */\n\tpublic appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);\n\t}\n\n\t/**\n\t * Generates an app icon URL for a client's icon.\n\t *\n\t * @param clientId - The client id that has the icon\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates an avatar URL, e.g. for a user or a webhook.\n\t *\n\t * @param id - The id that has the icon\n\t * @param avatarHash - The hash provided by Discord for this avatar\n\t * @param options - Optional options for the avatar\n\t */\n\tpublic avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);\n\t}\n\n\t/**\n\t * Generates a user avatar decoration preset URL.\n\t *\n\t * @param asset - The avatar decoration hash\n\t */\n\tpublic avatarDecoration(asset: string): string {\n\t\treturn this.makeURL(`/avatar-decoration-presets/${asset}`, { extension: 'png' });\n\t}\n\n\t/**\n\t * Generates a banner URL, e.g. for a user or a guild.\n\t *\n\t * @param id - The id that has the banner splash\n\t * @param bannerHash - The hash provided by Discord for this banner\n\t * @param options - Optional options for the banner\n\t */\n\tpublic banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);\n\t}\n\n\t/**\n\t * Generates an icon URL for a channel, e.g. a group DM.\n\t *\n\t * @param channelId - The channel id that has the icon\n\t * @param iconHash - The hash provided by Discord for this channel\n\t * @param options - Optional options for the icon\n\t */\n\tpublic channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a default avatar URL\n\t *\n\t * @param index - The default avatar index\n\t * @remarks\n\t * To calculate the index for a user do `(userId >> 22) % 6`,\n\t * or `discriminator % 5` if they're using the legacy username system.\n\t */\n\tpublic defaultAvatar(index: number): string {\n\t\treturn this.makeURL(`/embed/avatars/${index}`, { extension: 'png' });\n\t}\n\n\t/**\n\t * Generates a discovery splash URL for a guild's discovery splash.\n\t *\n\t * @param guildId - The guild id that has the discovery splash\n\t * @param splashHash - The hash provided by Discord for this splash\n\t * @param options - Optional options for the splash\n\t */\n\tpublic discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);\n\t}\n\n\t/**\n\t * Generates an emoji's URL.\n\t *\n\t * @param emojiId - The emoji id\n\t * @param options - Optional options for the emoji\n\t */\n\tpublic emoji(emojiId: string, options?: Readonly<EmojiURLOptions>): string {\n\t\treturn this.makeURL(`/emojis/${emojiId}`, options);\n\t}\n\n\t/**\n\t * Generates a guild member avatar URL.\n\t *\n\t * @param guildId - The id of the guild\n\t * @param userId - The id of the user\n\t * @param avatarHash - The hash provided by Discord for this avatar\n\t * @param options - Optional options for the avatar\n\t */\n\tpublic guildMemberAvatar(\n\t\tguildId: string,\n\t\tuserId: string,\n\t\tavatarHash: string,\n\t\toptions?: Readonly<ImageURLOptions>,\n\t): string {\n\t\treturn this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);\n\t}\n\n\t/**\n\t * Generates a guild member banner URL.\n\t *\n\t * @param guildId - The id of the guild\n\t * @param userId - The id of the user\n\t * @param bannerHash - The hash provided by Discord for this banner\n\t * @param options - Optional options for the banner\n\t */\n\tpublic guildMemberBanner(\n\t\tguildId: string,\n\t\tuserId: string,\n\t\tbannerHash: string,\n\t\toptions?: Readonly<ImageURLOptions>,\n\t): string {\n\t\treturn this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banners/${bannerHash}`, bannerHash, options);\n\t}\n\n\t/**\n\t * Generates an icon URL, e.g. for a guild.\n\t *\n\t * @param id - The id that has the icon splash\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string {\n\t\treturn this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);\n\t}\n\n\t/**\n\t * Generates a URL for the icon of a role\n\t *\n\t * @param roleId - The id of the role that has the icon\n\t * @param roleIconHash - The hash provided by Discord for this role icon\n\t * @param options - Optional options for the role icon\n\t */\n\tpublic roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a guild invite splash URL for a guild's invite splash.\n\t *\n\t * @param guildId - The guild id that has the invite splash\n\t * @param splashHash - The hash provided by Discord for this splash\n\t * @param options - Optional options for the splash\n\t */\n\tpublic splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/splashes/${guildId}/${splashHash}`, options);\n\t}\n\n\t/**\n\t * Generates a sticker URL.\n\t *\n\t * @param stickerId - The sticker id\n\t * @param extension - The extension of the sticker\n\t * @privateRemarks\n\t * Stickers cannot have a `.webp` extension, so we default to a `.png`.\n\t * Sticker GIFs do not use the CDN base URL.\n\t */\n\tpublic sticker(stickerId: string, extension: StickerExtension = 'png'): string {\n\t\treturn this.makeURL(`/stickers/${stickerId}`, {\n\t\t\tallowedExtensions: ALLOWED_STICKER_EXTENSIONS,\n\t\t\tbase: extension === 'gif' ? this.mediaProxy : this.cdn,\n\t\t\textension,\n\t\t});\n\t}\n\n\t/**\n\t * Generates a sticker pack banner URL.\n\t *\n\t * @param bannerId - The banner id\n\t * @param options - Optional options for the banner\n\t */\n\tpublic stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);\n\t}\n\n\t/**\n\t * Generates a team icon URL for a team's icon.\n\t *\n\t * @param teamId - The team id that has the icon\n\t * @param iconHash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the icon\n\t */\n\tpublic teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);\n\t}\n\n\t/**\n\t * Generates a cover image for a guild scheduled event.\n\t *\n\t * @param scheduledEventId - The scheduled event id\n\t * @param coverHash - The hash provided by discord for this cover image\n\t * @param options - Optional options for the cover image\n\t */\n\tpublic guildScheduledEventCover(\n\t\tscheduledEventId: string,\n\t\tcoverHash: string,\n\t\toptions?: Readonly<BaseImageURLOptions>,\n\t): string {\n\t\treturn this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);\n\t}\n\n\t/**\n\t * Generates a URL for a soundboard sound.\n\t *\n\t * @param soundId - The soundboard sound id\n\t */\n\tpublic soundboardSound(soundId: string): string {\n\t\treturn `${this.cdn}${CDNRoutes.soundboardSound(soundId)}`;\n\t}\n\n\t/**\n\t * Generates a URL for a guild tag badge.\n\t *\n\t * @param guildId - The guild id\n\t * @param badgeHash - The hash of the badge\n\t * @param options - Optional options for the badge\n\t */\n\tpublic guildTagBadge(guildId: string, badgeHash: string, options?: Readonly<BaseImageURLOptions>): string {\n\t\treturn this.makeURL(`/guild-tag-badges/${guildId}/${badgeHash}`, options);\n\t}\n\n\t/**\n\t * Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.\n\t *\n\t * @param route - The base cdn route\n\t * @param hash - The hash provided by Discord for this icon\n\t * @param options - Optional options for the link\n\t */\n\tprivate dynamicMakeURL(\n\t\troute: string,\n\t\thash: string,\n\t\t{ forceStatic = false, ...options }: Readonly<ImageURLOptions> = {},\n\t): string {\n\t\treturn this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, animated: true } : options);\n\t}\n\n\t/**\n\t * Constructs the URL for the resource\n\t *\n\t * @param route - The base cdn route\n\t * @param options - The extension/size options for the link\n\t */\n\tprivate makeURL(\n\t\troute: string,\n\t\t{\n\t\t\tallowedExtensions = ALLOWED_EXTENSIONS,\n\t\t\tbase = this.cdn,\n\t\t\textension = 'webp',\n\t\t\tsize,\n\t\t\tanimated,\n\t\t}: Readonly<MakeURLOptions> = {},\n\t): string {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\textension = String(extension).toLowerCase();\n\n\t\tif (!allowedExtensions.includes(extension)) {\n\t\t\tthrow new RangeError(`Invalid extension provided: ${extension}\\nMust be one of: ${allowedExtensions.join(', ')}`);\n\t\t}\n\n\t\tif (size && !ALLOWED_SIZES.includes(size)) {\n\t\t\tthrow new RangeError(`Invalid size provided: ${size}\\nMust be one of: ${ALLOWED_SIZES.join(', ')}`);\n\t\t}\n\n\t\tconst url = new URL(`${base}${route}.${extension}`);\n\n\t\tif (animated !== undefined) {\n\t\t\turl.searchParams.set('animated', String(animated));\n\t\t}\n\n\t\tif (size) {\n\t\t\turl.searchParams.set('size', String(size));\n\t\t}\n\n\t\treturn url.toString();\n\t}\n}\n","import { getUserAgentAppendix } from '@discordjs/util';\nimport type { ImageSize } from 'discord-api-types/v10';\nimport { APIVersion } from 'discord-api-types/v10';\nimport { getDefaultStrategy } from '../../environment.js';\nimport type { RESTOptions, ResponseLike } from './types.js';\n\nexport type { ImageSize } from 'discord-api-types/v10';\n\nexport const DefaultUserAgent =\n\t`DiscordBot (https://discord.js.org, 3.0.0-pr-11006.1765450794-e636950b2)` as `DiscordBot (https://discord.js.org, ${string})`;\n\n/**\n * The default string to append onto the user agent.\n */\nexport const DefaultUserAgentAppendix = getUserAgentAppendix();\n\nexport const DefaultRestOptions = {\n\tagent: null,\n\tapi: 'https://discord.com/api',\n\tauthPrefix: 'Bot',\n\tcdn: 'https://cdn.discordapp.com',\n\theaders: {},\n\tinvalidRequestWarningInterval: 0,\n\tglobalRequestsPerSecond: 50,\n\toffset: 50,\n\trejectOnRateLimit: null,\n\tretries: 3,\n\tretryBackoff: 0,\n\ttimeout: 15_000,\n\tuserAgentAppendix: DefaultUserAgentAppendix,\n\tversion: APIVersion,\n\thashSweepInterval: 14_400_000, // 4 Hours\n\thashLifetime: 86_400_000, // 24 Hours\n\thandlerSweepInterval: 3_600_000, // 1 Hour\n\tasync makeRequest(...args): Promise<ResponseLike> {\n\t\treturn getDefaultStrategy()(...args);\n\t},\n\tmediaProxy: 'https://media.discordapp.net',\n} as const satisfies Required<RESTOptions>;\n\n/**\n * The events that the REST manager emits\n */\nexport enum RESTEvents {\n\tDebug = 'restDebug',\n\tHandlerSweep = 'handlerSweep',\n\tHashSweep = 'hashSweep',\n\tInvalidRequestWarning = 'invalidRequestWarning',\n\tRateLimited = 'rateLimited',\n\tResponse = 'response',\n}\n\nexport const ALLOWED_EXTENSIONS = ['webp', 'png', 'jpg', 'jpeg', 'gif'] as const satisfies readonly string[];\nexport const ALLOWED_STICKER_EXTENSIONS = ['png', 'json', 'gif'] as const satisfies readonly string[];\nexport const ALLOWED_SIZES: readonly number[] = [\n\t16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096,\n] satisfies readonly ImageSize[];\n\nexport type ImageExtension = (typeof ALLOWED_EXTENSIONS)[number];\nexport type StickerExtension = (typeof ALLOWED_STICKER_EXTENSIONS)[number];\n\nexport const OverwrittenMimeTypes = {\n\t// https://github.com/discordjs/discord.js/issues/8557\n\t'image/apng': 'image/png',\n} as const satisfies Readonly<Record<string, string>>;\n\nexport const BurstHandlerMajorIdKey = 'burst';\n\nexport const AUTH_UUID_NAMESPACE = 'acc82a4c-f887-417b-a69c-f74096ff7e59';\n","import type { InternalRequest, RawFile } from '../utils/types.js';\n\nexport interface DiscordErrorFieldInformation {\n\tcode: string;\n\tmessage: string;\n}\n\nexport interface DiscordErrorGroupWrapper {\n\t_errors: DiscordError[];\n}\n\nexport type DiscordError =\n\t| DiscordErrorFieldInformation\n\t| DiscordErrorGroupWrapper\n\t| string\n\t| { [k: string]: DiscordError };\n\nexport interface DiscordErrorData {\n\tcode: number;\n\terrors?: DiscordError;\n\tmessage: string;\n}\n\nexport interface OAuthErrorData {\n\terror: string;\n\terror_description?: string;\n}\n\nexport interface RequestBody {\n\tfiles: RawFile[] | undefined;\n\tjson: unknown | undefined;\n}\n\nfunction isErrorGroupWrapper(error: DiscordError): error is DiscordErrorGroupWrapper {\n\treturn Reflect.has(error as Record<string, unknown>, '_errors');\n}\n\nfunction isErrorResponse(error: DiscordError): error is DiscordErrorFieldInformation {\n\treturn typeof Reflect.get(error as Record<string, unknown>, 'message') === 'string';\n}\n\n/**\n * Represents an API error returned by Discord\n */\nexport class DiscordAPIError extends Error {\n\tpublic requestBody: RequestBody;\n\n\t/**\n\t * @param rawError - The error reported by Discord\n\t * @param code - The error code reported by Discord\n\t * @param status - The status code of the response\n\t * @param method - The method of the request that errored\n\t * @param url - The url of the request that errored\n\t * @param bodyData - The unparsed data for the request that errored\n\t */\n\tpublic constructor(\n\t\tpublic rawError: DiscordErrorData | OAuthErrorData,\n\t\tpublic code: number | string,\n\t\tpublic status: number,\n\t\tpublic method: string,\n\t\tpublic url: string,\n\t\tbodyData: Pick<InternalRequest, 'body' | 'files'>,\n\t) {\n\t\tsuper(DiscordAPIError.getMessage(rawError));\n\n\t\tthis.requestBody = { files: bodyData.files, json: bodyData.body };\n\t}\n\n\t/**\n\t * The name of the error\n\t */\n\tpublic override get name(): string {\n\t\treturn `${DiscordAPIError.name}[${this.code}]`;\n\t}\n\n\tprivate static getMessage(error: DiscordErrorData | OAuthErrorData) {\n\t\tlet flattened = '';\n\t\tif ('code' in error) {\n\t\t\tif (error.errors) {\n\t\t\t\tflattened = [...this.flattenDiscordError(error.errors)].join('\\n');\n\t\t\t}\n\n\t\t\treturn error.message && flattened\n\t\t\t\t? `${error.message}\\n${flattened}`\n\t\t\t\t: error.message || flattened || 'Unknown Error';\n\t\t}\n\n\t\treturn error.error_description ?? 'No Description';\n\t}\n\n\tprivate static *flattenDiscordError(obj: DiscordError, key = ''): IterableIterator<string> {\n\t\tif (isErrorResponse(obj)) {\n\t\t\treturn yield `${key.length ? `${key}[${obj.code}]` : `${obj.code}`}: ${obj.message}`.trim();\n\t\t}\n\n\t\tfor (const [otherKey, val] of Object.entries(obj)) {\n\t\t\tconst nextKey = otherKey.startsWith('_')\n\t\t\t\t? key\n\t\t\t\t: key\n\t\t\t\t\t? Number.isNaN(Number(otherKey))\n\t\t\t\t\t\t? `${key}.${otherKey}`\n\t\t\t\t\t\t: `${key}[${otherKey}]`\n\t\t\t\t\t: otherKey;\n\n\t\t\tif (typeof val === 'string') {\n\t\t\t\tyield val;\n\t\t\t} else if (isErrorGroupWrapper(val)) {\n\t\t\t\tfor (const error of val._errors) {\n\t\t\t\t\tyield* this.flattenDiscordError(error, nextKey);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tyield* this.flattenDiscordError(val, nextKey);\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { InternalRequest } from '../utils/types.js';\nimport type { RequestBody } from './DiscordAPIError.js';\n\n/**\n * Represents a HTTP error\n */\nexport class HTTPError extends Error {\n\tpublic requestBody: RequestBody;\n\n\tpublic override name = HTTPError.name;\n\n\t/**\n\t * @param status - The status code of the response\n\t * @param statusText - The status text of the response\n\t * @param method - The method of the request that errored\n\t * @param url - The url of the request that errored\n\t * @param bodyData - The unparsed data for the request that errored\n\t */\n\tpublic constructor(\n\t\tpublic status: number,\n\t\tstatusText: string,\n\t\tpublic method: string,\n\t\tpublic url: string,\n\t\tbodyData: Pick<InternalRequest, 'body' | 'files'>,\n\t) {\n\t\tsuper(statusText);\n\t\tthis.requestBody = { files: bodyData.files, json: bodyData.body };\n\t}\n}\n","import type { RateLimitData } from '../utils/types.js';\n\nexport class RateLimitError extends Error implements RateLimitData {\n\tpublic timeToReset: number;\n\n\tpublic limit: number;\n\n\tpublic method: string;\n\n\tpublic hash: string;\n\n\tpublic url: string;\n\n\tpublic route: string;\n\n\tpublic majorParameter: string;\n\n\tpublic global: boolean;\n\n\tpublic retryAfter: number;\n\n\tpublic sublimitTimeout: number;\n\n\tpublic scope: RateLimitData['scope'];\n\n\tpublic constructor(data: RateLimitData) {\n\t\tsuper();\n\t\tthis.timeToReset = data.timeToReset;\n\t\tthis.limit = data.limit;\n\t\tthis.method = data.method;\n\t\tthis.hash = data.hash;\n\t\tthis.url = data.url;\n\t\tthis.route = data.route;\n\t\tthis.majorParameter = data.majorParameter;\n\t\tthis.global = data.global;\n\t\tthis.retryAfter = data.retryAfter;\n\t\tthis.sublimitTimeout = data.sublimitTimeout;\n\t\tthis.scope = data.scope;\n\t}\n\n\t/**\n\t * The name of the error\n\t */\n\tpublic override get name(): string {\n\t\treturn `${RateLimitError.name}[${this.route}]`;\n\t}\n}\n","import { Collection } from '@discordjs/collection';\nimport { DiscordSnowflake } from '@sapphire/snowflake';\nimport { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';\nimport { filetypeinfo } from 'magic-bytes.js';\nimport type { RequestInit, BodyInit, Dispatcher } from 'undici';\nimport { v5 as uuidV5 } from 'uuid';\nimport { CDN } from './CDN.js';\nimport { BurstHandler } from './handlers/BurstHandler.js';\nimport { SequentialHandler } from './handlers/SequentialHandler.js';\nimport type { IHandler } from './interfaces/Handler.js';\nimport {\n\tAUTH_UUID_NAMESPACE,\n\tBurstHandlerMajorIdKey,\n\tDefaultRestOptions,\n\tDefaultUserAgent,\n\tOverwrittenMimeTypes,\n\tRESTEvents,\n} from './utils/constants.js';\nimport { RequestMethod } from './utils/types.js';\nimport type {\n\tRESTOptions,\n\tResponseLike,\n\tRestEvents,\n\tHashData,\n\tInternalRequest,\n\tRouteLike,\n\tRequestHeaders,\n\tRouteData,\n\tRequestData,\n\tAuthData,\n} from './utils/types.js';\nimport { isBufferLike, parseResponse } from './utils/utils.js';\n\n/**\n * Represents the class that manages handlers for endpoints\n */\nexport class REST extends AsyncEventEmitter<RestEvents> {\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\n\tpublic readonly cdn: CDN;\n\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#token: string | null = null;\n\n\tprivate hashTimer!: NodeJS.Timeout | number;\n\n\tprivate handlerTimer!: NodeJS.Timeout | number;\n\n\tpublic readonly options: RESTOptions;\n\n\tpublic constructor(options: Partial<RESTOptions> = {}) {\n\t\tconsole.log('even rest got something new ‼️ 🗣️ 🔥');\n\n\t\tsuper();\n\t\tthis.cdn = new CDN(options);\n\t\tthis.options = { ...DefaultRestOptions, ...options };\n\t\tthis.globalRemaining = Math.max(1, 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\t// eslint-disable-next-line unicorn/consistent-function-scoping\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 !== Number.POSITIVE_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((val, key) => {\n\t\t\t\t\t// `-1` indicates a global hash\n\t\t\t\t\tif (val.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 - val.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(key, val);\n\n\t\t\t\t\t\t// Emit debug information\n\t\t\t\t\t\tthis.emit(RESTEvents.Debug, `[REST] Hash ${val.value} for ${key} swept due to lifetime being exceeded`);\n\t\t\t\t\t}\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);\n\n\t\t\tthis.hashTimer.unref?.();\n\t\t}\n\n\t\tif (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Number.POSITIVE_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((val, key) => {\n\t\t\t\t\tconst { inactive } = val;\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(key, val);\n\t\t\t\t\t\tthis.emit(RESTEvents.Debug, `[REST] Handler ${val.id} for ${key} swept due to being inactive`);\n\t\t\t\t\t}\n\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);\n\n\t\t\tthis.handlerTimer.unref?.();\n\t\t}\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 async 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 async 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 async 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 async 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 async 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.queueRequest(options);\n\t\treturn parseResponse(response);\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 * @returns The response from the api request\n\t */\n\tpublic async queueRequest(request: InternalRequest): Promise<ResponseLike> {\n\t\t// Generalize the endpoint to its route data\n\t\tconst routeId = REST.generateRouteData(request.fullRoute, request.method);\n\t\tconst customAuth = typeof request.auth === 'object' && request.auth.token !== this.#token;\n\t\tconst auth = customAuth ? uuidV5((request.auth as AuthData).token, AUTH_UUID_NAMESPACE) : request.auth !== false;\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}${customAuth ? `:${auth}` : ''}`) ?? {\n\t\t\tvalue: `Global(${request.method}:${routeId.bucketRoute}${customAuth ? `:${auth}` : ''})`,\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,\n\t\t\tsignal: request.signal,\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 * @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 =\n\t\t\tmajorParameter === BurstHandlerMajorIdKey\n\t\t\t\t? new BurstHandler(this, hash, majorParameter)\n\t\t\t\t: 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<{ fetchOptions: RequestInit; url: string }> {\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\tif (typeof request.auth === 'object') {\n\t\t\t\theaders.Authorization = `${request.auth.prefix ?? this.options.authPrefix} ${request.auth.token}`;\n\t\t\t} else {\n\t\t\t\t// If we haven't received a token, throw an error\n\t\t\t\tif (!this.#token) {\n\t\t\t\t\tthrow new Error('Expected token to be set for this request, but none was present');\n\t\t\t\t}\n\n\t\t\t\theaders.Authorization = `${this.options.authPrefix} ${this.#token}`;\n\t\t\t}\n\t\t}\n\n\t\t// If a reason was set, set its 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/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/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 (isBufferLike(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\tlet contentType = file.contentType;\n\n\t\t\t\t\tif (!contentType) {\n\t\t\t\t\t\tconst [parsedType] = filetypeinfo(file.data);\n\n\t\t\t\t\t\tif (parsedType) {\n\t\t\t\t\t\t\tcontentType =\n\t\t\t\t\t\t\t\tOverwrittenMimeTypes[parsedType.mime as keyof typeof OverwrittenMimeTypes] ??\n\t\t\t\t\t\t\t\tparsedType.mime ??\n\t\t\t\t\t\t\t\t'application/octet-stream';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\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\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, eqeqeq\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, eqeqeq\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\tconst method = request.method.toUpperCase();\n\n\t\t// The non null assertions in the following block are due to exactOptionalPropertyTypes, they have been tested to work with undefined\n\t\tconst fetchOptions: RequestInit = {\n\t\t\t// Set body to null on get / head requests. This does not follow fetch spec (likely because it causes subtle bugs) but is aligned with what request was doing\n\t\t\tbody: ['GET', 'HEAD'].includes(method) ? null : finalBody!,\n\t\t\theaders: { ...request.headers, ...additionalHeaders, ...headers } as Record<string, string>,\n\t\t\tmethod,\n\t\t\t// Prioritize setting an agent per request, use the agent for this instance otherwise.\n\t\t\tdispatcher: request.dispatcher ?? this.agent ?? undefined!,\n\t\t};\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 * @internal\n\t */\n\tprivate static generateRouteData(endpoint: RouteLike, method: RequestMethod): RouteData {\n\t\tif (endpoint.startsWith('/interactions/') && endpoint.endsWith('/callback')) {\n\t\t\treturn {\n\t\t\t\tmajorParameter: BurstHandlerMajorIdKey,\n\t\t\t\tbucketRoute: '/interactions/:id/:token/callback',\n\t\t\t\toriginal: endpoint,\n\t\t\t};\n\t\t}\n\n\t\tconst majorIdMatch = /(?:^\\/webhooks\\/(\\d{17,19}\\/[^/?]+))|(?:^\\/(?:channels|guilds|webhooks)\\/(\\d{17,19}))/.exec(\n\t\t\tendpoint,\n\t\t);\n\n\t\t// Get the major id or id + token for this route - global otherwise\n\t\tconst majorId = majorIdMatch?.[2] ?? majorIdMatch?.[1] ?? 'global';\n\n\t\tconst baseRoute = endpoint\n\t\t\t// Strip out all ids\n\t\t\t.replaceAll(/\\d{17,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\t\t\t// Strip out webhook tokens\n\t\t\t.replace(/\\/webhooks\\/:id\\/[^/?]+/, '/webhooks/:id/:token');\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{17,19}$/.exec(endpoint)![0]!;\n\t\t\tconst timestamp = DiscordSnowflake.timestampFrom(id);\n\t\t\tif (Date.now() - timestamp > 1_000 * 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","import type { Readable } from 'node:stream';\nimport type { ReadableStream } from 'node:stream/web';\nimport type { Collection } from '@discordjs/collection';\nimport type { Awaitable, RawFile } from '@discordjs/util';\nimport type { Agent, Dispatcher, RequestInit, BodyInit, Response } from 'undici';\nimport type { IHandler } from '../interfaces/Handler.js';\n\nexport interface RestEvents {\n\thandlerSweep: [sweptHandlers: Collection<string, IHandler>];\n\thashSweep: [sweptHashes: Collection<string, HashData>];\n\tinvalidRequestWarning: [invalidRequestInfo: InvalidRequestWarningData];\n\trateLimited: [rateLimitInfo: RateLimitData];\n\tresponse: [request: APIRequest, response: ResponseLike];\n\trestDebug: [info: string];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface RestEventsMap extends RestEvents {}\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 | null;\n\t/**\n\t * The base api path, without version\n\t *\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: 'Bearer' | 'Bot';\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 * 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 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\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 4h)\n\t *\n\t * @defaultValue `14_400_000`\n\t */\n\thashSweepInterval: number;\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 * The method called to perform the actual HTTP request given a url and web `fetch` options\n\t * For example, to use global fetch, simply provide `makeRequest: fetch`\n\t */\n\tmakeRequest(url: string, init: RequestInit): Promise<ResponseLike>;\n\t/**\n\t * The media proxy path\n\t *\n\t * @defaultValue `'https://media.discordapp.net'`\n\t */\n\tmediaProxy: string;\n\t/**\n\t * The extra offset to add to rate limits in milliseconds\n\t *\n\t * @defaultValue `50`\n\t */\n\toffset: GetRateLimitOffsetFunction | 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: RateLimitQueueFilter | string[] | 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 exponentially add before retrying a 5xx or aborted request\n\t *\n\t * @defaultValue `0`\n\t */\n\tretryBackoff: GetRetryBackoffFunction | 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: GetTimeoutFunction | number;\n\t/**\n\t * Extra information to add to the user agent\n\t *\n\t * @defaultValue DefaultUserAgentAppendix\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}\n\n/**\n * Data emitted on `RESTEvents.RateLimited`\n */\nexport interface RateLimitData {\n\t/**\n\t * Whether the rate limit that was reached was the global limit\n\t */\n\tglobal: boolean;\n\t/**\n\t * The bucket hash for this request\n\t */\n\thash: string;\n\t/**\n\t * The amount of requests we can perform before locking requests\n\t */\n\tlimit: number;\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 * The HTTP method being performed\n\t */\n\tmethod: string;\n\t/**\n\t * The time, in milliseconds, that will need to pass before this specific request can be retried\n\t */\n\tretryAfter: number;\n\t/**\n\t * The route being hit in this request\n\t */\n\troute: string;\n\t/**\n\t * The scope of the rate limit that was hit.\n\t *\n\t * This can be `user` for rate limits that are per client, `global` for rate limits that affect all clients or `shared` for rate limits that\n\t * are shared per resource.\n\t */\n\tscope: 'global' | 'shared' | 'user';\n\t/**\n\t * The time, in milliseconds, that will need to pass before the sublimit lock for the route resets, and requests that fall under a sublimit\n\t * can be retried\n\t *\n\t * This is only present on certain sublimits, and `0` otherwise\n\t */\n\tsublimitTimeout: number;\n\t/**\n\t * The time, in milliseconds, until the route's request-lock is reset\n\t */\n\ttimeToReset: number;\n\t/**\n\t * The full URL for this request\n\t */\n\turl: string;\n}\n\n/**\n * A function that determines whether the rate limit hit should throw an Error\n */\nexport type RateLimitQueueFilter = (rateLimitData: RateLimitData) => Awaitable<boolean>;\n\n/**\n * A function that determines the rate limit offset for a given request.\n */\nexport type GetRateLimitOffsetFunction = (route: string) => number;\n\n/**\n * A function that determines the backoff for a retry for a given request.\n *\n * @param route - The route that has encountered a server-side error\n * @param statusCode - The status code received or `null` if aborted\n * @param retryCount - The number of retries that have been attempted so far. The first call will be `0`\n * @param requestBody - The body that was sent with the request\n * @returns The delay for the current request or `null` to throw an error instead of retrying\n */\nexport type GetRetryBackoffFunction = (\n\troute: string,\n\tstatusCode: number | null,\n\tretryCount: number,\n\trequestBody: unknown,\n) => number | null;\n\n/**\n * A function that determines the timeout for a given request.\n *\n * @param route - The route that is being processed\n * @param body - The body that will be sent with the request\n */\nexport type GetTimeoutFunction = (route: string, body: unknown) => number;\n\nexport interface APIRequest {\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 HTTP method used in this request\n\t */\n\tmethod: string;\n\t/**\n\t * Additional HTTP options for this request\n\t */\n\toptions: RequestInit;\n\t/**\n\t * The full path used to make the request\n\t */\n\tpath: RouteLike;\n\t/**\n\t * The number of times this request has been attempted\n\t */\n\tretries: number;\n\t/**\n\t * The API route identifying the ratelimit for this request\n\t */\n\troute: string;\n}\n\nexport interface ResponseLike extends Pick<\n\tResponse,\n\t'arrayBuffer' | 'bodyUsed' | 'headers' | 'json' | 'ok' | 'status' | 'statusText' | 'text'\n> {\n\tbody: Readable | ReadableStream | null;\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 type { RawFile } from '@discordjs/util';\n\nexport interface AuthData {\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 `REST.options.authPrefix`\n\t */\n\tprefix?: 'Bearer' | 'Bot';\n\t/**\n\t * The authorization token to use for this request\n\t */\n\ttoken: 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 * Alternate authorization data to use for this request only, or `false` to disable the Authorization header.\n\t * When making a request to a route that includes a token (such as interactions or webhooks), set to `false`\n\t * to avoid accidentally unsetting the instance token if a 401 is encountered.\n\t *\n\t * @defaultValue `true`\n\t */\n\tauth?: AuthData | boolean | undefined;\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 | undefined;\n\t/**\n\t * The signal to abort the queue entry or the REST call, where applicable\n\t */\n\tsignal?: AbortSignal | undefined;\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 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 */\nexport interface InternalRequest extends RequestData {\n\tfullRoute: RouteLike;\n\tmethod: RequestMethod;\n}\n\nexport interface HandlerRequestData extends Pick<InternalRequest, 'body' | 'files' | 'signal'> {\n\tauth: boolean | string;\n}\n\n/**\n * Parsed route data for an endpoint\n */\nexport interface RouteData {\n\tbucketRoute: string;\n\tmajorParameter: string;\n\toriginal: RouteLike;\n}\n\n/**\n * Represents a hash and its associated fields\n */\nexport interface HashData {\n\tlastAccess: number;\n\tvalue: string;\n}\n","import type { Buffer } from 'node:buffer';\nimport type { RESTPatchAPIChannelJSONBody, Snowflake } from 'discord-api-types/v10';\nimport type { REST } from '../REST.js';\nimport { RateLimitError } from '../errors/RateLimitError.js';\nimport { RequestMethod } from './types.js';\nimport type {\n\tGetRateLimitOffsetFunction,\n\tGetRetryBackoffFunction,\n\tGetTimeoutFunction,\n\tRateLimitData,\n\tResponseLike,\n} from './types.js';\n\nfunction serializeSearchParam(value: unknown): string | null {\n\t// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check\n\tswitch (typeof value) {\n\t\tcase 'string':\n\t\t\treturn value;\n\t\tcase 'number':\n\t\tcase 'bigint':\n\t\tcase 'boolean':\n\t\t\treturn value.toString();\n\t\tcase 'object':\n\t\t\tif (value === null) return null;\n\t\t\tif (value instanceof Date) {\n\t\t\t\treturn Number.isNaN(value.getTime()) ? null : value.toISOString();\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\tif (typeof value.toString === 'function' && value.toString !== Object.prototype.toString) return value.toString();\n\t\t\treturn null;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Creates and populates an URLSearchParams instance from an object, stripping\n * out null and undefined values, while also coercing non-strings to strings.\n *\n * @param options - The options to use\n * @returns A populated URLSearchParams instance\n */\nexport function makeURLSearchParams<OptionsType extends object>(options?: Readonly<OptionsType>) {\n\tconst params = new URLSearchParams();\n\tif (!options) return params;\n\n\tfor (const [key, value] of Object.entries(options)) {\n\t\tconst serialized = serializeSearchParam(value);\n\t\tif (serialized !== null) params.append(key, serialized);\n\t}\n\n\treturn params;\n}\n\n/**\n * Converts the response to usable data\n *\n * @param res - The fetch response\n */\nexport async function parseResponse(res: ResponseLike): Promise<unknown> {\n\tif (res.headers.get('Content-Type')?.startsWith('application/json')) {\n\t\treturn res.json();\n\t}\n\n\treturn res.arrayBuffer();\n}\n\n/**\n * Check whether a request falls under a sublimit\n *\n * @param bucketRoute - The buckets route identifier\n * @param body - The options provided as JSON data\n * @param method - The HTTP method that will be used to make the request\n * @returns Whether the request falls under a sublimit\n */\nexport function hasSublimit(bucketRoute: string, body?: unknown, method?: string): boolean {\n\t// TODO: Update for new sublimits\n\t// Currently known sublimits:\n\t// Editing channel `name` or `topic`\n\tif (bucketRoute === '/channels/:id') {\n\t\tif (typeof body !== 'object' || body === null) return false;\n\t\t// This should never be a POST body, but just in case\n\t\tif (method !== RequestMethod.Patch) return false;\n\t\tconst castedBody = body as RESTPatchAPIChannelJSONBody;\n\t\treturn ['name', 'topic'].some((key) => Reflect.has(castedBody, key));\n\t}\n\n\t// If we are checking if a request has a sublimit on a route not checked above, sublimit all requests to avoid a flood of 429s\n\treturn true;\n}\n\n/**\n * Check whether an error indicates that a retry can be attempted\n *\n * @param error - The error thrown by the network request\n * @returns Whether the error indicates a retry should be attempted\n */\nexport function shouldRetry(error: Error | NodeJS.ErrnoException) {\n\t// Retry for possible timed out requests\n\tif (error.name === 'AbortError') return true;\n\t// Downlevel ECONNRESET to retry as it may be recoverable\n\treturn ('code' in error && error.code === 'ECONNRESET') || error.message.includes('ECONNRESET');\n}\n\n/**\n * Determines whether the request should be queued or whether a RateLimitError should be thrown\n *\n * @internal\n */\nexport async function onRateLimit(manager: REST, rateLimitData: RateLimitData) {\n\tconst { options } = manager;\n\tif (!options.rejectOnRateLimit) return;\n\n\tconst shouldThrow =\n\t\ttypeof options.rejectOnRateLimit === 'function'\n\t\t\t? await options.rejectOnRateLimit(rateLimitData)\n\t\t\t: options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase()));\n\tif (shouldThrow) {\n\t\tthrow new RateLimitError(rateLimitData);\n\t}\n}\n\n/**\n * Calculates the default avatar index for a given user id.\n *\n * @param userId - The user id to calculate the default avatar index for\n */\nexport function calculateUserDefaultAvatarIndex(userId: Snowflake) {\n\treturn Number(BigInt(userId) >> 22n) % 6;\n}\n\n/**\n * Sleeps for a given amount of time.\n *\n * @param ms - The amount of time (in milliseconds) to sleep for\n */\nexport async function sleep(ms: number): Promise<void> {\n\treturn new Promise<void>((resolve) => {\n\t\tsetTimeout(() => resolve(), ms);\n\t});\n}\n\n/**\n * Verifies that a value is a buffer-like object.\n *\n * @param value - The value to check\n */\nexport function isBufferLike(value: unknown): value is ArrayBuffer | Buffer | Uint8Array | Uint8ClampedArray {\n\treturn value instanceof ArrayBuffer || value instanceof Uint8Array || value instanceof Uint8ClampedArray;\n}\n\n/**\n * Normalizes the offset for rate limits. Applies a Math.max(0, N) to prevent negative offsets,\n * also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeRateLimitOffset(offset: GetRateLimitOffsetFunction | number, route: string): number {\n\tif (typeof offset === 'number') {\n\t\treturn Math.max(0, offset);\n\t}\n\n\tconst result = offset(route);\n\treturn Math.max(0, result);\n}\n\n/**\n * Normalizes the retry backoff used to add delay to retrying 5xx and aborted requests.\n * Applies a Math.max(0, N) to prevent negative backoffs, also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeRetryBackoff(\n\tretryBackoff: GetRetryBackoffFunction | number,\n\troute: string,\n\tstatusCode: number | null,\n\tretryCount: number,\n\trequestBody: unknown,\n): number | null {\n\tif (typeof retryBackoff === 'number') {\n\t\treturn Math.max(0, retryBackoff) * (1 << retryCount);\n\t}\n\n\t// No need to Math.max as we'll only set the sleep timer if the value is > 0 (and not equal)\n\treturn retryBackoff(route, statusCode, retryCount, requestBody);\n}\n\n/**\n * Normalizes the timeout for aborting requests. Applies a Math.max(0, N) to prevent negative timeouts,\n * also deals with callbacks.\n *\n * @internal\n */\nexport function normalizeTimeout(timeout: GetTimeoutFunction | number, route: string, requestBody: unknown): number {\n\tif (typeof timeout === 'number') {\n\t\treturn Math.max(0, timeout);\n\t}\n\n\tconst result = timeout(route, requestBody);\n\treturn Math.max(0, result);\n}\n","/* eslint-disable n/prefer-global/process */\n\nimport type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { DiscordErrorData, OAuthErrorData } from '../errors/DiscordAPIError.js';\nimport { DiscordAPIError } from '../errors/DiscordAPIError.js';\nimport { HTTPError } from '../errors/HTTPError.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { ResponseLike, HandlerRequestData, RouteData } from '../utils/types.js';\nimport { normalizeRetryBackoff, normalizeTimeout, parseResponse, shouldRetry, sleep } from '../utils/utils.js';\n\nlet authFalseWarningEmitted = false;\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\n/**\n * Increment the invalid request count and emit warning if necessary\n *\n * @internal\n */\nexport function incrementInvalidCount(manager: REST) {\n\tif (!invalidCountResetTime || invalidCountResetTime < Date.now()) {\n\t\tinvalidCountResetTime = Date.now() + 1_000 * 60 * 10;\n\t\tinvalidCount = 0;\n\t}\n\n\tinvalidCount++;\n\n\tconst emitInvalid =\n\t\tmanager.options.invalidRequestWarningInterval > 0 &&\n\t\tinvalidCount % manager.options.invalidRequestWarningInterval === 0;\n\tif (emitInvalid) {\n\t\t// Let library users know periodically about invalid requests\n\t\tmanager.emit(RESTEvents.InvalidRequestWarning, {\n\t\t\tcount: invalidCount,\n\t\t\tremainingTime: invalidCountResetTime - Date.now(),\n\t\t});\n\t}\n}\n\n/**\n * Performs the actual network request for a request handler\n *\n * @param manager - The manager that holds options and emits informational events\n * @param routeId - The generalized api route with literal ids for major parameters\n * @param url - The fully resolved url to make the request to\n * @param options - The fetch options needed to make the request\n * @param requestData - Extra data from the user's request needed for errors and additional processing\n * @param retries - The number of retries this request has already attempted (recursion occurs on the handler)\n * @returns The respond from the network or `null` when the request should be retried\n * @internal\n */\nexport async function makeNetworkRequest(\n\tmanager: REST,\n\trouteId: RouteData,\n\turl: string,\n\toptions: RequestInit,\n\trequestData: HandlerRequestData,\n\tretries: number,\n) {\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(\n\t\t() => controller.abort(),\n\t\tnormalizeTimeout(manager.options.timeout, routeId.bucketRoute, requestData.body),\n\t);\n\tif (requestData.signal) {\n\t\t// If the user signal was aborted, abort the controller, else abort the local signal.\n\t\t// The reason why we don't re-use the user's signal, is because users may use the same signal for multiple\n\t\t// requests, and we do not want to cause unexpected side-effects.\n\t\tif (requestData.signal.aborted) controller.abort();\n\t\telse requestData.signal.addEventListener('abort', () => controller.abort());\n\t}\n\n\tlet res: ResponseLike;\n\ttry {\n\t\tres = await manager.options.makeRequest(url, { ...options, signal: controller.signal });\n\t} catch (error: unknown) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\t// Retry the specified number of times if needed\n\t\tif (shouldRetry(error) && retries !== manager.options.retries) {\n\t\t\tconst backoff = normalizeRetryBackoff(\n\t\t\t\tmanager.options.retryBackoff,\n\t\t\t\trouteId.bucketRoute,\n\t\t\t\tnull,\n\t\t\t\tretries,\n\t\t\t\trequestData.body,\n\t\t\t);\n\t\t\tif (backoff === null) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (backoff > 0) {\n\t\t\t\tawait sleep(backoff);\n\t\t\t}\n\n\t\t\t// Retry is handled by the handler upon receiving null\n\t\t\treturn null;\n\t\t}\n\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\n\tif (manager.listenerCount(RESTEvents.Response)) {\n\t\tmanager.emit(\n\t\t\tRESTEvents.Response,\n\t\t\t{\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\tpath: routeId.original,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\toptions,\n\t\t\t\tdata: requestData,\n\t\t\t\tretries,\n\t\t\t},\n\t\t\tres instanceof Response ? res.clone() : { ...res },\n\t\t);\n\t}\n\n\treturn res;\n}\n\n/**\n * Handles 5xx and 4xx errors (not 429's) conventionally. 429's should be handled before calling this function\n *\n * @param manager - The manager that holds options and emits informational events\n * @param res - The response received from {@link makeNetworkRequest}\n * @param method - The method used to make the request\n * @param url - The fully resolved url to make the request to\n * @param requestData - Extra data from the user's request needed for errors and additional processing\n * @param retries - The number of retries this request has already attempted (recursion occurs on the handler)\n * @param routeId - The generalized API route with literal ids for major parameters\n * @returns The response if the status code is not handled or null to request a retry\n */\nexport async function handleErrors(\n\tmanager: REST,\n\tres: ResponseLike,\n\tmethod: string,\n\turl: string,\n\trequestData: HandlerRequestData,\n\tretries: number,\n\trouteId: RouteData,\n) {\n\tconst status = res.status;\n\tif (status >= 500 && status < 600) {\n\t\t// Retry the specified number of times for possible server side issues\n\t\tif (retries !== manager.options.retries) {\n\t\t\tconst backoff = normalizeRetryBackoff(\n\t\t\t\tmanager.options.retryBackoff,\n\t\t\t\trouteId.bucketRoute,\n\t\t\t\tstatus,\n\t\t\t\tretries,\n\t\t\t\trequestData.body,\n\t\t\t);\n\t\t\tif (backoff === null) {\n\t\t\t\tthrow new HTTPError(status, res.statusText, method, url, requestData);\n\t\t\t}\n\n\t\t\tif (backoff > 0) {\n\t\t\t\tawait sleep(backoff);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t// We are out of retries, throw an error\n\t\tthrow new HTTPError(status, res.statusText, method, url, requestData);\n\t} else {\n\t\t// Handle possible malformed requests\n\t\tif (status >= 400 && status < 500) {\n\t\t\t// The request will not succeed for some reason, parse the error returned from the api\n\t\t\tconst data = (await parseResponse(res)) as DiscordErrorData | OAuthErrorData;\n\t\t\tconst isDiscordError = 'code' in data;\n\n\t\t\t// If we receive this status code, it means the token we had is no longer valid.\n\t\t\tif (status === 401 && requestData.auth === true) {\n\t\t\t\tif (isDiscordError && data.code !== 0 && !authFalseWarningEmitted) {\n\t\t\t\t\tconst errorText = `Encountered HTTP 401 with error ${data.code}: ${data.message}. Your token will be removed from this REST instance. If you are using @discordjs/rest directly, consider adding 'auth: false' to the request. Open an issue with your library if not.`;\n\t\t\t\t\t// Use emitWarning if possible, probably not available in edge / web\n\t\t\t\t\tif (typeof globalThis.process !== 'undefined' && typeof globalThis.process.emitWarning === 'function') {\n\t\t\t\t\t\tglobalThis.process.emitWarning(errorText);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(errorText);\n\t\t\t\t\t}\n\n\t\t\t\t\tauthFalseWarningEmitted = true;\n\t\t\t\t}\n\n\t\t\t\tmanager.setToken(null!);\n\t\t\t}\n\n\t\t\t// throw the API error\n\t\t\tthrow new DiscordAPIError(data, isDiscordError ? data.code : data.error, status, method, url, requestData);\n\t\t}\n\n\t\treturn res;\n\t}\n}\n","import type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { IHandler } from '../interfaces/Handler.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { ResponseLike, HandlerRequestData, RouteData, RateLimitData } from '../utils/types.js';\nimport { normalizeRateLimitOffset, onRateLimit, sleep } from '../utils/utils.js';\nimport { handleErrors, incrementInvalidCount, makeNetworkRequest } from './Shared.js';\n\n/**\n * The structure used to handle burst requests for a given bucket.\n * Burst requests have no ratelimit handling but allow for pre- and post-processing\n * of data in the same manner as sequentially queued requests.\n *\n * @remarks\n * This queue may still emit a rate limit error if an unexpected 429 is hit\n */\nexport class BurstHandler implements IHandler {\n\t/**\n\t * {@inheritdoc IHandler.id}\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * {@inheritDoc IHandler.inactive}\n\t */\n\tpublic inactive = 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: REST,\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 * 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 * {@inheritDoc IHandler.queueRequest}\n\t */\n\tpublic async queueRequest(\n\t\trouteId: RouteData,\n\t\turl: string,\n\t\toptions: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t): Promise<ResponseLike> {\n\t\treturn this.runRequest(routeId, url, options, requestData);\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<ResponseLike> {\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst res = await makeNetworkRequest(this.manager, routeId, url, options, requestData, retries);\n\n\t\t// Retry requested\n\t\tif (res === null) {\n\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t}\n\n\t\tconst status = res.status;\n\t\tlet retryAfter = 0;\n\t\tconst retry = res.headers.get('Retry-After');\n\n\t\t// Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\t\tif (retry) retryAfter = Number(retry) * 1_000 + offset;\n\n\t\t// Count the invalid requests\n\t\tif (status === 401 || status === 403 || status === 429) {\n\t\t\tincrementInvalidCount(this.manager);\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// Unexpected ratelimit\n\t\t\tconst isGlobal = res.headers.has('X-RateLimit-Global');\n\t\t\tconst scope = (res.headers.get('X-RateLimit-Scope') ?? 'user') as RateLimitData['scope'];\n\n\t\t\tawait onRateLimit(this.manager, {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit: Number.POSITIVE_INFINITY,\n\t\t\t\ttimeToReset: retryAfter,\n\t\t\t\tretryAfter,\n\t\t\t\tsublimitTimeout: 0,\n\t\t\t\tscope,\n\t\t\t});\n\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}`,\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 : ${Number.POSITIVE_INFINITY}`,\n\t\t\t\t\t` Retry After : ${retryAfter}ms`,\n\t\t\t\t\t` Sublimit : None`,\n\t\t\t\t\t` Scope : ${scope}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\n\t\t\t// We are bypassing all other limits, but an encountered limit should be respected (it's probably a non-punished rate limit anyways)\n\t\t\tawait sleep(retryAfter);\n\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 {\n\t\t\tconst handled = await handleErrors(this.manager, res, method, url, requestData, retries, routeId);\n\t\t\tif (handled === null) {\n\t\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\treturn handled;\n\t\t}\n\t}\n}\n","import { AsyncQueue } from '@sapphire/async-queue';\nimport type { RequestInit } from 'undici';\nimport type { REST } from '../REST.js';\nimport type { IHandler } from '../interfaces/Handler.js';\nimport { RESTEvents } from '../utils/constants.js';\nimport type { RateLimitData, ResponseLike, HandlerRequestData, RouteData } from '../utils/types.js';\nimport { hasSublimit, normalizeRateLimitOffset, onRateLimit, sleep } from '../utils/utils.js';\nimport { handleErrors, incrementInvalidCount, makeNetworkRequest } from './Shared.js';\n\nconst enum QueueType {\n\tStandard,\n\tSublimit,\n}\n\n/**\n * The structure used to handle sequential 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 = Number.POSITIVE_INFINITY;\n\n\t/**\n\t * The interface used to sequence async requests sequentially\n\t */\n\t#asyncQueue = new AsyncQueue();\n\n\t/**\n\t * The interface used to sequence sublimited async requests sequentially\n\t */\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#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#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: REST,\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 getTimeToReset(routeId: RouteData): number {\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\t\treturn this.reset + 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);\n\t\tthis.manager.globalDelay = null;\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t): Promise<ResponseLike> {\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\n\t\t// Wait for any previous requests to be completed before this one is run\n\t\tawait queue.wait({ signal: requestData.signal });\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\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\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: RequestInit,\n\t\trequestData: HandlerRequestData,\n\t\tretries = 0,\n\t): Promise<ResponseLike> {\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\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\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 + 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\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\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\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.getTimeToReset(routeId);\n\t\t\t\tdelay = sleep(timeout);\n\t\t\t}\n\n\t\t\tconst rateLimitData: RateLimitData = {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod: options.method ?? 'get',\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit,\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tretryAfter: timeout,\n\t\t\t\tsublimitTimeout: 0,\n\t\t\t\tscope: 'user',\n\t\t\t};\n\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 onRateLimit(this.manager, rateLimitData);\n\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\n\t\t\t// Wait the remaining time left before the rate limit resets\n\t\t\tawait delay;\n\t\t}\n\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() + 1_000;\n\t\t\tthis.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;\n\t\t}\n\n\t\tthis.manager.globalRemaining--;\n\n\t\tconst method = options.method ?? 'get';\n\n\t\tconst res = await makeNetworkRequest(this.manager, routeId, url, options, requestData, retries);\n\n\t\t// Retry requested\n\t\tif (res === null) {\n\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t}\n\n\t\tconst status = res.status;\n\t\tlet retryAfter = 0;\n\n\t\tconst limit = res.headers.get('X-RateLimit-Limit');\n\t\tconst remaining = res.headers.get('X-RateLimit-Remaining');\n\t\tconst reset = res.headers.get('X-RateLimit-Reset-After');\n\t\tconst hash = res.headers.get('X-RateLimit-Bucket');\n\t\tconst retry = res.headers.get('Retry-After');\n\t\tconst scope = (res.headers.get('X-RateLimit-Scope') ?? 'user') as RateLimitData['scope'];\n\n\t\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\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) : Number.POSITIVE_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) * 1_000 + Date.now() + 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) * 1_000 + 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(\n\t\t\t\t`${method}:${routeId.bucketRoute}${typeof requestData.auth === 'string' ? `:${requestData.auth}` : ''}`,\n\t\t\t\t{ value: hash, lastAccess: Date.now() },\n\t\t\t);\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(\n\t\t\t\t`${method}:${routeId.bucketRoute}${typeof requestData.auth === 'string' ? `:${requestData.auth}` : ''}`,\n\t\t\t);\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.has('X-RateLimit-Global')) {\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\tincrementInvalidCount(this.manager);\n\t\t}\n\n\t\tif (res.ok) {\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\tconst offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);\n\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 + 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.getTimeToReset(routeId);\n\t\t\t}\n\n\t\t\tawait onRateLimit(this.manager, {\n\t\t\t\tglobal: isGlobal,\n\t\t\t\tmethod,\n\t\t\t\turl,\n\t\t\t\troute: routeId.bucketRoute,\n\t\t\t\tmajorParameter: this.majorParameter,\n\t\t\t\thash: this.hash,\n\t\t\t\tlimit,\n\t\t\t\ttimeToReset: timeout,\n\t\t\t\tretryAfter,\n\t\t\t\tsublimitTimeout: sublimitTimeout ?? 0,\n\t\t\t\tscope,\n\t\t\t});\n\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\t` Scope : ${scope}`,\n\t\t\t\t].join('\\n'),\n\t\t\t);\n\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\n\t\t\t\tthis.#sublimitPromise?.resolve();\n\t\t\t\tthis.#sublimitPromise = null;\n\t\t\t\tawait sleep(sublimitTimeout);\n\t\t\t\tlet resolve: () => void;\n\t\t\t\t// eslint-disable-next-line promise/param-names, no-promise-executor-return\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\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 {\n\t\t\tconst handled = await handleErrors(this.manager, res, method, url, requestData, retries, routeId);\n\t\t\tif (handled === null) {\n\t\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\t\treturn this.runRequest(routeId, url, options, requestData, ++retries);\n\t\t\t}\n\n\t\t\treturn handled;\n\t\t}\n\t}\n}\n","export * from './lib/CDN.js';\nexport * from './lib/errors/DiscordAPIError.js';\nexport * from './lib/errors/HTTPError.js';\nexport * from './lib/errors/RateLimitError.js';\nexport type * from './lib/interfaces/Handler.js';\nexport * from './lib/REST.js';\nexport * from './lib/utils/constants.js';\nexport * from './lib/utils/types.js';\nexport { calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse } from './lib/utils/utils.js';\n\n/**\n * The {@link https://github.com/discordjs/discord.js/blob/main/packages/rest#readme | @discordjs/rest} version\n * that you are currently using.\n */\n// This needs to explicitly be `string` so it is not typed as a \"const string\" that gets injected by esbuild\nexport const version = '3.0.0-pr-11006.1765450794-e636950b2' as string;\n"],"mappings":"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","names":["import_v10","RESTEvents","RequestMethod","limit","offset","res","uuidV5"]}
package/dist/web.mjs CHANGED
@@ -18,7 +18,7 @@ import { CDNRoutes } from "discord-api-types/v10";
18
18
  // src/lib/utils/constants.ts
19
19
  import { getUserAgentAppendix } from "@discordjs/util";
20
20
  import { APIVersion } from "discord-api-types/v10";
21
- var DefaultUserAgent = `DiscordBot (https://discord.js.org, 3.0.0-move-client-init.1761650119-a4c0a246f)`;
21
+ var DefaultUserAgent = `DiscordBot (https://discord.js.org, 3.0.0-pr-11006.1765450794-e636950b2)`;
22
22
  var DefaultUserAgentAppendix = getUserAgentAppendix();
23
23
  var DefaultRestOptions = {
24
24
  agent: null,
@@ -1135,6 +1135,7 @@ var REST = class _REST extends AsyncEventEmitter {
1135
1135
  handlerTimer;
1136
1136
  options;
1137
1137
  constructor(options = {}) {
1138
+ console.log("even rest got something new \u203C\uFE0F \u{1F5E3}\uFE0F \u{1F525}");
1138
1139
  super();
1139
1140
  this.cdn = new CDN(options);
1140
1141
  this.options = { ...DefaultRestOptions, ...options };
@@ -1419,7 +1420,7 @@ var REST = class _REST extends AsyncEventEmitter {
1419
1420
  };
1420
1421
 
1421
1422
  // src/shared.ts
1422
- var version = "3.0.0-move-client-init.1761650119-a4c0a246f";
1423
+ var version = "3.0.0-pr-11006.1765450794-e636950b2";
1423
1424
 
1424
1425
  // src/web.ts
1425
1426
  setDefaultStrategy(fetch);