mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 16:43:31 +01:00
271 lines
8.7 KiB
TypeScript
271 lines
8.7 KiB
TypeScript
import {
|
|
ALLOWED_EXTENSIONS,
|
|
ALLOWED_SIZES,
|
|
ALLOWED_STICKER_EXTENSIONS,
|
|
DefaultRestOptions,
|
|
ImageExtension,
|
|
ImageSize,
|
|
StickerExtension,
|
|
} from './utils/constants';
|
|
|
|
/**
|
|
* The options used for image URLs
|
|
*/
|
|
export interface BaseImageURLOptions {
|
|
/**
|
|
* The extension to use for the image URL
|
|
* @default 'webp'
|
|
*/
|
|
extension?: ImageExtension;
|
|
/**
|
|
* The size specified in the image URL
|
|
*/
|
|
size?: ImageSize;
|
|
}
|
|
|
|
/**
|
|
* The options used for image URLs with animated content
|
|
*/
|
|
export 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
|
|
*/
|
|
export interface MakeURLOptions {
|
|
/**
|
|
* The extension to use for the image URL
|
|
* @default 'webp'
|
|
*/
|
|
extension?: string | undefined;
|
|
/**
|
|
* The size specified in the image URL
|
|
*/
|
|
size?: ImageSize;
|
|
/**
|
|
* The allowed extensions that can be used
|
|
*/
|
|
allowedExtensions?: ReadonlyArray<string>;
|
|
}
|
|
|
|
/**
|
|
* The CDN link builder
|
|
*/
|
|
export class CDN {
|
|
public constructor(private readonly base: string = DefaultRestOptions.cdn) {}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string {
|
|
return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string {
|
|
return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* Generates the default avatar URL for a discriminator.
|
|
* @param discriminator The discriminator modulo 5
|
|
*/
|
|
public defaultAvatar(discriminator: number): string {
|
|
return this.makeURL(`/embed/avatars/${discriminator}`, { extension: 'png' });
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* Generates an emoji's URL for an emoji.
|
|
* @param emojiId The emoji id
|
|
* @param extension The extension of the emoji
|
|
*/
|
|
public emoji(emojiId: string, extension?: ImageExtension): string {
|
|
return this.makeURL(`/emojis/${emojiId}`, { extension });
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public guildMemberAvatar(
|
|
guildId: string,
|
|
userId: string,
|
|
avatarHash: string,
|
|
options?: Readonly<ImageURLOptions>,
|
|
): string {
|
|
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string {
|
|
return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/splashes/${guildId}/${splashHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* Generates a sticker URL.
|
|
* @param stickerId The sticker id
|
|
* @param extension The extension of the sticker
|
|
*/
|
|
public sticker(stickerId: string, extension?: StickerExtension): string {
|
|
return this.makeURL(`/stickers/${stickerId}`, {
|
|
allowedExtensions: ALLOWED_STICKER_EXTENSIONS,
|
|
extension: extension ?? 'png', // Stickers cannot have a `.webp` extension, so we default to a `.png`
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generates a sticker pack banner URL.
|
|
* @param bannerId The banner id
|
|
* @param options Optional options for the banner
|
|
*/
|
|
public stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
|
return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public guildScheduledEventCover(
|
|
scheduledEventId: string,
|
|
coverHash: string,
|
|
options?: Readonly<BaseImageURLOptions>,
|
|
): string {
|
|
return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);
|
|
}
|
|
|
|
/**
|
|
* 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(
|
|
route: string,
|
|
hash: string,
|
|
{ forceStatic = false, ...options }: Readonly<ImageURLOptions> = {},
|
|
): string {
|
|
return this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, extension: 'gif' } : options);
|
|
}
|
|
|
|
/**
|
|
* Constructs the URL for the resource
|
|
* @param route The base cdn route
|
|
* @param options The extension/size options for the link
|
|
*/
|
|
private makeURL(
|
|
route: string,
|
|
{ allowedExtensions = ALLOWED_EXTENSIONS, extension = 'webp', size }: Readonly<MakeURLOptions> = {},
|
|
): string {
|
|
extension = String(extension).toLowerCase();
|
|
|
|
if (!allowedExtensions.includes(extension)) {
|
|
throw new RangeError(`Invalid extension provided: ${extension}\nMust be one of: ${allowedExtensions.join(', ')}`);
|
|
}
|
|
|
|
if (size && !ALLOWED_SIZES.includes(size)) {
|
|
throw new RangeError(`Invalid size provided: ${size}\nMust 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();
|
|
}
|
|
}
|