Cleaned up repo and separated both bots into their respective folders
This commit is contained in:
		
							parent
							
								
									5414de60ca
								
							
						
					
					
						commit
						a9fda1fcb7
					
				
					 3134 changed files with 382980 additions and 31 deletions
				
			
		
							
								
								
									
										865
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										865
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,865 @@ | |||
| import { Agent, Dispatcher, request, BodyInit } from 'undici'; | ||||
| import { Buffer } from 'node:buffer'; | ||||
| import { EventEmitter } from 'node:events'; | ||||
| import { URLSearchParams } from 'node:url'; | ||||
| import { Collection } from '@discordjs/collection'; | ||||
| 
 | ||||
| declare const DefaultUserAgent = "DiscordBot (https://discord.js.org, [VI]{{inject}}[/VI])"; | ||||
| declare const DefaultRestOptions: { | ||||
|     readonly agent: Agent; | ||||
|     readonly api: "https://discord.com/api"; | ||||
|     readonly authPrefix: "Bot"; | ||||
|     readonly cdn: "https://cdn.discordapp.com"; | ||||
|     readonly headers: {}; | ||||
|     readonly invalidRequestWarningInterval: 0; | ||||
|     readonly globalRequestsPerSecond: 50; | ||||
|     readonly offset: 50; | ||||
|     readonly rejectOnRateLimit: null; | ||||
|     readonly retries: 3; | ||||
|     readonly timeout: 15000; | ||||
|     readonly userAgentAppendix: `Node.js ${string}`; | ||||
|     readonly version: "10"; | ||||
|     readonly hashSweepInterval: 14400000; | ||||
|     readonly hashLifetime: 86400000; | ||||
|     readonly handlerSweepInterval: 3600000; | ||||
| }; | ||||
| /** | ||||
|  * The events that the REST manager emits | ||||
|  */ | ||||
| declare const enum RESTEvents { | ||||
|     Debug = "restDebug", | ||||
|     HandlerSweep = "handlerSweep", | ||||
|     HashSweep = "hashSweep", | ||||
|     InvalidRequestWarning = "invalidRequestWarning", | ||||
|     RateLimited = "rateLimited", | ||||
|     Response = "response" | ||||
| } | ||||
| declare const ALLOWED_EXTENSIONS: readonly ["webp", "png", "jpg", "jpeg", "gif"]; | ||||
| declare const ALLOWED_STICKER_EXTENSIONS: readonly ["png", "json"]; | ||||
| declare const ALLOWED_SIZES: readonly [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]; | ||||
| type ImageExtension = typeof ALLOWED_EXTENSIONS[number]; | ||||
| type StickerExtension = typeof ALLOWED_STICKER_EXTENSIONS[number]; | ||||
| type ImageSize = typeof ALLOWED_SIZES[number]; | ||||
| 
 | ||||
| /** | ||||
|  * The options used for image URLs | ||||
|  */ | ||||
| interface BaseImageURLOptions { | ||||
|     /** | ||||
|      * The extension to use for the image URL | ||||
|      * | ||||
|      * @defaultValue `'webp'` | ||||
|      */ | ||||
|     extension?: ImageExtension; | ||||
|     /** | ||||
|      * The size specified in the image URL | ||||
|      */ | ||||
|     size?: ImageSize; | ||||
| } | ||||
| /** | ||||
|  * The options used for image URLs with animated content | ||||
|  */ | ||||
| interface ImageURLOptions extends BaseImageURLOptions { | ||||
|     /** | ||||
|      * Whether or not to prefer the static version of an image asset. | ||||
|      */ | ||||
|     forceStatic?: boolean; | ||||
| } | ||||
| /** | ||||
|  * The options to use when making a CDN URL | ||||
|  */ | ||||
| interface MakeURLOptions { | ||||
|     /** | ||||
|      * The allowed extensions that can be used | ||||
|      */ | ||||
|     allowedExtensions?: readonly string[]; | ||||
|     /** | ||||
|      * The extension to use for the image URL | ||||
|      * | ||||
|      * @defaultValue `'webp'` | ||||
|      */ | ||||
|     extension?: string | undefined; | ||||
|     /** | ||||
|      * The size specified in the image URL | ||||
|      */ | ||||
|     size?: ImageSize; | ||||
| } | ||||
| /** | ||||
|  * The CDN link builder | ||||
|  */ | ||||
| declare class CDN { | ||||
|     private readonly base; | ||||
|     constructor(base?: string); | ||||
|     /** | ||||
|      * Generates an app asset URL for a client's asset. | ||||
|      * | ||||
|      * @param clientId - The client id that has the asset | ||||
|      * @param assetHash - The hash provided by Discord for this asset | ||||
|      * @param options - Optional options for the asset | ||||
|      */ | ||||
|     appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates an app icon URL for a client's icon. | ||||
|      * | ||||
|      * @param clientId - The client id that has the icon | ||||
|      * @param iconHash - The hash provided by Discord for this icon | ||||
|      * @param options - Optional options for the icon | ||||
|      */ | ||||
|     appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates an avatar URL, e.g. for a user or a webhook. | ||||
|      * | ||||
|      * @param id - The id that has the icon | ||||
|      * @param avatarHash - The hash provided by Discord for this avatar | ||||
|      * @param options - Optional options for the avatar | ||||
|      */ | ||||
|     avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a banner URL, e.g. for a user or a guild. | ||||
|      * | ||||
|      * @param id - The id that has the banner splash | ||||
|      * @param bannerHash - The hash provided by Discord for this banner | ||||
|      * @param options - Optional options for the banner | ||||
|      */ | ||||
|     banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates an icon URL for a channel, e.g. a group DM. | ||||
|      * | ||||
|      * @param channelId - The channel id that has the icon | ||||
|      * @param iconHash - The hash provided by Discord for this channel | ||||
|      * @param options - Optional options for the icon | ||||
|      */ | ||||
|     channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates the default avatar URL for a discriminator. | ||||
|      * | ||||
|      * @param discriminator - The discriminator modulo 5 | ||||
|      */ | ||||
|     defaultAvatar(discriminator: number): string; | ||||
|     /** | ||||
|      * Generates a discovery splash URL for a guild's discovery splash. | ||||
|      * | ||||
|      * @param guildId - The guild id that has the discovery splash | ||||
|      * @param splashHash - The hash provided by Discord for this splash | ||||
|      * @param options - Optional options for the splash | ||||
|      */ | ||||
|     discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates an emoji's URL for an emoji. | ||||
|      * | ||||
|      * @param emojiId - The emoji id | ||||
|      * @param extension - The extension of the emoji | ||||
|      */ | ||||
|     emoji(emojiId: string, extension?: ImageExtension): string; | ||||
|     /** | ||||
|      * Generates a guild member avatar URL. | ||||
|      * | ||||
|      * @param guildId - The id of the guild | ||||
|      * @param userId - The id of the user | ||||
|      * @param avatarHash - The hash provided by Discord for this avatar | ||||
|      * @param options - Optional options for the avatar | ||||
|      */ | ||||
|     guildMemberAvatar(guildId: string, userId: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a guild member banner URL. | ||||
|      * | ||||
|      * @param guildId - The id of the guild | ||||
|      * @param userId - The id of the user | ||||
|      * @param bannerHash - The hash provided by Discord for this banner | ||||
|      * @param options - Optional options for the banner | ||||
|      */ | ||||
|     guildMemberBanner(guildId: string, userId: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates an icon URL, e.g. for a guild. | ||||
|      * | ||||
|      * @param id - The id that has the icon splash | ||||
|      * @param iconHash - The hash provided by Discord for this icon | ||||
|      * @param options - Optional options for the icon | ||||
|      */ | ||||
|     icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a URL for the icon of a role | ||||
|      * | ||||
|      * @param roleId - The id of the role that has the icon | ||||
|      * @param roleIconHash - The hash provided by Discord for this role icon | ||||
|      * @param options - Optional options for the role icon | ||||
|      */ | ||||
|     roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a guild invite splash URL for a guild's invite splash. | ||||
|      * | ||||
|      * @param guildId - The guild id that has the invite splash | ||||
|      * @param splashHash - The hash provided by Discord for this splash | ||||
|      * @param options - Optional options for the splash | ||||
|      */ | ||||
|     splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a sticker URL. | ||||
|      * | ||||
|      * @param stickerId - The sticker id | ||||
|      * @param extension - The extension of the sticker | ||||
|      */ | ||||
|     sticker(stickerId: string, extension?: StickerExtension): string; | ||||
|     /** | ||||
|      * Generates a sticker pack banner URL. | ||||
|      * | ||||
|      * @param bannerId - The banner id | ||||
|      * @param options - Optional options for the banner | ||||
|      */ | ||||
|     stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a team icon URL for a team's icon. | ||||
|      * | ||||
|      * @param teamId - The team id that has the icon | ||||
|      * @param iconHash - The hash provided by Discord for this icon | ||||
|      * @param options - Optional options for the icon | ||||
|      */ | ||||
|     teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Generates a cover image for a guild scheduled event. | ||||
|      * | ||||
|      * @param scheduledEventId - The scheduled event id | ||||
|      * @param coverHash - The hash provided by discord for this cover image | ||||
|      * @param options - Optional options for the cover image | ||||
|      */ | ||||
|     guildScheduledEventCover(scheduledEventId: string, coverHash: string, options?: Readonly<BaseImageURLOptions>): string; | ||||
|     /** | ||||
|      * Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`. | ||||
|      * | ||||
|      * @param route - The base cdn route | ||||
|      * @param hash - The hash provided by Discord for this icon | ||||
|      * @param options - Optional options for the link | ||||
|      */ | ||||
|     private dynamicMakeURL; | ||||
|     /** | ||||
|      * Constructs the URL for the resource | ||||
|      * | ||||
|      * @param route - The base cdn route | ||||
|      * @param options - The extension/size options for the link | ||||
|      */ | ||||
|     private makeURL; | ||||
| } | ||||
| 
 | ||||
| interface IHandler { | ||||
|     /** | ||||
|      * The unique id of the handler | ||||
|      */ | ||||
|     readonly id: string; | ||||
|     /** | ||||
|      * If the bucket is currently inactive (no pending requests) | ||||
|      */ | ||||
|     get inactive(): boolean; | ||||
|     /** | ||||
|      * Queues a request to be sent | ||||
|      * | ||||
|      * @param routeId - The generalized api route with literal ids for major parameters | ||||
|      * @param url - The url to do the request on | ||||
|      * @param options - All the information needed to make a request | ||||
|      * @param requestData - Extra data from the user's request needed for errors and additional processing | ||||
|      */ | ||||
|     queueRequest(routeId: RouteData, url: string, options: RequestOptions, requestData: HandlerRequestData): Promise<Dispatcher.ResponseData>; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Options to be passed when creating the REST instance | ||||
|  */ | ||||
| interface RESTOptions { | ||||
|     /** | ||||
|      * The agent to set globally | ||||
|      */ | ||||
|     agent: Dispatcher; | ||||
|     /** | ||||
|      * The base api path, without version | ||||
|      * | ||||
|      * @defaultValue `'https://discord.com/api'` | ||||
|      */ | ||||
|     api: string; | ||||
|     /** | ||||
|      * The authorization prefix to use for requests, useful if you want to use | ||||
|      * bearer tokens | ||||
|      * | ||||
|      * @defaultValue `'Bot'` | ||||
|      */ | ||||
|     authPrefix: 'Bearer' | 'Bot'; | ||||
|     /** | ||||
|      * The cdn path | ||||
|      * | ||||
|      * @defaultValue 'https://cdn.discordapp.com' | ||||
|      */ | ||||
|     cdn: string; | ||||
|     /** | ||||
|      * How many requests to allow sending per second (Infinity for unlimited, 50 for the standard global limit used by Discord) | ||||
|      * | ||||
|      * @defaultValue `50` | ||||
|      */ | ||||
|     globalRequestsPerSecond: number; | ||||
|     /** | ||||
|      * The amount of time in milliseconds that passes between each hash sweep. (defaults to 1h) | ||||
|      * | ||||
|      * @defaultValue `3_600_000` | ||||
|      */ | ||||
|     handlerSweepInterval: number; | ||||
|     /** | ||||
|      * The maximum amount of time a hash can exist in milliseconds without being hit with a request (defaults to 24h) | ||||
|      * | ||||
|      * @defaultValue `86_400_000` | ||||
|      */ | ||||
|     hashLifetime: number; | ||||
|     /** | ||||
|      * The amount of time in milliseconds that passes between each hash sweep. (defaults to 4h) | ||||
|      * | ||||
|      * @defaultValue `14_400_000` | ||||
|      */ | ||||
|     hashSweepInterval: number; | ||||
|     /** | ||||
|      * Additional headers to send for all API requests | ||||
|      * | ||||
|      * @defaultValue `{}` | ||||
|      */ | ||||
|     headers: Record<string, string>; | ||||
|     /** | ||||
|      * 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). | ||||
|      * That is, if set to 500, warnings will be emitted at invalid request number 500, 1000, 1500, and so on. | ||||
|      * | ||||
|      * @defaultValue `0` | ||||
|      */ | ||||
|     invalidRequestWarningInterval: number; | ||||
|     /** | ||||
|      * The extra offset to add to rate limits in milliseconds | ||||
|      * | ||||
|      * @defaultValue `50` | ||||
|      */ | ||||
|     offset: number; | ||||
|     /** | ||||
|      * Determines how rate limiting and pre-emptive throttling should be handled. | ||||
|      * When an array of strings, each element is treated as a prefix for the request route | ||||
|      * (e.g. `/channels` to match any route starting with `/channels` such as `/channels/:id/messages`) | ||||
|      * for which to throw {@link RateLimitError}s. All other request routes will be queued normally | ||||
|      * | ||||
|      * @defaultValue `null` | ||||
|      */ | ||||
|     rejectOnRateLimit: RateLimitQueueFilter | string[] | null; | ||||
|     /** | ||||
|      * The number of retries for errors with the 500 code, or errors | ||||
|      * that timeout | ||||
|      * | ||||
|      * @defaultValue `3` | ||||
|      */ | ||||
|     retries: number; | ||||
|     /** | ||||
|      * The time to wait in milliseconds before a request is aborted | ||||
|      * | ||||
|      * @defaultValue `15_000` | ||||
|      */ | ||||
|     timeout: number; | ||||
|     /** | ||||
|      * Extra information to add to the user agent | ||||
|      * | ||||
|      * @defaultValue `Node.js ${process.version}` | ||||
|      */ | ||||
|     userAgentAppendix: string; | ||||
|     /** | ||||
|      * The version of the API to use | ||||
|      * | ||||
|      * @defaultValue `'10'` | ||||
|      */ | ||||
|     version: string; | ||||
| } | ||||
| /** | ||||
|  * Data emitted on `RESTEvents.RateLimited` | ||||
|  */ | ||||
| interface RateLimitData { | ||||
|     /** | ||||
|      * Whether the rate limit that was reached was the global limit | ||||
|      */ | ||||
|     global: boolean; | ||||
|     /** | ||||
|      * The bucket hash for this request | ||||
|      */ | ||||
|     hash: string; | ||||
|     /** | ||||
|      * The amount of requests we can perform before locking requests | ||||
|      */ | ||||
|     limit: number; | ||||
|     /** | ||||
|      * The major parameter of the route | ||||
|      * | ||||
|      * For example, in `/channels/x`, this will be `x`. | ||||
|      * If there is no major parameter (e.g: `/bot/gateway`) this will be `global`. | ||||
|      */ | ||||
|     majorParameter: string; | ||||
|     /** | ||||
|      * The HTTP method being performed | ||||
|      */ | ||||
|     method: string; | ||||
|     /** | ||||
|      * The route being hit in this request | ||||
|      */ | ||||
|     route: string; | ||||
|     /** | ||||
|      * The time, in milliseconds, until the request-lock is reset | ||||
|      */ | ||||
|     timeToReset: number; | ||||
|     /** | ||||
|      * The full URL for this request | ||||
|      */ | ||||
|     url: string; | ||||
| } | ||||
| /** | ||||
|  * A function that determines whether the rate limit hit should throw an Error | ||||
|  */ | ||||
| type RateLimitQueueFilter = (rateLimitData: RateLimitData) => Promise<boolean> | boolean; | ||||
| interface APIRequest { | ||||
|     /** | ||||
|      * The data that was used to form the body of this request | ||||
|      */ | ||||
|     data: HandlerRequestData; | ||||
|     /** | ||||
|      * The HTTP method used in this request | ||||
|      */ | ||||
|     method: string; | ||||
|     /** | ||||
|      * Additional HTTP options for this request | ||||
|      */ | ||||
|     options: RequestOptions; | ||||
|     /** | ||||
|      * The full path used to make the request | ||||
|      */ | ||||
|     path: RouteLike; | ||||
|     /** | ||||
|      * The number of times this request has been attempted | ||||
|      */ | ||||
|     retries: number; | ||||
|     /** | ||||
|      * The API route identifying the ratelimit for this request | ||||
|      */ | ||||
|     route: string; | ||||
| } | ||||
| interface InvalidRequestWarningData { | ||||
|     /** | ||||
|      * Number of invalid requests that have been made in the window | ||||
|      */ | ||||
|     count: number; | ||||
|     /** | ||||
|      * Time in milliseconds remaining before the count resets | ||||
|      */ | ||||
|     remainingTime: number; | ||||
| } | ||||
| interface RestEvents { | ||||
|     handlerSweep: [sweptHandlers: Collection<string, IHandler>]; | ||||
|     hashSweep: [sweptHashes: Collection<string, HashData>]; | ||||
|     invalidRequestWarning: [invalidRequestInfo: InvalidRequestWarningData]; | ||||
|     newListener: [name: string, listener: (...args: any) => void]; | ||||
|     rateLimited: [rateLimitInfo: RateLimitData]; | ||||
|     removeListener: [name: string, listener: (...args: any) => void]; | ||||
|     response: [request: APIRequest, response: Dispatcher.ResponseData]; | ||||
|     restDebug: [info: string]; | ||||
| } | ||||
| type RequestOptions = Exclude<Parameters<typeof request>[1], undefined>; | ||||
| interface REST { | ||||
|     emit: (<K extends keyof RestEvents>(event: K, ...args: RestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, ...args: any[]) => boolean); | ||||
|     off: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     on: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     once: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     removeAllListeners: (<K extends keyof RestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof RestEvents>) => this); | ||||
| } | ||||
| declare class REST extends EventEmitter { | ||||
|     readonly cdn: CDN; | ||||
|     readonly requestManager: RequestManager; | ||||
|     constructor(options?: Partial<RESTOptions>); | ||||
|     /** | ||||
|      * Gets the agent set for this instance | ||||
|      */ | ||||
|     getAgent(): Dispatcher | null; | ||||
|     /** | ||||
|      * Sets the default agent to use for requests performed by this instance | ||||
|      * | ||||
|      * @param agent - Sets the agent to use | ||||
|      */ | ||||
|     setAgent(agent: Dispatcher): this; | ||||
|     /** | ||||
|      * Sets the authorization token that should be used for requests | ||||
|      * | ||||
|      * @param token - The authorization token to use | ||||
|      */ | ||||
|     setToken(token: string): this; | ||||
|     /** | ||||
|      * Runs a get request from the api | ||||
|      * | ||||
|      * @param fullRoute - The full route to query | ||||
|      * @param options - Optional request options | ||||
|      */ | ||||
|     get(fullRoute: RouteLike, options?: RequestData): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a delete request from the api | ||||
|      * | ||||
|      * @param fullRoute - The full route to query | ||||
|      * @param options - Optional request options | ||||
|      */ | ||||
|     delete(fullRoute: RouteLike, options?: RequestData): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a post request from the api | ||||
|      * | ||||
|      * @param fullRoute - The full route to query | ||||
|      * @param options - Optional request options | ||||
|      */ | ||||
|     post(fullRoute: RouteLike, options?: RequestData): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a put request from the api | ||||
|      * | ||||
|      * @param fullRoute - The full route to query | ||||
|      * @param options - Optional request options | ||||
|      */ | ||||
|     put(fullRoute: RouteLike, options?: RequestData): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a patch request from the api | ||||
|      * | ||||
|      * @param fullRoute - The full route to query | ||||
|      * @param options - Optional request options | ||||
|      */ | ||||
|     patch(fullRoute: RouteLike, options?: RequestData): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a request from the api | ||||
|      * | ||||
|      * @param options - Request options | ||||
|      */ | ||||
|     request(options: InternalRequest): Promise<unknown>; | ||||
|     /** | ||||
|      * Runs a request from the API, yielding the raw Response object | ||||
|      * | ||||
|      * @param options - Request options | ||||
|      */ | ||||
|     raw(options: InternalRequest): Promise<Dispatcher.ResponseData>; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Represents a file to be added to the request | ||||
|  */ | ||||
| interface RawFile { | ||||
|     /** | ||||
|      * Content-Type of the file | ||||
|      */ | ||||
|     contentType?: string; | ||||
|     /** | ||||
|      * The actual data for the file | ||||
|      */ | ||||
|     data: Buffer | boolean | number | string; | ||||
|     /** | ||||
|      * An explicit key to use for key of the formdata field for this file. | ||||
|      * When not provided, the index of the file in the files array is used in the form `files[${index}]`. | ||||
|      * If you wish to alter the placeholder snowflake, you must provide this property in the same form (`files[${placeholder}]`) | ||||
|      */ | ||||
|     key?: string; | ||||
|     /** | ||||
|      * The name of the file | ||||
|      */ | ||||
|     name: string; | ||||
| } | ||||
| /** | ||||
|  * Represents possible data to be given to an endpoint | ||||
|  */ | ||||
| interface RequestData { | ||||
|     /** | ||||
|      * Whether to append JSON data to form data instead of `payload_json` when sending files | ||||
|      */ | ||||
|     appendToFormData?: boolean; | ||||
|     /** | ||||
|      * If this request needs the `Authorization` header | ||||
|      * | ||||
|      * @defaultValue `true` | ||||
|      */ | ||||
|     auth?: boolean; | ||||
|     /** | ||||
|      * The authorization prefix to use for this request, useful if you use this with bearer tokens | ||||
|      * | ||||
|      * @defaultValue `'Bot'` | ||||
|      */ | ||||
|     authPrefix?: 'Bearer' | 'Bot'; | ||||
|     /** | ||||
|      * The body to send to this request. | ||||
|      * If providing as BodyInit, set `passThroughBody: true` | ||||
|      */ | ||||
|     body?: BodyInit | unknown; | ||||
|     /** | ||||
|      * The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} to use for the request.
 | ||||
|      */ | ||||
|     dispatcher?: Agent; | ||||
|     /** | ||||
|      * Files to be attached to this request | ||||
|      */ | ||||
|     files?: RawFile[] | undefined; | ||||
|     /** | ||||
|      * Additional headers to add to this request | ||||
|      */ | ||||
|     headers?: Record<string, string>; | ||||
|     /** | ||||
|      * Whether to pass-through the body property directly to `fetch()`. | ||||
|      * <warn>This only applies when files is NOT present</warn> | ||||
|      */ | ||||
|     passThroughBody?: boolean; | ||||
|     /** | ||||
|      * Query string parameters to append to the called endpoint | ||||
|      */ | ||||
|     query?: URLSearchParams; | ||||
|     /** | ||||
|      * Reason to show in the audit logs | ||||
|      */ | ||||
|     reason?: string | undefined; | ||||
|     /** | ||||
|      * The signal to abort the queue entry or the REST call, where applicable | ||||
|      */ | ||||
|     signal?: AbortSignal | undefined; | ||||
|     /** | ||||
|      * If this request should be versioned | ||||
|      * | ||||
|      * @defaultValue `true` | ||||
|      */ | ||||
|     versioned?: boolean; | ||||
| } | ||||
| /** | ||||
|  * Possible headers for an API call | ||||
|  */ | ||||
| interface RequestHeaders { | ||||
|     Authorization?: string; | ||||
|     'User-Agent': string; | ||||
|     'X-Audit-Log-Reason'?: string; | ||||
| } | ||||
| /** | ||||
|  * Possible API methods to be used when doing requests | ||||
|  */ | ||||
| declare const enum RequestMethod { | ||||
|     Delete = "DELETE", | ||||
|     Get = "GET", | ||||
|     Patch = "PATCH", | ||||
|     Post = "POST", | ||||
|     Put = "PUT" | ||||
| } | ||||
| type RouteLike = `/${string}`; | ||||
| /** | ||||
|  * Internal request options | ||||
|  * | ||||
|  * @internal | ||||
|  */ | ||||
| interface InternalRequest extends RequestData { | ||||
|     fullRoute: RouteLike; | ||||
|     method: RequestMethod; | ||||
| } | ||||
| type HandlerRequestData = Pick<InternalRequest, 'auth' | 'body' | 'files' | 'signal'>; | ||||
| /** | ||||
|  * Parsed route data for an endpoint | ||||
|  * | ||||
|  * @internal | ||||
|  */ | ||||
| interface RouteData { | ||||
|     bucketRoute: string; | ||||
|     majorParameter: string; | ||||
|     original: RouteLike; | ||||
| } | ||||
| /** | ||||
|  * Represents a hash and its associated fields | ||||
|  * | ||||
|  * @internal | ||||
|  */ | ||||
| interface HashData { | ||||
|     lastAccess: number; | ||||
|     value: string; | ||||
| } | ||||
| interface RequestManager { | ||||
|     emit: (<K extends keyof RestEvents>(event: K, ...args: RestEvents[K]) => boolean) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, ...args: any[]) => boolean); | ||||
|     off: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     on: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     once: (<K extends keyof RestEvents>(event: K, listener: (...args: RestEvents[K]) => void) => this) & (<S extends string | symbol>(event: Exclude<S, keyof RestEvents>, listener: (...args: any[]) => void) => this); | ||||
|     removeAllListeners: (<K extends keyof RestEvents>(event?: K) => this) & (<S extends string | symbol>(event?: Exclude<S, keyof RestEvents>) => this); | ||||
| } | ||||
| /** | ||||
|  * Represents the class that manages handlers for endpoints | ||||
|  */ | ||||
| declare class RequestManager extends EventEmitter { | ||||
|     #private; | ||||
|     /** | ||||
|      * The {@link https://undici.nodejs.org/#/docs/api/Agent | Agent} for all requests
 | ||||
|      * performed by this manager. | ||||
|      */ | ||||
|     agent: Dispatcher | null; | ||||
|     /** | ||||
|      * The number of requests remaining in the global bucket | ||||
|      */ | ||||
|     globalRemaining: number; | ||||
|     /** | ||||
|      * The promise used to wait out the global rate limit | ||||
|      */ | ||||
|     globalDelay: Promise<void> | null; | ||||
|     /** | ||||
|      * The timestamp at which the global bucket resets | ||||
|      */ | ||||
|     globalReset: number; | ||||
|     /** | ||||
|      * API bucket hashes that are cached from provided routes | ||||
|      */ | ||||
|     readonly hashes: Collection<string, HashData>; | ||||
|     /** | ||||
|      * Request handlers created from the bucket hash and the major parameters | ||||
|      */ | ||||
|     readonly handlers: Collection<string, IHandler>; | ||||
|     private hashTimer; | ||||
|     private handlerTimer; | ||||
|     readonly options: RESTOptions; | ||||
|     constructor(options: Partial<RESTOptions>); | ||||
|     private setupSweepers; | ||||
|     /** | ||||
|      * Sets the default agent to use for requests performed by this manager | ||||
|      * | ||||
|      * @param agent - The agent to use | ||||
|      */ | ||||
|     setAgent(agent: Dispatcher): this; | ||||
|     /** | ||||
|      * Sets the authorization token that should be used for requests | ||||
|      * | ||||
|      * @param token - The authorization token to use | ||||
|      */ | ||||
|     setToken(token: string): this; | ||||
|     /** | ||||
|      * Queues a request to be sent | ||||
|      * | ||||
|      * @param request - All the information needed to make a request | ||||
|      * @returns The response from the api request | ||||
|      */ | ||||
|     queueRequest(request: InternalRequest): Promise<Dispatcher.ResponseData>; | ||||
|     /** | ||||
|      * Creates a new rate limit handler from a hash, based on the hash and the major parameter | ||||
|      * | ||||
|      * @param hash - The hash for the route | ||||
|      * @param majorParameter - The major parameter for this handler | ||||
|      * @internal | ||||
|      */ | ||||
|     private createHandler; | ||||
|     /** | ||||
|      * Formats the request data to a usable format for fetch | ||||
|      * | ||||
|      * @param request - The request data | ||||
|      */ | ||||
|     private resolveRequest; | ||||
|     /** | ||||
|      * Stops the hash sweeping interval | ||||
|      */ | ||||
|     clearHashSweeper(): void; | ||||
|     /** | ||||
|      * Stops the request handler sweeping interval | ||||
|      */ | ||||
|     clearHandlerSweeper(): void; | ||||
|     /** | ||||
|      * Generates route data for an endpoint:method | ||||
|      * | ||||
|      * @param endpoint - The raw endpoint to generalize | ||||
|      * @param method - The HTTP method this endpoint is called without | ||||
|      * @internal | ||||
|      */ | ||||
|     private static generateRouteData; | ||||
| } | ||||
| 
 | ||||
| interface DiscordErrorFieldInformation { | ||||
|     code: string; | ||||
|     message: string; | ||||
| } | ||||
| interface DiscordErrorGroupWrapper { | ||||
|     _errors: DiscordError[]; | ||||
| } | ||||
| type DiscordError = DiscordErrorFieldInformation | DiscordErrorGroupWrapper | string | { | ||||
|     [k: string]: DiscordError; | ||||
| }; | ||||
| interface DiscordErrorData { | ||||
|     code: number; | ||||
|     errors?: DiscordError; | ||||
|     message: string; | ||||
| } | ||||
| interface OAuthErrorData { | ||||
|     error: string; | ||||
|     error_description?: string; | ||||
| } | ||||
| interface RequestBody { | ||||
|     files: RawFile[] | undefined; | ||||
|     json: unknown | undefined; | ||||
| } | ||||
| /** | ||||
|  * Represents an API error returned by Discord | ||||
|  */ | ||||
| declare class DiscordAPIError extends Error { | ||||
|     rawError: DiscordErrorData | OAuthErrorData; | ||||
|     code: number | string; | ||||
|     status: number; | ||||
|     method: string; | ||||
|     url: string; | ||||
|     requestBody: RequestBody; | ||||
|     /** | ||||
|      * @param rawError - The error reported by Discord | ||||
|      * @param code - The error code reported by Discord | ||||
|      * @param status - The status code of the response | ||||
|      * @param method - The method of the request that erred | ||||
|      * @param url - The url of the request that erred | ||||
|      * @param bodyData - The unparsed data for the request that errored | ||||
|      */ | ||||
|     constructor(rawError: DiscordErrorData | OAuthErrorData, code: number | string, status: number, method: string, url: string, bodyData: Pick<InternalRequest, 'body' | 'files'>); | ||||
|     /** | ||||
|      * The name of the error | ||||
|      */ | ||||
|     get name(): string; | ||||
|     private static getMessage; | ||||
|     private static flattenDiscordError; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Represents a HTTP error | ||||
|  */ | ||||
| declare class HTTPError extends Error { | ||||
|     status: number; | ||||
|     method: string; | ||||
|     url: string; | ||||
|     requestBody: RequestBody; | ||||
|     name: string; | ||||
|     /** | ||||
|      * @param status - The status code of the response | ||||
|      * @param method - The method of the request that erred | ||||
|      * @param url - The url of the request that erred | ||||
|      * @param bodyData - The unparsed data for the request that errored | ||||
|      */ | ||||
|     constructor(status: number, method: string, url: string, bodyData: Pick<InternalRequest, 'body' | 'files'>); | ||||
| } | ||||
| 
 | ||||
| declare class RateLimitError extends Error implements RateLimitData { | ||||
|     timeToReset: number; | ||||
|     limit: number; | ||||
|     method: string; | ||||
|     hash: string; | ||||
|     url: string; | ||||
|     route: string; | ||||
|     majorParameter: string; | ||||
|     global: boolean; | ||||
|     constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }: RateLimitData); | ||||
|     /** | ||||
|      * The name of the error | ||||
|      */ | ||||
|     get name(): string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates and populates an URLSearchParams instance from an object, stripping | ||||
|  * out null and undefined values, while also coercing non-strings to strings. | ||||
|  * | ||||
|  * @param options - The options to use | ||||
|  * @returns A populated URLSearchParams instance | ||||
|  */ | ||||
| declare function makeURLSearchParams<T extends object>(options?: Readonly<T>): URLSearchParams; | ||||
| /** | ||||
|  * Converts the response to usable data | ||||
|  * | ||||
|  * @param res - The fetch response | ||||
|  */ | ||||
| declare function parseResponse(res: Dispatcher.ResponseData): Promise<unknown>; | ||||
| 
 | ||||
| /** | ||||
|  * The {@link https://github.com/discordjs/discord.js/blob/main/packages/rest/#readme | @discordjs/rest} version
 | ||||
|  * that you are currently using. | ||||
|  */ | ||||
| declare const version: string; | ||||
| 
 | ||||
| export { ALLOWED_EXTENSIONS, ALLOWED_SIZES, ALLOWED_STICKER_EXTENSIONS, APIRequest, BaseImageURLOptions, CDN, DefaultRestOptions, DefaultUserAgent, DiscordAPIError, DiscordErrorData, HTTPError, HandlerRequestData, HashData, ImageExtension, ImageSize, ImageURLOptions, InternalRequest, InvalidRequestWarningData, MakeURLOptions, OAuthErrorData, REST, RESTEvents, RESTOptions, RateLimitData, RateLimitError, RateLimitQueueFilter, RawFile, RequestBody, RequestData, RequestHeaders, RequestManager, RequestMethod, RequestOptions, RestEvents, RouteData, RouteLike, StickerExtension, makeURLSearchParams, parseResponse, version }; | ||||
							
								
								
									
										940
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										940
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,940 @@ | |||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| 
 | ||||
| // src/index.ts
 | ||||
| var src_exports = {}; | ||||
| __export(src_exports, { | ||||
|   ALLOWED_EXTENSIONS: () => ALLOWED_EXTENSIONS, | ||||
|   ALLOWED_SIZES: () => ALLOWED_SIZES, | ||||
|   ALLOWED_STICKER_EXTENSIONS: () => ALLOWED_STICKER_EXTENSIONS, | ||||
|   CDN: () => CDN, | ||||
|   DefaultRestOptions: () => DefaultRestOptions, | ||||
|   DefaultUserAgent: () => DefaultUserAgent, | ||||
|   DiscordAPIError: () => DiscordAPIError, | ||||
|   HTTPError: () => HTTPError, | ||||
|   REST: () => REST, | ||||
|   RESTEvents: () => RESTEvents, | ||||
|   RateLimitError: () => RateLimitError, | ||||
|   RequestManager: () => RequestManager, | ||||
|   RequestMethod: () => RequestMethod, | ||||
|   makeURLSearchParams: () => makeURLSearchParams, | ||||
|   parseResponse: () => parseResponse, | ||||
|   version: () => version | ||||
| }); | ||||
| module.exports = __toCommonJS(src_exports); | ||||
| 
 | ||||
| // src/lib/CDN.ts
 | ||||
| var import_node_url = require("url"); | ||||
| 
 | ||||
| // src/lib/utils/constants.ts
 | ||||
| var import_node_process = __toESM(require("process")); | ||||
| var import_v10 = require("discord-api-types/v10"); | ||||
| var import_undici = require("undici"); | ||||
| var DefaultUserAgent = `DiscordBot (https://discord.js.org, 1.5.0)`; | ||||
| var DefaultRestOptions = { | ||||
|   get agent() { | ||||
|     return new import_undici.Agent({ | ||||
|       connect: { | ||||
|         timeout: 3e4 | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|   api: "https://discord.com/api", | ||||
|   authPrefix: "Bot", | ||||
|   cdn: "https://cdn.discordapp.com", | ||||
|   headers: {}, | ||||
|   invalidRequestWarningInterval: 0, | ||||
|   globalRequestsPerSecond: 50, | ||||
|   offset: 50, | ||||
|   rejectOnRateLimit: null, | ||||
|   retries: 3, | ||||
|   timeout: 15e3, | ||||
|   userAgentAppendix: `Node.js ${import_node_process.default.version}`, | ||||
|   version: import_v10.APIVersion, | ||||
|   hashSweepInterval: 144e5, | ||||
|   hashLifetime: 864e5, | ||||
|   handlerSweepInterval: 36e5 | ||||
| }; | ||||
| var RESTEvents = /* @__PURE__ */ ((RESTEvents2) => { | ||||
|   RESTEvents2["Debug"] = "restDebug"; | ||||
|   RESTEvents2["HandlerSweep"] = "handlerSweep"; | ||||
|   RESTEvents2["HashSweep"] = "hashSweep"; | ||||
|   RESTEvents2["InvalidRequestWarning"] = "invalidRequestWarning"; | ||||
|   RESTEvents2["RateLimited"] = "rateLimited"; | ||||
|   RESTEvents2["Response"] = "response"; | ||||
|   return RESTEvents2; | ||||
| })(RESTEvents || {}); | ||||
| var ALLOWED_EXTENSIONS = ["webp", "png", "jpg", "jpeg", "gif"]; | ||||
| var ALLOWED_STICKER_EXTENSIONS = ["png", "json"]; | ||||
| var ALLOWED_SIZES = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]; | ||||
| 
 | ||||
| // src/lib/CDN.ts
 | ||||
| var CDN = class { | ||||
|   constructor(base = DefaultRestOptions.cdn) { | ||||
|     this.base = base; | ||||
|   } | ||||
|   appAsset(clientId, assetHash, options) { | ||||
|     return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options); | ||||
|   } | ||||
|   appIcon(clientId, iconHash, options) { | ||||
|     return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options); | ||||
|   } | ||||
|   avatar(id, avatarHash, options) { | ||||
|     return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options); | ||||
|   } | ||||
|   banner(id, bannerHash, options) { | ||||
|     return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options); | ||||
|   } | ||||
|   channelIcon(channelId, iconHash, options) { | ||||
|     return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options); | ||||
|   } | ||||
|   defaultAvatar(discriminator) { | ||||
|     return this.makeURL(`/embed/avatars/${discriminator}`, { extension: "png" }); | ||||
|   } | ||||
|   discoverySplash(guildId, splashHash, options) { | ||||
|     return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options); | ||||
|   } | ||||
|   emoji(emojiId, extension) { | ||||
|     return this.makeURL(`/emojis/${emojiId}`, { extension }); | ||||
|   } | ||||
|   guildMemberAvatar(guildId, userId, avatarHash, options) { | ||||
|     return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options); | ||||
|   } | ||||
|   guildMemberBanner(guildId, userId, bannerHash, options) { | ||||
|     return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banner`, bannerHash, options); | ||||
|   } | ||||
|   icon(id, iconHash, options) { | ||||
|     return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options); | ||||
|   } | ||||
|   roleIcon(roleId, roleIconHash, options) { | ||||
|     return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options); | ||||
|   } | ||||
|   splash(guildId, splashHash, options) { | ||||
|     return this.makeURL(`/splashes/${guildId}/${splashHash}`, options); | ||||
|   } | ||||
|   sticker(stickerId, extension) { | ||||
|     return this.makeURL(`/stickers/${stickerId}`, { | ||||
|       allowedExtensions: ALLOWED_STICKER_EXTENSIONS, | ||||
|       extension: extension ?? "png" | ||||
|     }); | ||||
|   } | ||||
|   stickerPackBanner(bannerId, options) { | ||||
|     return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options); | ||||
|   } | ||||
|   teamIcon(teamId, iconHash, options) { | ||||
|     return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options); | ||||
|   } | ||||
|   guildScheduledEventCover(scheduledEventId, coverHash, options) { | ||||
|     return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options); | ||||
|   } | ||||
|   dynamicMakeURL(route, hash, { forceStatic = false, ...options } = {}) { | ||||
|     return this.makeURL(route, !forceStatic && hash.startsWith("a_") ? { ...options, extension: "gif" } : options); | ||||
|   } | ||||
|   makeURL(route, { allowedExtensions = ALLOWED_EXTENSIONS, extension = "webp", size } = {}) { | ||||
|     extension = String(extension).toLowerCase(); | ||||
|     if (!allowedExtensions.includes(extension)) { | ||||
|       throw new RangeError(`Invalid extension provided: ${extension} | ||||
| Must be one of: ${allowedExtensions.join(", ")}`);
 | ||||
|     } | ||||
|     if (size && !ALLOWED_SIZES.includes(size)) { | ||||
|       throw new RangeError(`Invalid size provided: ${size} | ||||
| Must be one of: ${ALLOWED_SIZES.join(", ")}`);
 | ||||
|     } | ||||
|     const url = new import_node_url.URL(`${this.base}${route}.${extension}`); | ||||
|     if (size) { | ||||
|       url.searchParams.set("size", String(size)); | ||||
|     } | ||||
|     return url.toString(); | ||||
|   } | ||||
| }; | ||||
| __name(CDN, "CDN"); | ||||
| 
 | ||||
| // src/lib/errors/DiscordAPIError.ts
 | ||||
| function isErrorGroupWrapper(error) { | ||||
|   return Reflect.has(error, "_errors"); | ||||
| } | ||||
| __name(isErrorGroupWrapper, "isErrorGroupWrapper"); | ||||
| function isErrorResponse(error) { | ||||
|   return typeof Reflect.get(error, "message") === "string"; | ||||
| } | ||||
| __name(isErrorResponse, "isErrorResponse"); | ||||
| var DiscordAPIError = class extends Error { | ||||
|   constructor(rawError, code, status, method, url, bodyData) { | ||||
|     super(DiscordAPIError.getMessage(rawError)); | ||||
|     this.rawError = rawError; | ||||
|     this.code = code; | ||||
|     this.status = status; | ||||
|     this.method = method; | ||||
|     this.url = url; | ||||
|     this.requestBody = { files: bodyData.files, json: bodyData.body }; | ||||
|   } | ||||
|   requestBody; | ||||
|   get name() { | ||||
|     return `${DiscordAPIError.name}[${this.code}]`; | ||||
|   } | ||||
|   static getMessage(error) { | ||||
|     let flattened = ""; | ||||
|     if ("code" in error) { | ||||
|       if (error.errors) { | ||||
|         flattened = [...this.flattenDiscordError(error.errors)].join("\n"); | ||||
|       } | ||||
|       return error.message && flattened ? `${error.message} | ||||
| ${flattened}` : error.message || flattened || "Unknown Error";
 | ||||
|     } | ||||
|     return error.error_description ?? "No Description"; | ||||
|   } | ||||
|   static *flattenDiscordError(obj, key = "") { | ||||
|     if (isErrorResponse(obj)) { | ||||
|       return yield `${key.length ? `${key}[${obj.code}]` : `${obj.code}`}: ${obj.message}`.trim(); | ||||
|     } | ||||
|     for (const [otherKey, val] of Object.entries(obj)) { | ||||
|       const nextKey = otherKey.startsWith("_") ? key : key ? Number.isNaN(Number(otherKey)) ? `${key}.${otherKey}` : `${key}[${otherKey}]` : otherKey; | ||||
|       if (typeof val === "string") { | ||||
|         yield val; | ||||
|       } else if (isErrorGroupWrapper(val)) { | ||||
|         for (const error of val._errors) { | ||||
|           yield* this.flattenDiscordError(error, nextKey); | ||||
|         } | ||||
|       } else { | ||||
|         yield* this.flattenDiscordError(val, nextKey); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| __name(DiscordAPIError, "DiscordAPIError"); | ||||
| 
 | ||||
| // src/lib/errors/HTTPError.ts
 | ||||
| var import_node_http = require("http"); | ||||
| var HTTPError = class extends Error { | ||||
|   constructor(status, method, url, bodyData) { | ||||
|     super(import_node_http.STATUS_CODES[status]); | ||||
|     this.status = status; | ||||
|     this.method = method; | ||||
|     this.url = url; | ||||
|     this.requestBody = { files: bodyData.files, json: bodyData.body }; | ||||
|   } | ||||
|   requestBody; | ||||
|   name = HTTPError.name; | ||||
| }; | ||||
| __name(HTTPError, "HTTPError"); | ||||
| 
 | ||||
| // src/lib/errors/RateLimitError.ts
 | ||||
| var RateLimitError = class extends Error { | ||||
|   timeToReset; | ||||
|   limit; | ||||
|   method; | ||||
|   hash; | ||||
|   url; | ||||
|   route; | ||||
|   majorParameter; | ||||
|   global; | ||||
|   constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }) { | ||||
|     super(); | ||||
|     this.timeToReset = timeToReset; | ||||
|     this.limit = limit; | ||||
|     this.method = method; | ||||
|     this.hash = hash; | ||||
|     this.url = url; | ||||
|     this.route = route; | ||||
|     this.majorParameter = majorParameter; | ||||
|     this.global = global; | ||||
|   } | ||||
|   get name() { | ||||
|     return `${RateLimitError.name}[${this.route}]`; | ||||
|   } | ||||
| }; | ||||
| __name(RateLimitError, "RateLimitError"); | ||||
| 
 | ||||
| // src/lib/RequestManager.ts
 | ||||
| var import_node_buffer2 = require("buffer"); | ||||
| var import_node_events = require("events"); | ||||
| var import_node_timers2 = require("timers"); | ||||
| var import_collection = require("@discordjs/collection"); | ||||
| var import_util = require("@discordjs/util"); | ||||
| var import_snowflake = require("@sapphire/snowflake"); | ||||
| var import_undici4 = require("undici"); | ||||
| 
 | ||||
| // src/lib/handlers/SequentialHandler.ts
 | ||||
| var import_node_timers = require("timers"); | ||||
| var import_promises = require("timers/promises"); | ||||
| var import_async_queue = require("@sapphire/async-queue"); | ||||
| var import_undici3 = require("undici"); | ||||
| 
 | ||||
| // src/lib/utils/utils.ts
 | ||||
| var import_node_buffer = require("buffer"); | ||||
| var import_node_url2 = require("url"); | ||||
| var import_node_util = require("util"); | ||||
| var import_undici2 = require("undici"); | ||||
| function parseHeader(header) { | ||||
|   if (header === void 0 || typeof header === "string") { | ||||
|     return header; | ||||
|   } | ||||
|   return header.join(";"); | ||||
| } | ||||
| __name(parseHeader, "parseHeader"); | ||||
| function serializeSearchParam(value) { | ||||
|   switch (typeof value) { | ||||
|     case "string": | ||||
|       return value; | ||||
|     case "number": | ||||
|     case "bigint": | ||||
|     case "boolean": | ||||
|       return value.toString(); | ||||
|     case "object": | ||||
|       if (value === null) | ||||
|         return null; | ||||
|       if (value instanceof Date) { | ||||
|         return Number.isNaN(value.getTime()) ? null : value.toISOString(); | ||||
|       } | ||||
|       if (typeof value.toString === "function" && value.toString !== Object.prototype.toString) | ||||
|         return value.toString(); | ||||
|       return null; | ||||
|     default: | ||||
|       return null; | ||||
|   } | ||||
| } | ||||
| __name(serializeSearchParam, "serializeSearchParam"); | ||||
| function makeURLSearchParams(options) { | ||||
|   const params = new import_node_url2.URLSearchParams(); | ||||
|   if (!options) | ||||
|     return params; | ||||
|   for (const [key, value] of Object.entries(options)) { | ||||
|     const serialized = serializeSearchParam(value); | ||||
|     if (serialized !== null) | ||||
|       params.append(key, serialized); | ||||
|   } | ||||
|   return params; | ||||
| } | ||||
| __name(makeURLSearchParams, "makeURLSearchParams"); | ||||
| async function parseResponse(res) { | ||||
|   const header = parseHeader(res.headers["content-type"]); | ||||
|   if (header?.startsWith("application/json")) { | ||||
|     return res.body.json(); | ||||
|   } | ||||
|   return res.body.arrayBuffer(); | ||||
| } | ||||
| __name(parseResponse, "parseResponse"); | ||||
| function hasSublimit(bucketRoute, body, method) { | ||||
|   if (bucketRoute === "/channels/:id") { | ||||
|     if (typeof body !== "object" || body === null) | ||||
|       return false; | ||||
|     if (method !== "PATCH" /* Patch */) | ||||
|       return false; | ||||
|     const castedBody = body; | ||||
|     return ["name", "topic"].some((key) => Reflect.has(castedBody, key)); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| __name(hasSublimit, "hasSublimit"); | ||||
| async function resolveBody(body) { | ||||
|   if (body == null) { | ||||
|     return null; | ||||
|   } else if (typeof body === "string") { | ||||
|     return body; | ||||
|   } else if (import_node_util.types.isUint8Array(body)) { | ||||
|     return body; | ||||
|   } else if (import_node_util.types.isArrayBuffer(body)) { | ||||
|     return new Uint8Array(body); | ||||
|   } else if (body instanceof import_node_url2.URLSearchParams) { | ||||
|     return body.toString(); | ||||
|   } else if (body instanceof DataView) { | ||||
|     return new Uint8Array(body.buffer); | ||||
|   } else if (body instanceof import_node_buffer.Blob) { | ||||
|     return new Uint8Array(await body.arrayBuffer()); | ||||
|   } else if (body instanceof import_undici2.FormData) { | ||||
|     return body; | ||||
|   } else if (body[Symbol.iterator]) { | ||||
|     const chunks = [...body]; | ||||
|     const length = chunks.reduce((a, b) => a + b.length, 0); | ||||
|     const uint8 = new Uint8Array(length); | ||||
|     let lengthUsed = 0; | ||||
|     return chunks.reduce((a, b) => { | ||||
|       a.set(b, lengthUsed); | ||||
|       lengthUsed += b.length; | ||||
|       return a; | ||||
|     }, uint8); | ||||
|   } else if (body[Symbol.asyncIterator]) { | ||||
|     const chunks = []; | ||||
|     for await (const chunk of body) { | ||||
|       chunks.push(chunk); | ||||
|     } | ||||
|     return import_node_buffer.Buffer.concat(chunks); | ||||
|   } | ||||
|   throw new TypeError(`Unable to resolve body.`); | ||||
| } | ||||
| __name(resolveBody, "resolveBody"); | ||||
| function shouldRetry(error) { | ||||
|   if (error.name === "AbortError") | ||||
|     return true; | ||||
|   return "code" in error && error.code === "ECONNRESET" || error.message.includes("ECONNRESET"); | ||||
| } | ||||
| __name(shouldRetry, "shouldRetry"); | ||||
| 
 | ||||
| // src/lib/handlers/SequentialHandler.ts
 | ||||
| var invalidCount = 0; | ||||
| var invalidCountResetTime = null; | ||||
| var SequentialHandler = class { | ||||
|   constructor(manager, hash, majorParameter) { | ||||
|     this.manager = manager; | ||||
|     this.hash = hash; | ||||
|     this.majorParameter = majorParameter; | ||||
|     this.id = `${hash}:${majorParameter}`; | ||||
|   } | ||||
|   id; | ||||
|   reset = -1; | ||||
|   remaining = 1; | ||||
|   limit = Number.POSITIVE_INFINITY; | ||||
|   #asyncQueue = new import_async_queue.AsyncQueue(); | ||||
|   #sublimitedQueue = null; | ||||
|   #sublimitPromise = null; | ||||
|   #shiftSublimit = false; | ||||
|   get inactive() { | ||||
|     return this.#asyncQueue.remaining === 0 && (this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) && !this.limited; | ||||
|   } | ||||
|   get globalLimited() { | ||||
|     return this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset; | ||||
|   } | ||||
|   get localLimited() { | ||||
|     return this.remaining <= 0 && Date.now() < this.reset; | ||||
|   } | ||||
|   get limited() { | ||||
|     return this.globalLimited || this.localLimited; | ||||
|   } | ||||
|   get timeToReset() { | ||||
|     return this.reset + this.manager.options.offset - Date.now(); | ||||
|   } | ||||
|   debug(message) { | ||||
|     this.manager.emit("restDebug" /* Debug */, `[REST ${this.id}] ${message}`); | ||||
|   } | ||||
|   async globalDelayFor(time) { | ||||
|     await (0, import_promises.setTimeout)(time); | ||||
|     this.manager.globalDelay = null; | ||||
|   } | ||||
|   async onRateLimit(rateLimitData) { | ||||
|     const { options } = this.manager; | ||||
|     if (!options.rejectOnRateLimit) | ||||
|       return; | ||||
|     const shouldThrow = typeof options.rejectOnRateLimit === "function" ? await options.rejectOnRateLimit(rateLimitData) : options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase())); | ||||
|     if (shouldThrow) { | ||||
|       throw new RateLimitError(rateLimitData); | ||||
|     } | ||||
|   } | ||||
|   async queueRequest(routeId, url, options, requestData) { | ||||
|     let queue = this.#asyncQueue; | ||||
|     let queueType = 0 /* Standard */; | ||||
|     if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) { | ||||
|       queue = this.#sublimitedQueue; | ||||
|       queueType = 1 /* Sublimit */; | ||||
|     } | ||||
|     await queue.wait({ signal: requestData.signal }); | ||||
|     if (queueType === 0 /* Standard */) { | ||||
|       if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) { | ||||
|         queue = this.#sublimitedQueue; | ||||
|         const wait = queue.wait(); | ||||
|         this.#asyncQueue.shift(); | ||||
|         await wait; | ||||
|       } else if (this.#sublimitPromise) { | ||||
|         await this.#sublimitPromise.promise; | ||||
|       } | ||||
|     } | ||||
|     try { | ||||
|       return await this.runRequest(routeId, url, options, requestData); | ||||
|     } finally { | ||||
|       queue.shift(); | ||||
|       if (this.#shiftSublimit) { | ||||
|         this.#shiftSublimit = false; | ||||
|         this.#sublimitedQueue?.shift(); | ||||
|       } | ||||
|       if (this.#sublimitedQueue?.remaining === 0) { | ||||
|         this.#sublimitPromise?.resolve(); | ||||
|         this.#sublimitedQueue = null; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   async runRequest(routeId, url, options, requestData, retries = 0) { | ||||
|     while (this.limited) { | ||||
|       const isGlobal = this.globalLimited; | ||||
|       let limit2; | ||||
|       let timeout2; | ||||
|       let delay; | ||||
|       if (isGlobal) { | ||||
|         limit2 = this.manager.options.globalRequestsPerSecond; | ||||
|         timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now(); | ||||
|         if (!this.manager.globalDelay) { | ||||
|           this.manager.globalDelay = this.globalDelayFor(timeout2); | ||||
|         } | ||||
|         delay = this.manager.globalDelay; | ||||
|       } else { | ||||
|         limit2 = this.limit; | ||||
|         timeout2 = this.timeToReset; | ||||
|         delay = (0, import_promises.setTimeout)(timeout2); | ||||
|       } | ||||
|       const rateLimitData = { | ||||
|         timeToReset: timeout2, | ||||
|         limit: limit2, | ||||
|         method: options.method ?? "get", | ||||
|         hash: this.hash, | ||||
|         url, | ||||
|         route: routeId.bucketRoute, | ||||
|         majorParameter: this.majorParameter, | ||||
|         global: isGlobal | ||||
|       }; | ||||
|       this.manager.emit("rateLimited" /* RateLimited */, rateLimitData); | ||||
|       await this.onRateLimit(rateLimitData); | ||||
|       if (isGlobal) { | ||||
|         this.debug(`Global rate limit hit, blocking all requests for ${timeout2}ms`); | ||||
|       } else { | ||||
|         this.debug(`Waiting ${timeout2}ms for rate limit to pass`); | ||||
|       } | ||||
|       await delay; | ||||
|     } | ||||
|     if (!this.manager.globalReset || this.manager.globalReset < Date.now()) { | ||||
|       this.manager.globalReset = Date.now() + 1e3; | ||||
|       this.manager.globalRemaining = this.manager.options.globalRequestsPerSecond; | ||||
|     } | ||||
|     this.manager.globalRemaining--; | ||||
|     const method = options.method ?? "get"; | ||||
|     const controller = new AbortController(); | ||||
|     const timeout = (0, import_node_timers.setTimeout)(() => controller.abort(), this.manager.options.timeout).unref(); | ||||
|     if (requestData.signal) { | ||||
|       const signal = requestData.signal; | ||||
|       if (signal.aborted) | ||||
|         controller.abort(); | ||||
|       else | ||||
|         signal.addEventListener("abort", () => controller.abort()); | ||||
|     } | ||||
|     let res; | ||||
|     try { | ||||
|       res = await (0, import_undici3.request)(url, { ...options, signal: controller.signal }); | ||||
|     } catch (error) { | ||||
|       if (!(error instanceof Error)) | ||||
|         throw error; | ||||
|       if (shouldRetry(error) && retries !== this.manager.options.retries) { | ||||
|         return await this.runRequest(routeId, url, options, requestData, ++retries); | ||||
|       } | ||||
|       throw error; | ||||
|     } finally { | ||||
|       (0, import_node_timers.clearTimeout)(timeout); | ||||
|     } | ||||
|     if (this.manager.listenerCount("response" /* Response */)) { | ||||
|       this.manager.emit( | ||||
|         "response" /* Response */, | ||||
|         { | ||||
|           method, | ||||
|           path: routeId.original, | ||||
|           route: routeId.bucketRoute, | ||||
|           options, | ||||
|           data: requestData, | ||||
|           retries | ||||
|         }, | ||||
|         { ...res } | ||||
|       ); | ||||
|     } | ||||
|     const status = res.statusCode; | ||||
|     let retryAfter = 0; | ||||
|     const limit = parseHeader(res.headers["x-ratelimit-limit"]); | ||||
|     const remaining = parseHeader(res.headers["x-ratelimit-remaining"]); | ||||
|     const reset = parseHeader(res.headers["x-ratelimit-reset-after"]); | ||||
|     const hash = parseHeader(res.headers["x-ratelimit-bucket"]); | ||||
|     const retry = parseHeader(res.headers["retry-after"]); | ||||
|     this.limit = limit ? Number(limit) : Number.POSITIVE_INFINITY; | ||||
|     this.remaining = remaining ? Number(remaining) : 1; | ||||
|     this.reset = reset ? Number(reset) * 1e3 + Date.now() + this.manager.options.offset : Date.now(); | ||||
|     if (retry) | ||||
|       retryAfter = Number(retry) * 1e3 + this.manager.options.offset; | ||||
|     if (hash && hash !== this.hash) { | ||||
|       this.debug(["Received bucket hash update", `  Old Hash  : ${this.hash}`, `  New Hash  : ${hash}`].join("\n")); | ||||
|       this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() }); | ||||
|     } else if (hash) { | ||||
|       const hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`); | ||||
|       if (hashData) { | ||||
|         hashData.lastAccess = Date.now(); | ||||
|       } | ||||
|     } | ||||
|     let sublimitTimeout = null; | ||||
|     if (retryAfter > 0) { | ||||
|       if (res.headers["x-ratelimit-global"] !== void 0) { | ||||
|         this.manager.globalRemaining = 0; | ||||
|         this.manager.globalReset = Date.now() + retryAfter; | ||||
|       } else if (!this.localLimited) { | ||||
|         sublimitTimeout = retryAfter; | ||||
|       } | ||||
|     } | ||||
|     if (status === 401 || status === 403 || status === 429) { | ||||
|       if (!invalidCountResetTime || invalidCountResetTime < Date.now()) { | ||||
|         invalidCountResetTime = Date.now() + 1e3 * 60 * 10; | ||||
|         invalidCount = 0; | ||||
|       } | ||||
|       invalidCount++; | ||||
|       const emitInvalid = this.manager.options.invalidRequestWarningInterval > 0 && invalidCount % this.manager.options.invalidRequestWarningInterval === 0; | ||||
|       if (emitInvalid) { | ||||
|         this.manager.emit("invalidRequestWarning" /* InvalidRequestWarning */, { | ||||
|           count: invalidCount, | ||||
|           remainingTime: invalidCountResetTime - Date.now() | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|     if (status >= 200 && status < 300) { | ||||
|       return res; | ||||
|     } else if (status === 429) { | ||||
|       const isGlobal = this.globalLimited; | ||||
|       let limit2; | ||||
|       let timeout2; | ||||
|       if (isGlobal) { | ||||
|         limit2 = this.manager.options.globalRequestsPerSecond; | ||||
|         timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now(); | ||||
|       } else { | ||||
|         limit2 = this.limit; | ||||
|         timeout2 = this.timeToReset; | ||||
|       } | ||||
|       await this.onRateLimit({ | ||||
|         timeToReset: timeout2, | ||||
|         limit: limit2, | ||||
|         method, | ||||
|         hash: this.hash, | ||||
|         url, | ||||
|         route: routeId.bucketRoute, | ||||
|         majorParameter: this.majorParameter, | ||||
|         global: isGlobal | ||||
|       }); | ||||
|       this.debug( | ||||
|         [ | ||||
|           "Encountered unexpected 429 rate limit", | ||||
|           `  Global         : ${isGlobal.toString()}`, | ||||
|           `  Method         : ${method}`, | ||||
|           `  URL            : ${url}`, | ||||
|           `  Bucket         : ${routeId.bucketRoute}`, | ||||
|           `  Major parameter: ${routeId.majorParameter}`, | ||||
|           `  Hash           : ${this.hash}`, | ||||
|           `  Limit          : ${limit2}`, | ||||
|           `  Retry After    : ${retryAfter}ms`, | ||||
|           `  Sublimit       : ${sublimitTimeout ? `${sublimitTimeout}ms` : "None"}` | ||||
|         ].join("\n") | ||||
|       ); | ||||
|       if (sublimitTimeout) { | ||||
|         const firstSublimit = !this.#sublimitedQueue; | ||||
|         if (firstSublimit) { | ||||
|           this.#sublimitedQueue = new import_async_queue.AsyncQueue(); | ||||
|           void this.#sublimitedQueue.wait(); | ||||
|           this.#asyncQueue.shift(); | ||||
|         } | ||||
|         this.#sublimitPromise?.resolve(); | ||||
|         this.#sublimitPromise = null; | ||||
|         await (0, import_promises.setTimeout)(sublimitTimeout); | ||||
|         let resolve; | ||||
|         const promise = new Promise((res2) => resolve = res2); | ||||
|         this.#sublimitPromise = { promise, resolve }; | ||||
|         if (firstSublimit) { | ||||
|           await this.#asyncQueue.wait(); | ||||
|           this.#shiftSublimit = true; | ||||
|         } | ||||
|       } | ||||
|       return this.runRequest(routeId, url, options, requestData, retries); | ||||
|     } else if (status >= 500 && status < 600) { | ||||
|       if (retries !== this.manager.options.retries) { | ||||
|         return this.runRequest(routeId, url, options, requestData, ++retries); | ||||
|       } | ||||
|       throw new HTTPError(status, method, url, requestData); | ||||
|     } else { | ||||
|       if (status >= 400 && status < 500) { | ||||
|         if (status === 401 && requestData.auth) { | ||||
|           this.manager.setToken(null); | ||||
|         } | ||||
|         const data = await parseResponse(res); | ||||
|         throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); | ||||
|       } | ||||
|       return res; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| __name(SequentialHandler, "SequentialHandler"); | ||||
| 
 | ||||
| // src/lib/RequestManager.ts
 | ||||
| var getFileType = (0, import_util.lazy)(async () => import("file-type")); | ||||
| var RequestMethod = /* @__PURE__ */ ((RequestMethod2) => { | ||||
|   RequestMethod2["Delete"] = "DELETE"; | ||||
|   RequestMethod2["Get"] = "GET"; | ||||
|   RequestMethod2["Patch"] = "PATCH"; | ||||
|   RequestMethod2["Post"] = "POST"; | ||||
|   RequestMethod2["Put"] = "PUT"; | ||||
|   return RequestMethod2; | ||||
| })(RequestMethod || {}); | ||||
| var RequestManager = class extends import_node_events.EventEmitter { | ||||
|   agent = null; | ||||
|   globalRemaining; | ||||
|   globalDelay = null; | ||||
|   globalReset = -1; | ||||
|   hashes = new import_collection.Collection(); | ||||
|   handlers = new import_collection.Collection(); | ||||
|   #token = null; | ||||
|   hashTimer; | ||||
|   handlerTimer; | ||||
|   options; | ||||
|   constructor(options) { | ||||
|     super(); | ||||
|     this.options = { ...DefaultRestOptions, ...options }; | ||||
|     this.options.offset = Math.max(0, this.options.offset); | ||||
|     this.globalRemaining = this.options.globalRequestsPerSecond; | ||||
|     this.agent = options.agent ?? null; | ||||
|     this.setupSweepers(); | ||||
|   } | ||||
|   setupSweepers() { | ||||
|     const validateMaxInterval = /* @__PURE__ */ __name((interval) => { | ||||
|       if (interval > 144e5) { | ||||
|         throw new Error("Cannot set an interval greater than 4 hours"); | ||||
|       } | ||||
|     }, "validateMaxInterval"); | ||||
|     if (this.options.hashSweepInterval !== 0 && this.options.hashSweepInterval !== Number.POSITIVE_INFINITY) { | ||||
|       validateMaxInterval(this.options.hashSweepInterval); | ||||
|       this.hashTimer = (0, import_node_timers2.setInterval)(() => { | ||||
|         const sweptHashes = new import_collection.Collection(); | ||||
|         const currentDate = Date.now(); | ||||
|         this.hashes.sweep((val, key) => { | ||||
|           if (val.lastAccess === -1) | ||||
|             return false; | ||||
|           const shouldSweep = Math.floor(currentDate - val.lastAccess) > this.options.hashLifetime; | ||||
|           if (shouldSweep) { | ||||
|             sweptHashes.set(key, val); | ||||
|           } | ||||
|           this.emit("restDebug" /* Debug */, `Hash ${val.value} for ${key} swept due to lifetime being exceeded`); | ||||
|           return shouldSweep; | ||||
|         }); | ||||
|         this.emit("hashSweep" /* HashSweep */, sweptHashes); | ||||
|       }, this.options.hashSweepInterval).unref(); | ||||
|     } | ||||
|     if (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Number.POSITIVE_INFINITY) { | ||||
|       validateMaxInterval(this.options.handlerSweepInterval); | ||||
|       this.handlerTimer = (0, import_node_timers2.setInterval)(() => { | ||||
|         const sweptHandlers = new import_collection.Collection(); | ||||
|         this.handlers.sweep((val, key) => { | ||||
|           const { inactive } = val; | ||||
|           if (inactive) { | ||||
|             sweptHandlers.set(key, val); | ||||
|           } | ||||
|           this.emit("restDebug" /* Debug */, `Handler ${val.id} for ${key} swept due to being inactive`); | ||||
|           return inactive; | ||||
|         }); | ||||
|         this.emit("handlerSweep" /* HandlerSweep */, sweptHandlers); | ||||
|       }, this.options.handlerSweepInterval).unref(); | ||||
|     } | ||||
|   } | ||||
|   setAgent(agent) { | ||||
|     this.agent = agent; | ||||
|     return this; | ||||
|   } | ||||
|   setToken(token) { | ||||
|     this.#token = token; | ||||
|     return this; | ||||
|   } | ||||
|   async queueRequest(request2) { | ||||
|     const routeId = RequestManager.generateRouteData(request2.fullRoute, request2.method); | ||||
|     const hash = this.hashes.get(`${request2.method}:${routeId.bucketRoute}`) ?? { | ||||
|       value: `Global(${request2.method}:${routeId.bucketRoute})`, | ||||
|       lastAccess: -1 | ||||
|     }; | ||||
|     const handler = this.handlers.get(`${hash.value}:${routeId.majorParameter}`) ?? this.createHandler(hash.value, routeId.majorParameter); | ||||
|     const { url, fetchOptions } = await this.resolveRequest(request2); | ||||
|     return handler.queueRequest(routeId, url, fetchOptions, { | ||||
|       body: request2.body, | ||||
|       files: request2.files, | ||||
|       auth: request2.auth !== false, | ||||
|       signal: request2.signal | ||||
|     }); | ||||
|   } | ||||
|   createHandler(hash, majorParameter) { | ||||
|     const queue = new SequentialHandler(this, hash, majorParameter); | ||||
|     this.handlers.set(queue.id, queue); | ||||
|     return queue; | ||||
|   } | ||||
|   async resolveRequest(request2) { | ||||
|     const { options } = this; | ||||
|     let query = ""; | ||||
|     if (request2.query) { | ||||
|       const resolvedQuery = request2.query.toString(); | ||||
|       if (resolvedQuery !== "") { | ||||
|         query = `?${resolvedQuery}`; | ||||
|       } | ||||
|     } | ||||
|     const headers = { | ||||
|       ...this.options.headers, | ||||
|       "User-Agent": `${DefaultUserAgent} ${options.userAgentAppendix}`.trim() | ||||
|     }; | ||||
|     if (request2.auth !== false) { | ||||
|       if (!this.#token) { | ||||
|         throw new Error("Expected token to be set for this request, but none was present"); | ||||
|       } | ||||
|       headers.Authorization = `${request2.authPrefix ?? this.options.authPrefix} ${this.#token}`; | ||||
|     } | ||||
|     if (request2.reason?.length) { | ||||
|       headers["X-Audit-Log-Reason"] = encodeURIComponent(request2.reason); | ||||
|     } | ||||
|     const url = `${options.api}${request2.versioned === false ? "" : `/v${options.version}`}${request2.fullRoute}${query}`; | ||||
|     let finalBody; | ||||
|     let additionalHeaders = {}; | ||||
|     if (request2.files?.length) { | ||||
|       const formData = new import_undici4.FormData(); | ||||
|       for (const [index, file] of request2.files.entries()) { | ||||
|         const fileKey = file.key ?? `files[${index}]`; | ||||
|         if (import_node_buffer2.Buffer.isBuffer(file.data)) { | ||||
|           const { fileTypeFromBuffer } = await getFileType(); | ||||
|           const contentType = file.contentType ?? (await fileTypeFromBuffer(file.data))?.mime; | ||||
|           formData.append(fileKey, new import_node_buffer2.Blob([file.data], { type: contentType }), file.name); | ||||
|         } else { | ||||
|           formData.append(fileKey, new import_node_buffer2.Blob([`${file.data}`], { type: file.contentType }), file.name); | ||||
|         } | ||||
|       } | ||||
|       if (request2.body != null) { | ||||
|         if (request2.appendToFormData) { | ||||
|           for (const [key, value] of Object.entries(request2.body)) { | ||||
|             formData.append(key, value); | ||||
|           } | ||||
|         } else { | ||||
|           formData.append("payload_json", JSON.stringify(request2.body)); | ||||
|         } | ||||
|       } | ||||
|       finalBody = formData; | ||||
|     } else if (request2.body != null) { | ||||
|       if (request2.passThroughBody) { | ||||
|         finalBody = request2.body; | ||||
|       } else { | ||||
|         finalBody = JSON.stringify(request2.body); | ||||
|         additionalHeaders = { "Content-Type": "application/json" }; | ||||
|       } | ||||
|     } | ||||
|     finalBody = await resolveBody(finalBody); | ||||
|     const fetchOptions = { | ||||
|       headers: { ...request2.headers, ...additionalHeaders, ...headers }, | ||||
|       method: request2.method.toUpperCase() | ||||
|     }; | ||||
|     if (finalBody !== void 0) { | ||||
|       fetchOptions.body = finalBody; | ||||
|     } | ||||
|     fetchOptions.dispatcher = request2.dispatcher ?? this.agent ?? void 0; | ||||
|     return { url, fetchOptions }; | ||||
|   } | ||||
|   clearHashSweeper() { | ||||
|     (0, import_node_timers2.clearInterval)(this.hashTimer); | ||||
|   } | ||||
|   clearHandlerSweeper() { | ||||
|     (0, import_node_timers2.clearInterval)(this.handlerTimer); | ||||
|   } | ||||
|   static generateRouteData(endpoint, method) { | ||||
|     const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(endpoint); | ||||
|     const majorId = majorIdMatch?.[1] ?? "global"; | ||||
|     const baseRoute = endpoint.replaceAll(/\d{16,19}/g, ":id").replace(/\/reactions\/(.*)/, "/reactions/:reaction"); | ||||
|     let exceptions = ""; | ||||
|     if (method === "DELETE" /* Delete */ && baseRoute === "/channels/:id/messages/:id") { | ||||
|       const id = /\d{16,19}$/.exec(endpoint)[0]; | ||||
|       const timestamp = import_snowflake.DiscordSnowflake.timestampFrom(id); | ||||
|       if (Date.now() - timestamp > 1e3 * 60 * 60 * 24 * 14) { | ||||
|         exceptions += "/Delete Old Message"; | ||||
|       } | ||||
|     } | ||||
|     return { | ||||
|       majorParameter: majorId, | ||||
|       bucketRoute: baseRoute + exceptions, | ||||
|       original: endpoint | ||||
|     }; | ||||
|   } | ||||
| }; | ||||
| __name(RequestManager, "RequestManager"); | ||||
| 
 | ||||
| // src/lib/REST.ts
 | ||||
| var import_node_events2 = require("events"); | ||||
| var REST = class extends import_node_events2.EventEmitter { | ||||
|   cdn; | ||||
|   requestManager; | ||||
|   constructor(options = {}) { | ||||
|     super(); | ||||
|     this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn); | ||||
|     this.requestManager = new RequestManager(options).on("restDebug" /* Debug */, this.emit.bind(this, "restDebug" /* Debug */)).on("rateLimited" /* RateLimited */, this.emit.bind(this, "rateLimited" /* RateLimited */)).on("invalidRequestWarning" /* InvalidRequestWarning */, this.emit.bind(this, "invalidRequestWarning" /* InvalidRequestWarning */)).on("hashSweep" /* HashSweep */, this.emit.bind(this, "hashSweep" /* HashSweep */)); | ||||
|     this.on("newListener", (name, listener) => { | ||||
|       if (name === "response" /* Response */) | ||||
|         this.requestManager.on(name, listener); | ||||
|     }); | ||||
|     this.on("removeListener", (name, listener) => { | ||||
|       if (name === "response" /* Response */) | ||||
|         this.requestManager.off(name, listener); | ||||
|     }); | ||||
|   } | ||||
|   getAgent() { | ||||
|     return this.requestManager.agent; | ||||
|   } | ||||
|   setAgent(agent) { | ||||
|     this.requestManager.setAgent(agent); | ||||
|     return this; | ||||
|   } | ||||
|   setToken(token) { | ||||
|     this.requestManager.setToken(token); | ||||
|     return this; | ||||
|   } | ||||
|   async get(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "GET" /* Get */ }); | ||||
|   } | ||||
|   async delete(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "DELETE" /* Delete */ }); | ||||
|   } | ||||
|   async post(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "POST" /* Post */ }); | ||||
|   } | ||||
|   async put(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "PUT" /* Put */ }); | ||||
|   } | ||||
|   async patch(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "PATCH" /* Patch */ }); | ||||
|   } | ||||
|   async request(options) { | ||||
|     const response = await this.raw(options); | ||||
|     return parseResponse(response); | ||||
|   } | ||||
|   async raw(options) { | ||||
|     return this.requestManager.queueRequest(options); | ||||
|   } | ||||
| }; | ||||
| __name(REST, "REST"); | ||||
| 
 | ||||
| // src/index.ts
 | ||||
| var version = "1.5.0"; | ||||
| // Annotate the CommonJS export names for ESM import in node:
 | ||||
| 0 && (module.exports = { | ||||
|   ALLOWED_EXTENSIONS, | ||||
|   ALLOWED_SIZES, | ||||
|   ALLOWED_STICKER_EXTENSIONS, | ||||
|   CDN, | ||||
|   DefaultRestOptions, | ||||
|   DefaultUserAgent, | ||||
|   DiscordAPIError, | ||||
|   HTTPError, | ||||
|   REST, | ||||
|   RESTEvents, | ||||
|   RateLimitError, | ||||
|   RequestManager, | ||||
|   RequestMethod, | ||||
|   makeURLSearchParams, | ||||
|   parseResponse, | ||||
|   version | ||||
| }); | ||||
| //# sourceMappingURL=index.js.map
 | ||||
							
								
								
									
										1
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										894
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.mjs
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										894
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.mjs
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,894 @@ | |||
| var __defProp = Object.defineProperty; | ||||
| var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); | ||||
| 
 | ||||
| // src/lib/CDN.ts
 | ||||
| import { URL } from "node:url"; | ||||
| 
 | ||||
| // src/lib/utils/constants.ts
 | ||||
| import process from "node:process"; | ||||
| import { APIVersion } from "discord-api-types/v10"; | ||||
| import { Agent } from "undici"; | ||||
| var DefaultUserAgent = `DiscordBot (https://discord.js.org, 1.5.0)`; | ||||
| var DefaultRestOptions = { | ||||
|   get agent() { | ||||
|     return new Agent({ | ||||
|       connect: { | ||||
|         timeout: 3e4 | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|   api: "https://discord.com/api", | ||||
|   authPrefix: "Bot", | ||||
|   cdn: "https://cdn.discordapp.com", | ||||
|   headers: {}, | ||||
|   invalidRequestWarningInterval: 0, | ||||
|   globalRequestsPerSecond: 50, | ||||
|   offset: 50, | ||||
|   rejectOnRateLimit: null, | ||||
|   retries: 3, | ||||
|   timeout: 15e3, | ||||
|   userAgentAppendix: `Node.js ${process.version}`, | ||||
|   version: APIVersion, | ||||
|   hashSweepInterval: 144e5, | ||||
|   hashLifetime: 864e5, | ||||
|   handlerSweepInterval: 36e5 | ||||
| }; | ||||
| var RESTEvents = /* @__PURE__ */ ((RESTEvents2) => { | ||||
|   RESTEvents2["Debug"] = "restDebug"; | ||||
|   RESTEvents2["HandlerSweep"] = "handlerSweep"; | ||||
|   RESTEvents2["HashSweep"] = "hashSweep"; | ||||
|   RESTEvents2["InvalidRequestWarning"] = "invalidRequestWarning"; | ||||
|   RESTEvents2["RateLimited"] = "rateLimited"; | ||||
|   RESTEvents2["Response"] = "response"; | ||||
|   return RESTEvents2; | ||||
| })(RESTEvents || {}); | ||||
| var ALLOWED_EXTENSIONS = ["webp", "png", "jpg", "jpeg", "gif"]; | ||||
| var ALLOWED_STICKER_EXTENSIONS = ["png", "json"]; | ||||
| var ALLOWED_SIZES = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]; | ||||
| 
 | ||||
| // src/lib/CDN.ts
 | ||||
| var CDN = class { | ||||
|   constructor(base = DefaultRestOptions.cdn) { | ||||
|     this.base = base; | ||||
|   } | ||||
|   appAsset(clientId, assetHash, options) { | ||||
|     return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options); | ||||
|   } | ||||
|   appIcon(clientId, iconHash, options) { | ||||
|     return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options); | ||||
|   } | ||||
|   avatar(id, avatarHash, options) { | ||||
|     return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options); | ||||
|   } | ||||
|   banner(id, bannerHash, options) { | ||||
|     return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options); | ||||
|   } | ||||
|   channelIcon(channelId, iconHash, options) { | ||||
|     return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options); | ||||
|   } | ||||
|   defaultAvatar(discriminator) { | ||||
|     return this.makeURL(`/embed/avatars/${discriminator}`, { extension: "png" }); | ||||
|   } | ||||
|   discoverySplash(guildId, splashHash, options) { | ||||
|     return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options); | ||||
|   } | ||||
|   emoji(emojiId, extension) { | ||||
|     return this.makeURL(`/emojis/${emojiId}`, { extension }); | ||||
|   } | ||||
|   guildMemberAvatar(guildId, userId, avatarHash, options) { | ||||
|     return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options); | ||||
|   } | ||||
|   guildMemberBanner(guildId, userId, bannerHash, options) { | ||||
|     return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banner`, bannerHash, options); | ||||
|   } | ||||
|   icon(id, iconHash, options) { | ||||
|     return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options); | ||||
|   } | ||||
|   roleIcon(roleId, roleIconHash, options) { | ||||
|     return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options); | ||||
|   } | ||||
|   splash(guildId, splashHash, options) { | ||||
|     return this.makeURL(`/splashes/${guildId}/${splashHash}`, options); | ||||
|   } | ||||
|   sticker(stickerId, extension) { | ||||
|     return this.makeURL(`/stickers/${stickerId}`, { | ||||
|       allowedExtensions: ALLOWED_STICKER_EXTENSIONS, | ||||
|       extension: extension ?? "png" | ||||
|     }); | ||||
|   } | ||||
|   stickerPackBanner(bannerId, options) { | ||||
|     return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options); | ||||
|   } | ||||
|   teamIcon(teamId, iconHash, options) { | ||||
|     return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options); | ||||
|   } | ||||
|   guildScheduledEventCover(scheduledEventId, coverHash, options) { | ||||
|     return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options); | ||||
|   } | ||||
|   dynamicMakeURL(route, hash, { forceStatic = false, ...options } = {}) { | ||||
|     return this.makeURL(route, !forceStatic && hash.startsWith("a_") ? { ...options, extension: "gif" } : options); | ||||
|   } | ||||
|   makeURL(route, { allowedExtensions = ALLOWED_EXTENSIONS, extension = "webp", size } = {}) { | ||||
|     extension = String(extension).toLowerCase(); | ||||
|     if (!allowedExtensions.includes(extension)) { | ||||
|       throw new RangeError(`Invalid extension provided: ${extension} | ||||
| Must be one of: ${allowedExtensions.join(", ")}`);
 | ||||
|     } | ||||
|     if (size && !ALLOWED_SIZES.includes(size)) { | ||||
|       throw new RangeError(`Invalid size provided: ${size} | ||||
| Must be one of: ${ALLOWED_SIZES.join(", ")}`);
 | ||||
|     } | ||||
|     const url = new URL(`${this.base}${route}.${extension}`); | ||||
|     if (size) { | ||||
|       url.searchParams.set("size", String(size)); | ||||
|     } | ||||
|     return url.toString(); | ||||
|   } | ||||
| }; | ||||
| __name(CDN, "CDN"); | ||||
| 
 | ||||
| // src/lib/errors/DiscordAPIError.ts
 | ||||
| function isErrorGroupWrapper(error) { | ||||
|   return Reflect.has(error, "_errors"); | ||||
| } | ||||
| __name(isErrorGroupWrapper, "isErrorGroupWrapper"); | ||||
| function isErrorResponse(error) { | ||||
|   return typeof Reflect.get(error, "message") === "string"; | ||||
| } | ||||
| __name(isErrorResponse, "isErrorResponse"); | ||||
| var DiscordAPIError = class extends Error { | ||||
|   constructor(rawError, code, status, method, url, bodyData) { | ||||
|     super(DiscordAPIError.getMessage(rawError)); | ||||
|     this.rawError = rawError; | ||||
|     this.code = code; | ||||
|     this.status = status; | ||||
|     this.method = method; | ||||
|     this.url = url; | ||||
|     this.requestBody = { files: bodyData.files, json: bodyData.body }; | ||||
|   } | ||||
|   requestBody; | ||||
|   get name() { | ||||
|     return `${DiscordAPIError.name}[${this.code}]`; | ||||
|   } | ||||
|   static getMessage(error) { | ||||
|     let flattened = ""; | ||||
|     if ("code" in error) { | ||||
|       if (error.errors) { | ||||
|         flattened = [...this.flattenDiscordError(error.errors)].join("\n"); | ||||
|       } | ||||
|       return error.message && flattened ? `${error.message} | ||||
| ${flattened}` : error.message || flattened || "Unknown Error";
 | ||||
|     } | ||||
|     return error.error_description ?? "No Description"; | ||||
|   } | ||||
|   static *flattenDiscordError(obj, key = "") { | ||||
|     if (isErrorResponse(obj)) { | ||||
|       return yield `${key.length ? `${key}[${obj.code}]` : `${obj.code}`}: ${obj.message}`.trim(); | ||||
|     } | ||||
|     for (const [otherKey, val] of Object.entries(obj)) { | ||||
|       const nextKey = otherKey.startsWith("_") ? key : key ? Number.isNaN(Number(otherKey)) ? `${key}.${otherKey}` : `${key}[${otherKey}]` : otherKey; | ||||
|       if (typeof val === "string") { | ||||
|         yield val; | ||||
|       } else if (isErrorGroupWrapper(val)) { | ||||
|         for (const error of val._errors) { | ||||
|           yield* this.flattenDiscordError(error, nextKey); | ||||
|         } | ||||
|       } else { | ||||
|         yield* this.flattenDiscordError(val, nextKey); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| __name(DiscordAPIError, "DiscordAPIError"); | ||||
| 
 | ||||
| // src/lib/errors/HTTPError.ts
 | ||||
| import { STATUS_CODES } from "node:http"; | ||||
| var HTTPError = class extends Error { | ||||
|   constructor(status, method, url, bodyData) { | ||||
|     super(STATUS_CODES[status]); | ||||
|     this.status = status; | ||||
|     this.method = method; | ||||
|     this.url = url; | ||||
|     this.requestBody = { files: bodyData.files, json: bodyData.body }; | ||||
|   } | ||||
|   requestBody; | ||||
|   name = HTTPError.name; | ||||
| }; | ||||
| __name(HTTPError, "HTTPError"); | ||||
| 
 | ||||
| // src/lib/errors/RateLimitError.ts
 | ||||
| var RateLimitError = class extends Error { | ||||
|   timeToReset; | ||||
|   limit; | ||||
|   method; | ||||
|   hash; | ||||
|   url; | ||||
|   route; | ||||
|   majorParameter; | ||||
|   global; | ||||
|   constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }) { | ||||
|     super(); | ||||
|     this.timeToReset = timeToReset; | ||||
|     this.limit = limit; | ||||
|     this.method = method; | ||||
|     this.hash = hash; | ||||
|     this.url = url; | ||||
|     this.route = route; | ||||
|     this.majorParameter = majorParameter; | ||||
|     this.global = global; | ||||
|   } | ||||
|   get name() { | ||||
|     return `${RateLimitError.name}[${this.route}]`; | ||||
|   } | ||||
| }; | ||||
| __name(RateLimitError, "RateLimitError"); | ||||
| 
 | ||||
| // src/lib/RequestManager.ts
 | ||||
| import { Blob as Blob2, Buffer as Buffer3 } from "node:buffer"; | ||||
| import { EventEmitter } from "node:events"; | ||||
| import { setInterval, clearInterval } from "node:timers"; | ||||
| import { Collection } from "@discordjs/collection"; | ||||
| import { lazy } from "@discordjs/util"; | ||||
| import { DiscordSnowflake } from "@sapphire/snowflake"; | ||||
| import { FormData as FormData2 } from "undici"; | ||||
| 
 | ||||
| // src/lib/handlers/SequentialHandler.ts
 | ||||
| import { setTimeout, clearTimeout } from "node:timers"; | ||||
| import { setTimeout as sleep } from "node:timers/promises"; | ||||
| import { AsyncQueue } from "@sapphire/async-queue"; | ||||
| import { request } from "undici"; | ||||
| 
 | ||||
| // src/lib/utils/utils.ts
 | ||||
| import { Blob, Buffer as Buffer2 } from "node:buffer"; | ||||
| import { URLSearchParams } from "node:url"; | ||||
| import { types } from "node:util"; | ||||
| import { FormData } from "undici"; | ||||
| function parseHeader(header) { | ||||
|   if (header === void 0 || typeof header === "string") { | ||||
|     return header; | ||||
|   } | ||||
|   return header.join(";"); | ||||
| } | ||||
| __name(parseHeader, "parseHeader"); | ||||
| function serializeSearchParam(value) { | ||||
|   switch (typeof value) { | ||||
|     case "string": | ||||
|       return value; | ||||
|     case "number": | ||||
|     case "bigint": | ||||
|     case "boolean": | ||||
|       return value.toString(); | ||||
|     case "object": | ||||
|       if (value === null) | ||||
|         return null; | ||||
|       if (value instanceof Date) { | ||||
|         return Number.isNaN(value.getTime()) ? null : value.toISOString(); | ||||
|       } | ||||
|       if (typeof value.toString === "function" && value.toString !== Object.prototype.toString) | ||||
|         return value.toString(); | ||||
|       return null; | ||||
|     default: | ||||
|       return null; | ||||
|   } | ||||
| } | ||||
| __name(serializeSearchParam, "serializeSearchParam"); | ||||
| function makeURLSearchParams(options) { | ||||
|   const params = new URLSearchParams(); | ||||
|   if (!options) | ||||
|     return params; | ||||
|   for (const [key, value] of Object.entries(options)) { | ||||
|     const serialized = serializeSearchParam(value); | ||||
|     if (serialized !== null) | ||||
|       params.append(key, serialized); | ||||
|   } | ||||
|   return params; | ||||
| } | ||||
| __name(makeURLSearchParams, "makeURLSearchParams"); | ||||
| async function parseResponse(res) { | ||||
|   const header = parseHeader(res.headers["content-type"]); | ||||
|   if (header?.startsWith("application/json")) { | ||||
|     return res.body.json(); | ||||
|   } | ||||
|   return res.body.arrayBuffer(); | ||||
| } | ||||
| __name(parseResponse, "parseResponse"); | ||||
| function hasSublimit(bucketRoute, body, method) { | ||||
|   if (bucketRoute === "/channels/:id") { | ||||
|     if (typeof body !== "object" || body === null) | ||||
|       return false; | ||||
|     if (method !== "PATCH" /* Patch */) | ||||
|       return false; | ||||
|     const castedBody = body; | ||||
|     return ["name", "topic"].some((key) => Reflect.has(castedBody, key)); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| __name(hasSublimit, "hasSublimit"); | ||||
| async function resolveBody(body) { | ||||
|   if (body == null) { | ||||
|     return null; | ||||
|   } else if (typeof body === "string") { | ||||
|     return body; | ||||
|   } else if (types.isUint8Array(body)) { | ||||
|     return body; | ||||
|   } else if (types.isArrayBuffer(body)) { | ||||
|     return new Uint8Array(body); | ||||
|   } else if (body instanceof URLSearchParams) { | ||||
|     return body.toString(); | ||||
|   } else if (body instanceof DataView) { | ||||
|     return new Uint8Array(body.buffer); | ||||
|   } else if (body instanceof Blob) { | ||||
|     return new Uint8Array(await body.arrayBuffer()); | ||||
|   } else if (body instanceof FormData) { | ||||
|     return body; | ||||
|   } else if (body[Symbol.iterator]) { | ||||
|     const chunks = [...body]; | ||||
|     const length = chunks.reduce((a, b) => a + b.length, 0); | ||||
|     const uint8 = new Uint8Array(length); | ||||
|     let lengthUsed = 0; | ||||
|     return chunks.reduce((a, b) => { | ||||
|       a.set(b, lengthUsed); | ||||
|       lengthUsed += b.length; | ||||
|       return a; | ||||
|     }, uint8); | ||||
|   } else if (body[Symbol.asyncIterator]) { | ||||
|     const chunks = []; | ||||
|     for await (const chunk of body) { | ||||
|       chunks.push(chunk); | ||||
|     } | ||||
|     return Buffer2.concat(chunks); | ||||
|   } | ||||
|   throw new TypeError(`Unable to resolve body.`); | ||||
| } | ||||
| __name(resolveBody, "resolveBody"); | ||||
| function shouldRetry(error) { | ||||
|   if (error.name === "AbortError") | ||||
|     return true; | ||||
|   return "code" in error && error.code === "ECONNRESET" || error.message.includes("ECONNRESET"); | ||||
| } | ||||
| __name(shouldRetry, "shouldRetry"); | ||||
| 
 | ||||
| // src/lib/handlers/SequentialHandler.ts
 | ||||
| var invalidCount = 0; | ||||
| var invalidCountResetTime = null; | ||||
| var SequentialHandler = class { | ||||
|   constructor(manager, hash, majorParameter) { | ||||
|     this.manager = manager; | ||||
|     this.hash = hash; | ||||
|     this.majorParameter = majorParameter; | ||||
|     this.id = `${hash}:${majorParameter}`; | ||||
|   } | ||||
|   id; | ||||
|   reset = -1; | ||||
|   remaining = 1; | ||||
|   limit = Number.POSITIVE_INFINITY; | ||||
|   #asyncQueue = new AsyncQueue(); | ||||
|   #sublimitedQueue = null; | ||||
|   #sublimitPromise = null; | ||||
|   #shiftSublimit = false; | ||||
|   get inactive() { | ||||
|     return this.#asyncQueue.remaining === 0 && (this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) && !this.limited; | ||||
|   } | ||||
|   get globalLimited() { | ||||
|     return this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset; | ||||
|   } | ||||
|   get localLimited() { | ||||
|     return this.remaining <= 0 && Date.now() < this.reset; | ||||
|   } | ||||
|   get limited() { | ||||
|     return this.globalLimited || this.localLimited; | ||||
|   } | ||||
|   get timeToReset() { | ||||
|     return this.reset + this.manager.options.offset - Date.now(); | ||||
|   } | ||||
|   debug(message) { | ||||
|     this.manager.emit("restDebug" /* Debug */, `[REST ${this.id}] ${message}`); | ||||
|   } | ||||
|   async globalDelayFor(time) { | ||||
|     await sleep(time); | ||||
|     this.manager.globalDelay = null; | ||||
|   } | ||||
|   async onRateLimit(rateLimitData) { | ||||
|     const { options } = this.manager; | ||||
|     if (!options.rejectOnRateLimit) | ||||
|       return; | ||||
|     const shouldThrow = typeof options.rejectOnRateLimit === "function" ? await options.rejectOnRateLimit(rateLimitData) : options.rejectOnRateLimit.some((route) => rateLimitData.route.startsWith(route.toLowerCase())); | ||||
|     if (shouldThrow) { | ||||
|       throw new RateLimitError(rateLimitData); | ||||
|     } | ||||
|   } | ||||
|   async queueRequest(routeId, url, options, requestData) { | ||||
|     let queue = this.#asyncQueue; | ||||
|     let queueType = 0 /* Standard */; | ||||
|     if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) { | ||||
|       queue = this.#sublimitedQueue; | ||||
|       queueType = 1 /* Sublimit */; | ||||
|     } | ||||
|     await queue.wait({ signal: requestData.signal }); | ||||
|     if (queueType === 0 /* Standard */) { | ||||
|       if (this.#sublimitedQueue && hasSublimit(routeId.bucketRoute, requestData.body, options.method)) { | ||||
|         queue = this.#sublimitedQueue; | ||||
|         const wait = queue.wait(); | ||||
|         this.#asyncQueue.shift(); | ||||
|         await wait; | ||||
|       } else if (this.#sublimitPromise) { | ||||
|         await this.#sublimitPromise.promise; | ||||
|       } | ||||
|     } | ||||
|     try { | ||||
|       return await this.runRequest(routeId, url, options, requestData); | ||||
|     } finally { | ||||
|       queue.shift(); | ||||
|       if (this.#shiftSublimit) { | ||||
|         this.#shiftSublimit = false; | ||||
|         this.#sublimitedQueue?.shift(); | ||||
|       } | ||||
|       if (this.#sublimitedQueue?.remaining === 0) { | ||||
|         this.#sublimitPromise?.resolve(); | ||||
|         this.#sublimitedQueue = null; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   async runRequest(routeId, url, options, requestData, retries = 0) { | ||||
|     while (this.limited) { | ||||
|       const isGlobal = this.globalLimited; | ||||
|       let limit2; | ||||
|       let timeout2; | ||||
|       let delay; | ||||
|       if (isGlobal) { | ||||
|         limit2 = this.manager.options.globalRequestsPerSecond; | ||||
|         timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now(); | ||||
|         if (!this.manager.globalDelay) { | ||||
|           this.manager.globalDelay = this.globalDelayFor(timeout2); | ||||
|         } | ||||
|         delay = this.manager.globalDelay; | ||||
|       } else { | ||||
|         limit2 = this.limit; | ||||
|         timeout2 = this.timeToReset; | ||||
|         delay = sleep(timeout2); | ||||
|       } | ||||
|       const rateLimitData = { | ||||
|         timeToReset: timeout2, | ||||
|         limit: limit2, | ||||
|         method: options.method ?? "get", | ||||
|         hash: this.hash, | ||||
|         url, | ||||
|         route: routeId.bucketRoute, | ||||
|         majorParameter: this.majorParameter, | ||||
|         global: isGlobal | ||||
|       }; | ||||
|       this.manager.emit("rateLimited" /* RateLimited */, rateLimitData); | ||||
|       await this.onRateLimit(rateLimitData); | ||||
|       if (isGlobal) { | ||||
|         this.debug(`Global rate limit hit, blocking all requests for ${timeout2}ms`); | ||||
|       } else { | ||||
|         this.debug(`Waiting ${timeout2}ms for rate limit to pass`); | ||||
|       } | ||||
|       await delay; | ||||
|     } | ||||
|     if (!this.manager.globalReset || this.manager.globalReset < Date.now()) { | ||||
|       this.manager.globalReset = Date.now() + 1e3; | ||||
|       this.manager.globalRemaining = this.manager.options.globalRequestsPerSecond; | ||||
|     } | ||||
|     this.manager.globalRemaining--; | ||||
|     const method = options.method ?? "get"; | ||||
|     const controller = new AbortController(); | ||||
|     const timeout = setTimeout(() => controller.abort(), this.manager.options.timeout).unref(); | ||||
|     if (requestData.signal) { | ||||
|       const signal = requestData.signal; | ||||
|       if (signal.aborted) | ||||
|         controller.abort(); | ||||
|       else | ||||
|         signal.addEventListener("abort", () => controller.abort()); | ||||
|     } | ||||
|     let res; | ||||
|     try { | ||||
|       res = await request(url, { ...options, signal: controller.signal }); | ||||
|     } catch (error) { | ||||
|       if (!(error instanceof Error)) | ||||
|         throw error; | ||||
|       if (shouldRetry(error) && retries !== this.manager.options.retries) { | ||||
|         return await this.runRequest(routeId, url, options, requestData, ++retries); | ||||
|       } | ||||
|       throw error; | ||||
|     } finally { | ||||
|       clearTimeout(timeout); | ||||
|     } | ||||
|     if (this.manager.listenerCount("response" /* Response */)) { | ||||
|       this.manager.emit( | ||||
|         "response" /* Response */, | ||||
|         { | ||||
|           method, | ||||
|           path: routeId.original, | ||||
|           route: routeId.bucketRoute, | ||||
|           options, | ||||
|           data: requestData, | ||||
|           retries | ||||
|         }, | ||||
|         { ...res } | ||||
|       ); | ||||
|     } | ||||
|     const status = res.statusCode; | ||||
|     let retryAfter = 0; | ||||
|     const limit = parseHeader(res.headers["x-ratelimit-limit"]); | ||||
|     const remaining = parseHeader(res.headers["x-ratelimit-remaining"]); | ||||
|     const reset = parseHeader(res.headers["x-ratelimit-reset-after"]); | ||||
|     const hash = parseHeader(res.headers["x-ratelimit-bucket"]); | ||||
|     const retry = parseHeader(res.headers["retry-after"]); | ||||
|     this.limit = limit ? Number(limit) : Number.POSITIVE_INFINITY; | ||||
|     this.remaining = remaining ? Number(remaining) : 1; | ||||
|     this.reset = reset ? Number(reset) * 1e3 + Date.now() + this.manager.options.offset : Date.now(); | ||||
|     if (retry) | ||||
|       retryAfter = Number(retry) * 1e3 + this.manager.options.offset; | ||||
|     if (hash && hash !== this.hash) { | ||||
|       this.debug(["Received bucket hash update", `  Old Hash  : ${this.hash}`, `  New Hash  : ${hash}`].join("\n")); | ||||
|       this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() }); | ||||
|     } else if (hash) { | ||||
|       const hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`); | ||||
|       if (hashData) { | ||||
|         hashData.lastAccess = Date.now(); | ||||
|       } | ||||
|     } | ||||
|     let sublimitTimeout = null; | ||||
|     if (retryAfter > 0) { | ||||
|       if (res.headers["x-ratelimit-global"] !== void 0) { | ||||
|         this.manager.globalRemaining = 0; | ||||
|         this.manager.globalReset = Date.now() + retryAfter; | ||||
|       } else if (!this.localLimited) { | ||||
|         sublimitTimeout = retryAfter; | ||||
|       } | ||||
|     } | ||||
|     if (status === 401 || status === 403 || status === 429) { | ||||
|       if (!invalidCountResetTime || invalidCountResetTime < Date.now()) { | ||||
|         invalidCountResetTime = Date.now() + 1e3 * 60 * 10; | ||||
|         invalidCount = 0; | ||||
|       } | ||||
|       invalidCount++; | ||||
|       const emitInvalid = this.manager.options.invalidRequestWarningInterval > 0 && invalidCount % this.manager.options.invalidRequestWarningInterval === 0; | ||||
|       if (emitInvalid) { | ||||
|         this.manager.emit("invalidRequestWarning" /* InvalidRequestWarning */, { | ||||
|           count: invalidCount, | ||||
|           remainingTime: invalidCountResetTime - Date.now() | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|     if (status >= 200 && status < 300) { | ||||
|       return res; | ||||
|     } else if (status === 429) { | ||||
|       const isGlobal = this.globalLimited; | ||||
|       let limit2; | ||||
|       let timeout2; | ||||
|       if (isGlobal) { | ||||
|         limit2 = this.manager.options.globalRequestsPerSecond; | ||||
|         timeout2 = this.manager.globalReset + this.manager.options.offset - Date.now(); | ||||
|       } else { | ||||
|         limit2 = this.limit; | ||||
|         timeout2 = this.timeToReset; | ||||
|       } | ||||
|       await this.onRateLimit({ | ||||
|         timeToReset: timeout2, | ||||
|         limit: limit2, | ||||
|         method, | ||||
|         hash: this.hash, | ||||
|         url, | ||||
|         route: routeId.bucketRoute, | ||||
|         majorParameter: this.majorParameter, | ||||
|         global: isGlobal | ||||
|       }); | ||||
|       this.debug( | ||||
|         [ | ||||
|           "Encountered unexpected 429 rate limit", | ||||
|           `  Global         : ${isGlobal.toString()}`, | ||||
|           `  Method         : ${method}`, | ||||
|           `  URL            : ${url}`, | ||||
|           `  Bucket         : ${routeId.bucketRoute}`, | ||||
|           `  Major parameter: ${routeId.majorParameter}`, | ||||
|           `  Hash           : ${this.hash}`, | ||||
|           `  Limit          : ${limit2}`, | ||||
|           `  Retry After    : ${retryAfter}ms`, | ||||
|           `  Sublimit       : ${sublimitTimeout ? `${sublimitTimeout}ms` : "None"}` | ||||
|         ].join("\n") | ||||
|       ); | ||||
|       if (sublimitTimeout) { | ||||
|         const firstSublimit = !this.#sublimitedQueue; | ||||
|         if (firstSublimit) { | ||||
|           this.#sublimitedQueue = new AsyncQueue(); | ||||
|           void this.#sublimitedQueue.wait(); | ||||
|           this.#asyncQueue.shift(); | ||||
|         } | ||||
|         this.#sublimitPromise?.resolve(); | ||||
|         this.#sublimitPromise = null; | ||||
|         await sleep(sublimitTimeout); | ||||
|         let resolve; | ||||
|         const promise = new Promise((res2) => resolve = res2); | ||||
|         this.#sublimitPromise = { promise, resolve }; | ||||
|         if (firstSublimit) { | ||||
|           await this.#asyncQueue.wait(); | ||||
|           this.#shiftSublimit = true; | ||||
|         } | ||||
|       } | ||||
|       return this.runRequest(routeId, url, options, requestData, retries); | ||||
|     } else if (status >= 500 && status < 600) { | ||||
|       if (retries !== this.manager.options.retries) { | ||||
|         return this.runRequest(routeId, url, options, requestData, ++retries); | ||||
|       } | ||||
|       throw new HTTPError(status, method, url, requestData); | ||||
|     } else { | ||||
|       if (status >= 400 && status < 500) { | ||||
|         if (status === 401 && requestData.auth) { | ||||
|           this.manager.setToken(null); | ||||
|         } | ||||
|         const data = await parseResponse(res); | ||||
|         throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); | ||||
|       } | ||||
|       return res; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| __name(SequentialHandler, "SequentialHandler"); | ||||
| 
 | ||||
| // src/lib/RequestManager.ts
 | ||||
| var getFileType = lazy(async () => import("file-type")); | ||||
| var RequestMethod = /* @__PURE__ */ ((RequestMethod2) => { | ||||
|   RequestMethod2["Delete"] = "DELETE"; | ||||
|   RequestMethod2["Get"] = "GET"; | ||||
|   RequestMethod2["Patch"] = "PATCH"; | ||||
|   RequestMethod2["Post"] = "POST"; | ||||
|   RequestMethod2["Put"] = "PUT"; | ||||
|   return RequestMethod2; | ||||
| })(RequestMethod || {}); | ||||
| var RequestManager = class extends EventEmitter { | ||||
|   agent = null; | ||||
|   globalRemaining; | ||||
|   globalDelay = null; | ||||
|   globalReset = -1; | ||||
|   hashes = new Collection(); | ||||
|   handlers = new Collection(); | ||||
|   #token = null; | ||||
|   hashTimer; | ||||
|   handlerTimer; | ||||
|   options; | ||||
|   constructor(options) { | ||||
|     super(); | ||||
|     this.options = { ...DefaultRestOptions, ...options }; | ||||
|     this.options.offset = Math.max(0, this.options.offset); | ||||
|     this.globalRemaining = this.options.globalRequestsPerSecond; | ||||
|     this.agent = options.agent ?? null; | ||||
|     this.setupSweepers(); | ||||
|   } | ||||
|   setupSweepers() { | ||||
|     const validateMaxInterval = /* @__PURE__ */ __name((interval) => { | ||||
|       if (interval > 144e5) { | ||||
|         throw new Error("Cannot set an interval greater than 4 hours"); | ||||
|       } | ||||
|     }, "validateMaxInterval"); | ||||
|     if (this.options.hashSweepInterval !== 0 && this.options.hashSweepInterval !== Number.POSITIVE_INFINITY) { | ||||
|       validateMaxInterval(this.options.hashSweepInterval); | ||||
|       this.hashTimer = setInterval(() => { | ||||
|         const sweptHashes = new Collection(); | ||||
|         const currentDate = Date.now(); | ||||
|         this.hashes.sweep((val, key) => { | ||||
|           if (val.lastAccess === -1) | ||||
|             return false; | ||||
|           const shouldSweep = Math.floor(currentDate - val.lastAccess) > this.options.hashLifetime; | ||||
|           if (shouldSweep) { | ||||
|             sweptHashes.set(key, val); | ||||
|           } | ||||
|           this.emit("restDebug" /* Debug */, `Hash ${val.value} for ${key} swept due to lifetime being exceeded`); | ||||
|           return shouldSweep; | ||||
|         }); | ||||
|         this.emit("hashSweep" /* HashSweep */, sweptHashes); | ||||
|       }, this.options.hashSweepInterval).unref(); | ||||
|     } | ||||
|     if (this.options.handlerSweepInterval !== 0 && this.options.handlerSweepInterval !== Number.POSITIVE_INFINITY) { | ||||
|       validateMaxInterval(this.options.handlerSweepInterval); | ||||
|       this.handlerTimer = setInterval(() => { | ||||
|         const sweptHandlers = new Collection(); | ||||
|         this.handlers.sweep((val, key) => { | ||||
|           const { inactive } = val; | ||||
|           if (inactive) { | ||||
|             sweptHandlers.set(key, val); | ||||
|           } | ||||
|           this.emit("restDebug" /* Debug */, `Handler ${val.id} for ${key} swept due to being inactive`); | ||||
|           return inactive; | ||||
|         }); | ||||
|         this.emit("handlerSweep" /* HandlerSweep */, sweptHandlers); | ||||
|       }, this.options.handlerSweepInterval).unref(); | ||||
|     } | ||||
|   } | ||||
|   setAgent(agent) { | ||||
|     this.agent = agent; | ||||
|     return this; | ||||
|   } | ||||
|   setToken(token) { | ||||
|     this.#token = token; | ||||
|     return this; | ||||
|   } | ||||
|   async queueRequest(request2) { | ||||
|     const routeId = RequestManager.generateRouteData(request2.fullRoute, request2.method); | ||||
|     const hash = this.hashes.get(`${request2.method}:${routeId.bucketRoute}`) ?? { | ||||
|       value: `Global(${request2.method}:${routeId.bucketRoute})`, | ||||
|       lastAccess: -1 | ||||
|     }; | ||||
|     const handler = this.handlers.get(`${hash.value}:${routeId.majorParameter}`) ?? this.createHandler(hash.value, routeId.majorParameter); | ||||
|     const { url, fetchOptions } = await this.resolveRequest(request2); | ||||
|     return handler.queueRequest(routeId, url, fetchOptions, { | ||||
|       body: request2.body, | ||||
|       files: request2.files, | ||||
|       auth: request2.auth !== false, | ||||
|       signal: request2.signal | ||||
|     }); | ||||
|   } | ||||
|   createHandler(hash, majorParameter) { | ||||
|     const queue = new SequentialHandler(this, hash, majorParameter); | ||||
|     this.handlers.set(queue.id, queue); | ||||
|     return queue; | ||||
|   } | ||||
|   async resolveRequest(request2) { | ||||
|     const { options } = this; | ||||
|     let query = ""; | ||||
|     if (request2.query) { | ||||
|       const resolvedQuery = request2.query.toString(); | ||||
|       if (resolvedQuery !== "") { | ||||
|         query = `?${resolvedQuery}`; | ||||
|       } | ||||
|     } | ||||
|     const headers = { | ||||
|       ...this.options.headers, | ||||
|       "User-Agent": `${DefaultUserAgent} ${options.userAgentAppendix}`.trim() | ||||
|     }; | ||||
|     if (request2.auth !== false) { | ||||
|       if (!this.#token) { | ||||
|         throw new Error("Expected token to be set for this request, but none was present"); | ||||
|       } | ||||
|       headers.Authorization = `${request2.authPrefix ?? this.options.authPrefix} ${this.#token}`; | ||||
|     } | ||||
|     if (request2.reason?.length) { | ||||
|       headers["X-Audit-Log-Reason"] = encodeURIComponent(request2.reason); | ||||
|     } | ||||
|     const url = `${options.api}${request2.versioned === false ? "" : `/v${options.version}`}${request2.fullRoute}${query}`; | ||||
|     let finalBody; | ||||
|     let additionalHeaders = {}; | ||||
|     if (request2.files?.length) { | ||||
|       const formData = new FormData2(); | ||||
|       for (const [index, file] of request2.files.entries()) { | ||||
|         const fileKey = file.key ?? `files[${index}]`; | ||||
|         if (Buffer3.isBuffer(file.data)) { | ||||
|           const { fileTypeFromBuffer } = await getFileType(); | ||||
|           const contentType = file.contentType ?? (await fileTypeFromBuffer(file.data))?.mime; | ||||
|           formData.append(fileKey, new Blob2([file.data], { type: contentType }), file.name); | ||||
|         } else { | ||||
|           formData.append(fileKey, new Blob2([`${file.data}`], { type: file.contentType }), file.name); | ||||
|         } | ||||
|       } | ||||
|       if (request2.body != null) { | ||||
|         if (request2.appendToFormData) { | ||||
|           for (const [key, value] of Object.entries(request2.body)) { | ||||
|             formData.append(key, value); | ||||
|           } | ||||
|         } else { | ||||
|           formData.append("payload_json", JSON.stringify(request2.body)); | ||||
|         } | ||||
|       } | ||||
|       finalBody = formData; | ||||
|     } else if (request2.body != null) { | ||||
|       if (request2.passThroughBody) { | ||||
|         finalBody = request2.body; | ||||
|       } else { | ||||
|         finalBody = JSON.stringify(request2.body); | ||||
|         additionalHeaders = { "Content-Type": "application/json" }; | ||||
|       } | ||||
|     } | ||||
|     finalBody = await resolveBody(finalBody); | ||||
|     const fetchOptions = { | ||||
|       headers: { ...request2.headers, ...additionalHeaders, ...headers }, | ||||
|       method: request2.method.toUpperCase() | ||||
|     }; | ||||
|     if (finalBody !== void 0) { | ||||
|       fetchOptions.body = finalBody; | ||||
|     } | ||||
|     fetchOptions.dispatcher = request2.dispatcher ?? this.agent ?? void 0; | ||||
|     return { url, fetchOptions }; | ||||
|   } | ||||
|   clearHashSweeper() { | ||||
|     clearInterval(this.hashTimer); | ||||
|   } | ||||
|   clearHandlerSweeper() { | ||||
|     clearInterval(this.handlerTimer); | ||||
|   } | ||||
|   static generateRouteData(endpoint, method) { | ||||
|     const majorIdMatch = /^\/(?:channels|guilds|webhooks)\/(\d{16,19})/.exec(endpoint); | ||||
|     const majorId = majorIdMatch?.[1] ?? "global"; | ||||
|     const baseRoute = endpoint.replaceAll(/\d{16,19}/g, ":id").replace(/\/reactions\/(.*)/, "/reactions/:reaction"); | ||||
|     let exceptions = ""; | ||||
|     if (method === "DELETE" /* Delete */ && baseRoute === "/channels/:id/messages/:id") { | ||||
|       const id = /\d{16,19}$/.exec(endpoint)[0]; | ||||
|       const timestamp = DiscordSnowflake.timestampFrom(id); | ||||
|       if (Date.now() - timestamp > 1e3 * 60 * 60 * 24 * 14) { | ||||
|         exceptions += "/Delete Old Message"; | ||||
|       } | ||||
|     } | ||||
|     return { | ||||
|       majorParameter: majorId, | ||||
|       bucketRoute: baseRoute + exceptions, | ||||
|       original: endpoint | ||||
|     }; | ||||
|   } | ||||
| }; | ||||
| __name(RequestManager, "RequestManager"); | ||||
| 
 | ||||
| // src/lib/REST.ts
 | ||||
| import { EventEmitter as EventEmitter2 } from "node:events"; | ||||
| var REST = class extends EventEmitter2 { | ||||
|   cdn; | ||||
|   requestManager; | ||||
|   constructor(options = {}) { | ||||
|     super(); | ||||
|     this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn); | ||||
|     this.requestManager = new RequestManager(options).on("restDebug" /* Debug */, this.emit.bind(this, "restDebug" /* Debug */)).on("rateLimited" /* RateLimited */, this.emit.bind(this, "rateLimited" /* RateLimited */)).on("invalidRequestWarning" /* InvalidRequestWarning */, this.emit.bind(this, "invalidRequestWarning" /* InvalidRequestWarning */)).on("hashSweep" /* HashSweep */, this.emit.bind(this, "hashSweep" /* HashSweep */)); | ||||
|     this.on("newListener", (name, listener) => { | ||||
|       if (name === "response" /* Response */) | ||||
|         this.requestManager.on(name, listener); | ||||
|     }); | ||||
|     this.on("removeListener", (name, listener) => { | ||||
|       if (name === "response" /* Response */) | ||||
|         this.requestManager.off(name, listener); | ||||
|     }); | ||||
|   } | ||||
|   getAgent() { | ||||
|     return this.requestManager.agent; | ||||
|   } | ||||
|   setAgent(agent) { | ||||
|     this.requestManager.setAgent(agent); | ||||
|     return this; | ||||
|   } | ||||
|   setToken(token) { | ||||
|     this.requestManager.setToken(token); | ||||
|     return this; | ||||
|   } | ||||
|   async get(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "GET" /* Get */ }); | ||||
|   } | ||||
|   async delete(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "DELETE" /* Delete */ }); | ||||
|   } | ||||
|   async post(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "POST" /* Post */ }); | ||||
|   } | ||||
|   async put(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "PUT" /* Put */ }); | ||||
|   } | ||||
|   async patch(fullRoute, options = {}) { | ||||
|     return this.request({ ...options, fullRoute, method: "PATCH" /* Patch */ }); | ||||
|   } | ||||
|   async request(options) { | ||||
|     const response = await this.raw(options); | ||||
|     return parseResponse(response); | ||||
|   } | ||||
|   async raw(options) { | ||||
|     return this.requestManager.queueRequest(options); | ||||
|   } | ||||
| }; | ||||
| __name(REST, "REST"); | ||||
| 
 | ||||
| // src/index.ts
 | ||||
| var version = "1.5.0"; | ||||
| export { | ||||
|   ALLOWED_EXTENSIONS, | ||||
|   ALLOWED_SIZES, | ||||
|   ALLOWED_STICKER_EXTENSIONS, | ||||
|   CDN, | ||||
|   DefaultRestOptions, | ||||
|   DefaultUserAgent, | ||||
|   DiscordAPIError, | ||||
|   HTTPError, | ||||
|   REST, | ||||
|   RESTEvents, | ||||
|   RateLimitError, | ||||
|   RequestManager, | ||||
|   RequestMethod, | ||||
|   makeURLSearchParams, | ||||
|   parseResponse, | ||||
|   version | ||||
| }; | ||||
| //# sourceMappingURL=index.mjs.map
 | ||||
							
								
								
									
										1
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.mjs.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sidBot-js/node_modules/@discordjs/rest/dist/index.mjs.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in a new issue
	
	 Sid
						Sid