@snazzah/emoji-sync
Version:
Sync Discord emojis with your app
426 lines (416 loc) • 13.9 kB
TypeScript
import * as undici_types from 'undici-types';
import EventEmitter from 'eventemitter3';
/**
* Represents a bucket for handling ratelimiting.
*/
declare class SequentialBucket {
#private;
/** The maximum requests that can be made by the bucket. */
limit: number;
/** The remaining requests that can be made by the bucket. */
remaining: number;
/** The timestamp of the next reset. */
reset: number;
/**
* Represents a bucket for handling ratelimiting.
* @arg rest Represents the RequestHandler.
* @arg hash The hash used to identify the bucket.
* @arg majorParameter The major parameter of the requests.
*/
constructor(rest: RequestHandler, hash: string, majorParameter: string);
/**
* The identifier of the bucket.
* @readonly
*/
get id(): string;
/**
* Whether the bucket is no longer in use.
* @readonly
*/
get inactive(): boolean;
/**
* Whether the bucket is currently limited.
* @readonly
*/
get limited(): boolean;
/**
* Enqueue a request to be sent.
* @arg request The request to enqueue.
* @arg next Whether to insert the request at the start of the queue.
* @returns Resolves with the returned JSON data.
*/
add<T = unknown>(request: Request, next?: boolean): Promise<T>;
}
/** The options for a {@link RequestHandler}. */
interface RESTOptions {
/** The dispatcher to use for undici. */
dispatcher?: undici_types.Dispatcher;
/** The base URL to use for API requests. */
baseURL?: string;
/** A number of milliseconds to offset the ratelimit timing calculations by. */
ratelimiterOffset?: number;
/** A number of milliseconds before requests are considered timed out. */
requestTimeout?: number;
/** The amount of times it will retry to send the request. */
retryLimit?: number;
}
interface HashData {
value: string;
lastAccess: number;
}
/** The options for a {@link Request}. */
interface RequestOptions {
/** Whether to add the "Authorization" header. */
auth?: boolean;
/** The data to be set for the request body. */
body?: Record<string, any>;
/** The headers to attach to the request. */
headers?: Record<string, string>;
/** The files to attach to the request body. */
files?: FileContent[];
/** An object of query keys and their values. */
query?: Record<string, any>;
/** The reason to display in the audit log. */
reason?: string;
}
/** The contents of a file. */
interface FileContent {
file: any;
name: string;
}
/**
* Represents a class to handle requests.
*/
declare class RequestHandler {
#private;
/** The manager that instansiated this handler. */
manager?: EmojiManager;
/** A map with SequentialBuckets. */
buckets: Map<string, SequentialBucket>;
/** Whether we are currently globally limited. */
globalBlock: boolean;
/** The timestamp of the next reset. */
globalReset: number;
/** A promise that will resolve as soon we are no longer limited. */
globalTimeout?: Promise<void>;
/** A map with bucket hash data. */
hashes: Map<string, HashData>;
/** Options for the RequestHandler. */
options: RESTOptions;
/**
* Represents a class to handle requests.
* @arg options Options for the RequestHandler.
*/
constructor(manager?: EmojiManager, options?: RESTOptions & {
token?: string;
});
/**
* Whether we are currently globally limited.
* @readonly
*/
get limited(): boolean;
/**
* Makes a request to the API.
* @arg method An uppercase HTTP method.
* @arg path The endpoint to make the request to.
* @arg options Data regarding the request.
* @returns Resolves with the returned JSON data.
*/
request<T = unknown>(method: string, path: string, options?: RequestOptions): Promise<T>;
}
/**
* Represents the request.
*/
declare class Request {
#private;
/** The data to be set for the request body. */
data?: FormData | string;
/** The RequestHandler. */
handler: RequestHandler;
/**
* The headers to attach to the request.
* @type {Object}
*/
headers: Record<string, string>;
/** The major parameter of the request. */
majorParameter: string;
/** An uppercase HTTP method. */
method: string;
/** Data regarding the request. */
options: RequestOptions;
/** The endpoint to make the request to. */
path: string;
/** The route to make the request to. */
route: string;
/** The URL to make the request to. */
url: URL;
/**
* Represents the request.
* @arg handler Represents the RequestHandler.
* @arg method An uppercase HTTP method.
* @arg path The endpoint to make the request to.
* @arg options Data regarding the request.
*/
constructor(handler: RequestHandler, method: string, path: string, options: RequestOptions);
/**
* The identifier of the request.
* @readonly
*/
get id(): string;
/**
* Sends the request to Discord.
* @returns The response.
*/
send(): Promise<Response>;
/**
* Attach data to the request.
* @arg body Optional data to attach to the request.
* @arg files Optional files to attach to the request.
*/
setBody(body?: Record<string, any>, files?: FileContent[]): Request;
}
/** The version of this package. */
declare const VERSION = "0.1.2";
/** The API version this package supports. */
declare const API_VERSION = 10;
/** The base API URL to use in requests. */
declare const API_BASE_URL: string;
/** The URL for Discord's CDN. */
declare const CDN_URL = "https://cdn.discordapp.com";
/**
* A user's avatar decoration data.
* @see https://discord.com/developers/docs/resources/user#avatar-decoration-data-object
*/
interface AvatarDecorationData {
/** The avatar decoration hash */
asset: string;
/** The id of the avatar decoration's SKU */
sku_id: string;
}
/**
* A user object.
* @see https://discord.com/developers/docs/resources/user#user-object
*/
interface User {
/** The user's id */
id: string;
/** The user's username, not unique across the platform */
username: string;
/** The user's avatar hash */
avatar: string | null;
/** The user's Discord-tag */
discriminator: string;
/** The public flags on a user's account. */
public_flags: number;
/** The flags on a user's account. */
flags: number;
/** Whether the user belongs to an OAuth2 application */
bot?: boolean;
/** The user's banner hash */
banner?: string | null;
/** The user's banner color encoded as an integer representation of hexadecimal color code */
accent_color?: number | null;
/** The user's display name, if it is set. For bots, this is the application name */
global_name: string | null;
/** The data for the user's avatar decoration */
avatar_decoration_data?: AvatarDecorationData | null;
}
/**
* A partial emoji object, usable with buttons and selects.
* @see https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure
*/
interface PartialEmoji {
/** Emoji id */
id: string;
/** Emoji name */
name: string;
/** Whether this emoji is animated */
animated: boolean;
}
/**
* An emoji object.
* @see https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure
*/
interface Emoji extends PartialEmoji {
user: User;
roles: string[];
require_colons: boolean;
managed: boolean;
available: boolean;
}
/**
* A request object for tracking requests coming from the {@link EmojiManager}.
*/
interface RawRequest {
auth: boolean;
body: Record<string, any> | undefined;
files: FileContent[] | undefined;
latency: number;
url: URL;
method: string;
response: Response;
request: Request;
}
/** The options for the {@link EmojiManager}. */
interface EmojiManagerOptions {
/** TThe bot/client token of the Discord application. */
token: string;
/**
* The application ID for use in the manager.
* If not defined, the manager will fetch the application ID before other requests are made.
*/
applicationId?: string;
/** The options passed to the request handler. */
rest?: RESTOptions;
}
/**
* The events typings for the {@link EmojiManager}.
* @private
*/
interface EmojiManagerEvents {
rawREST: (request: RawRequest) => void;
warn: (warning: string) => void;
debug: (message: string) => void;
error: (err: Error) => void;
}
/** The options for {@link EmojiManager.loadFromFolder} */
interface LoadFromFolderOptions {
/** Whether to recursively get files in the folder */
recursive?: boolean;
}
/**
* A manager for managing an emoji collection.
*/
declare class EmojiManager<Key extends string = string> extends EventEmitter<EmojiManagerEvents> {
#private;
/** The application ID of the manager. */
applicationId?: string;
/** The request handler for the manager. */
readonly requestHandler: RequestHandler;
/** Emojis matched by their key. */
readonly emojis: Map<Key, Emoji>;
/** @param opts The options for the manager */
constructor(opts: EmojiManagerOptions);
/**
* Get an emoji object
* @param key The emoji key to get
* @returns The emoji object
*/
get(key: Key): Emoji | null;
/**
* Get a partial emoji object for use in buttons/selects.
* @param key The emoji key to get
* @returns The partial emoji object
*/
getPartial(key: Key): PartialEmoji | null;
/**
* Get an emoji as a formatted markdown element
* @param key The emoji key to get
* @returns The formatted markdown representation of the emoji
*/
getMarkdown(key: Key): string | null;
/**
* Load emojis into the manager. The values can either be a data image uri (starting with `data:`), URLs (starting with `http(s):`), or file paths.
* @param emojis The emojis to load into the manager
*/
load(emojis: Record<string, string>): void;
/**
* Load image files from a folder.
* @param folderPath The folder to load emojis from
* @param options Options for the function
*/
loadFromFolder(folderPath: string, options?: LoadFromFolderOptions): Promise<void>;
/**
* Syncs the local emojis to the application.
*/
sync(): Promise<void>;
/**
* Load an array of emojis that were previously fetched from the Discord API into the manager.
* @param emojis The emojis from the Discord API to load
*/
loadFromDiscord(emojis: Emoji[]): void;
}
/**
* Get the paths of files in a folder
* @param folderPath The folder to get files from
* @param recursive Whether to get files recursively
* @returns The paths of the inside the folder
*/
declare function getFiles(folderPath: string, recursive?: boolean): Promise<string[]>;
/**
* Calculates the timestamp in milliseconds associated with a Discord ID/snowflake
* @param id The ID of a structure
*/
declare function getCreatedAt(id: string): number;
/**
* Gets the number of milliseconds since epoch represented by an ID/snowflake
* @param id The ID of a structure
*/
declare function getDiscordEpoch(id: string): number;
/**
* Converts an emoji to a formatted markdown string
* @param emoji The emoji to convert to a markdown format
* @returns The formatted markdown string
*/
declare function toMarkdown(emoji: Omit<PartialEmoji, 'animated'> & {
animated?: boolean;
}): string;
/**
* Converts data to a data URI
* @param data The data to convert
* @param mimeType The MIME type of the data
* @returns The data URI string
*/
declare function toDataUri(data: Buffer | ArrayBuffer, mimeType: string): string;
/**
* Converts a file extension to a MIME type
* @param extension The file extension to convert
* @returns The corresponding MIME type or null if unsupported
*/
declare function extensionToMimeType(extension: string): string | null;
/** An HTTP error from a request. */
declare class DiscordHTTPError extends Error {
/** The client request of the error. */
readonly req: Request;
/** The response from the server. */
readonly res: Response;
/** The response class from a {@link Server}. */
readonly response: any;
/** The status code from the response. */
readonly code: number;
/** The error stack. */
readonly stack: string;
/**
* @param req A client request
* @param res A response
* @param stack The error stack
*/
constructor(req: Request, res: Response, stack: string);
get headers(): Headers;
get name(): string;
}
/** An Discord error from a request. */
declare class DiscordRESTError extends Error {
/** The client request of the error. */
readonly req: Request;
/** The response from the server. */
readonly res: Response;
/** The response class from a {@link Server}. */
readonly response: any;
/** The error code from the response. */
readonly code: number;
/** The message of the error. */
readonly message: string;
/** The error stack. */
readonly stack: string;
/**
* @param req A client request
* @param res An incoming message from the server
* @param response A response's body
* @param stack The error stack
*/
constructor(req: Request, res: Response, response: any, stack: string);
get name(): string;
private flattenErrors;
}
export { API_BASE_URL, API_VERSION, type AvatarDecorationData, CDN_URL, DiscordHTTPError, DiscordRESTError, type Emoji, EmojiManager, type EmojiManagerOptions, type LoadFromFolderOptions, type PartialEmoji, type RawRequest, type User, VERSION, extensionToMimeType, getCreatedAt, getDiscordEpoch, getFiles, toDataUri, toMarkdown };