@discordjs/structures
Version:
Wrapper around Discord's structures
1,063 lines (1,025 loc) • 66 kB
TypeScript
import { ChannelFlags, PermissionFlagsBits, GuildChannelType, ChannelType, ThreadChannelType, GuildTextChannelType, TextChannelType, APIChannel, APIPartialChannel, APIGuildForumTag, APIOverwrite, APIThreadMetadata, APINewsChannel, APIAnnouncementThreadChannel, APIGuildCategoryChannel, APIDMChannel, APIGuildForumChannel, APIGroupDMChannel, APIGuildMediaChannel, APIPrivateThreadChannel, APIPublicThreadChannel, APIGuildStageVoiceChannel, APITextChannel, APIGuildVoiceChannel, APIInvite, APIExtendedInvite, APIAvatarDecorationData, APIUser, APIConnection } from 'discord-api-types/v10';
type ReplaceOmittedWithUnknown<Omitted extends keyof Data | '', Data> = {
[Key in keyof Data]: Key extends Omitted ? unknown : Data[Key];
};
type CollapseUnion<Type> = Type extends infer Union ? {
[Key in keyof Union]: Union[Key];
} : never;
type OptionalPropertyNames<Type> = {
[Key in keyof Type]-?: {} extends {
[Prop in Key]: Type[Key];
} ? Key : never;
}[keyof Type];
type MergePrototype<Class1, Class2> = Pick<Class1, Exclude<keyof Class1, keyof Class2>> & Pick<Class2, Exclude<keyof Class2, OptionalPropertyNames<Class2>>> & Pick<Class2, Exclude<OptionalPropertyNames<Class2>, keyof Class1>> & {
[Prop in OptionalPropertyNames<Class2> & keyof Class1]: Class1[Prop] | Exclude<Class2[Prop], undefined>;
};
type MergePrototypes<ClassArray extends readonly unknown[]> = ClassArray extends [infer Class1] ? Class1 : ClassArray extends [infer Class1, ...infer Rest] ? MergePrototype<Class1, MergePrototypes<Rest>> : never;
interface RecursiveReadonlyArray<ItemType> extends ReadonlyArray<ItemType | RecursiveReadonlyArray<ItemType>> {
}
type EnumLike<Enum, Value> = Record<keyof Enum, Value>;
type If<Check, Value, True, False = never> = Check extends Value ? (Value extends Check ? True : False) : False;
type NonAbstract<Type extends abstract new (...args: any) => any> = Type extends abstract new (...args: infer Args) => infer Instance ? Pick<Type, keyof Type> & (new (...args: Args) => Instance) : never;
type Partialize<Type, Omitted extends keyof Type | ''> = Omit<Type, Omitted> & Partial<Pick<Type, Exclude<Omitted, ''>>>;
/**
* Data that can be resolved to give a bit field. This can be:
* A bit number (this can be a number literal or a value taken from {@link (BitField:class).Flags})
* A string bit number
* An instance of BitField
* An Array of BitFieldResolvable
*/
type BitFieldResolvable<Flags extends string> = Flags | Readonly<BitField<Flags>> | RecursiveReadonlyArray<Flags | Readonly<BitField<Flags>> | bigint | number | `${bigint}`> | bigint | number | `${bigint}`;
/**
* Data structure that makes it easy to interact with a bit field.
*/
declare abstract class BitField<Flags extends string> {
/**
* Numeric bit field flags.
*
* @remarks Defined in extension classes
*/
static readonly Flags: EnumLike<unknown, bigint | number>;
static readonly DefaultBit: bigint;
/**
* Bitfield of the packed bits
*/
bitField: bigint;
['constructor']: NonAbstract<typeof BitField<Flags>>;
/**
* @param bits - Bit(s) to read from
*/
constructor(bits?: BitFieldResolvable<Flags>);
/**
* Checks whether the bit field has a bit, or any of multiple bits.
*
* @param bit - Bit(s) to check for
* @returns Whether the bit field has the bit(s)
*/
any(bit: BitFieldResolvable<Flags>): boolean;
/**
* Checks if this bit field equals another
*
* @param bit - Bit(s) to check for
* @returns Whether this bit field equals the other
*/
equals(bit: BitFieldResolvable<Flags>): boolean;
/**
* Checks whether the bit field has a bit, or multiple bits.
*
* @param bit - Bit(s) to check for
* @returns Whether the bit field has the bit(s)
*/
has(bit: BitFieldResolvable<Flags>, ..._hasParams: unknown[]): boolean;
/**
* Gets all given bits that are missing from the bit field.
*
* @param bits - Bit(s) to check for
* @param hasParams - Additional parameters for the has method, if any
* @returns A bit field containing the missing bits
*/
missing(bits: BitFieldResolvable<Flags>, ...hasParams: readonly unknown[]): Flags[];
/**
* Freezes these bits, making them immutable.
*
* @returns This bit field but frozen
*/
freeze(): Readonly<this>;
/**
* Adds bits to these ones.
*
* @param bits - Bits to add
* @returns These bits or new BitField if the instance is frozen.
*/
add(...bits: BitFieldResolvable<Flags>[]): BitField<Flags>;
/**
* Removes bits from these.
*
* @param bits - Bits to remove
* @returns These bits or new BitField if the instance is frozen.
*/
remove(...bits: BitFieldResolvable<Flags>[]): BitField<Flags>;
/**
* Gets an object mapping field names to a boolean indicating whether the bit is available.
*
* @param hasParams - Additional parameters for the has method, if any
* @returns An object mapping field names to a boolean indicating whether the bit is available
*/
serialize(...hasParams: readonly unknown[]): Partial<Record<keyof Flags, boolean>>;
/**
* Gets an Array of bit field names based on the bits available.
*
* @param hasParams - Additional parameters for the has method, if any
* @returns An Array of bit field names
*/
toArray(...hasParams: readonly unknown[]): Flags[];
toJSON(asNumber?: boolean): string | number;
valueOf(): bigint;
[Symbol.iterator](...hasParams: unknown[]): Generator<Flags, void, unknown>;
/**
* Resolves bit fields to their numeric form.
*
* @param bit - bit(s) to resolve
* @returns the numeric value of the bit fields
*/
static resolve<Flags extends string = string>(bit: BitFieldResolvable<Flags>): bigint;
}
/**
* Data structure that makes it easy to interact with a {@link (Channel:class).flags} bitfield.
*/
declare class ChannelFlagsBitField extends BitField<keyof ChannelFlags> {
/**
* Numeric guild channel flags.
*/
static readonly Flags: typeof ChannelFlags;
toJSON(): string | number;
}
/**
* Data structure that makes it easy to interact with a permission bit field. All {@link GuildMember}s have a set of
* permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrite}s for the member
* that override their default permissions.
*/
declare class PermissionsBitField extends BitField<keyof typeof PermissionFlagsBits> {
/**
* Numeric permission flags.
*
* @see {@link https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags}
*/
static Flags: {
readonly CreateInstantInvite: bigint;
readonly KickMembers: bigint;
readonly BanMembers: bigint;
readonly Administrator: bigint;
readonly ManageChannels: bigint;
readonly ManageGuild: bigint;
readonly AddReactions: bigint;
readonly ViewAuditLog: bigint;
readonly PrioritySpeaker: bigint;
readonly Stream: bigint;
readonly ViewChannel: bigint;
readonly SendMessages: bigint;
readonly SendTTSMessages: bigint;
readonly ManageMessages: bigint;
readonly EmbedLinks: bigint;
readonly AttachFiles: bigint;
readonly ReadMessageHistory: bigint;
readonly MentionEveryone: bigint;
readonly UseExternalEmojis: bigint;
readonly ViewGuildInsights: bigint;
readonly Connect: bigint;
readonly Speak: bigint;
readonly MuteMembers: bigint;
readonly DeafenMembers: bigint;
readonly MoveMembers: bigint;
readonly UseVAD: bigint;
readonly ChangeNickname: bigint;
readonly ManageNicknames: bigint;
readonly ManageRoles: bigint;
readonly ManageWebhooks: bigint;
readonly ManageEmojisAndStickers: bigint;
readonly ManageGuildExpressions: bigint;
readonly UseApplicationCommands: bigint;
readonly RequestToSpeak: bigint;
readonly ManageEvents: bigint;
readonly ManageThreads: bigint;
readonly CreatePublicThreads: bigint;
readonly CreatePrivateThreads: bigint;
readonly UseExternalStickers: bigint;
readonly SendMessagesInThreads: bigint;
readonly UseEmbeddedActivities: bigint;
readonly ModerateMembers: bigint;
readonly ViewCreatorMonetizationAnalytics: bigint;
readonly UseSoundboard: bigint;
readonly CreateGuildExpressions: bigint;
readonly CreateEvents: bigint;
readonly UseExternalSounds: bigint;
readonly SendVoiceMessages: bigint;
readonly SendPolls: bigint;
readonly UseExternalApps: bigint;
};
/**
* Bit field representing every permission combined
*/
static readonly All: bigint;
/**
* Bit field representing the default permissions for users
*/
static readonly Default = 104324673n;
/**
* Bit field representing the permissions required for moderators of stage channels
*/
static readonly StageModerator: bigint;
/**
* Gets all given bits that are missing from the bit field.
*
* @param bits - Bit(s) to check for
* @param checkAdmin - Whether to allow the administrator permission to override
* @returns A bit field containing the missing permissions
*/
missing(bits: BitFieldResolvable<keyof typeof PermissionFlagsBits>, checkAdmin?: boolean): ("CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTTSMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "ViewGuildInsights" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVAD" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageGuildExpressions" | "UseApplicationCommands" | "RequestToSpeak" | "ManageEvents" | "ManageThreads" | "CreatePublicThreads" | "CreatePrivateThreads" | "UseExternalStickers" | "SendMessagesInThreads" | "UseEmbeddedActivities" | "ModerateMembers" | "ViewCreatorMonetizationAnalytics" | "UseSoundboard" | "CreateGuildExpressions" | "CreateEvents" | "UseExternalSounds" | "SendVoiceMessages" | "SendPolls" | "UseExternalApps")[];
/**
* Checks whether the bit field has a permission, or any of multiple permissions.
*
* @param permission - Permission(s) to check for
* @param checkAdmin - Whether to allow the administrator permission to override
* @returns Whether the bit field has the permission(s)
*/
any(permission: BitFieldResolvable<keyof typeof PermissionFlagsBits>, checkAdmin?: boolean): boolean;
/**
* Checks whether the bit field has a permission, or multiple permissions.
*
* @param permission - Permission(s) to check for
* @param checkAdmin - Whether to allow the administrator permission to override
* @returns Whether the bit field has the permission(s)
*/
has(permission: BitFieldResolvable<keyof typeof PermissionFlagsBits>, checkAdmin?: boolean): boolean;
/**
* Gets an Array of bitfield names based on the permissions available.
*
* @returns An Array of permission names
*/
toArray(): ("CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTTSMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "ViewGuildInsights" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVAD" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageGuildExpressions" | "UseApplicationCommands" | "RequestToSpeak" | "ManageEvents" | "ManageThreads" | "CreatePublicThreads" | "CreatePrivateThreads" | "UseExternalStickers" | "SendMessagesInThreads" | "UseEmbeddedActivities" | "ModerateMembers" | "ViewCreatorMonetizationAnalytics" | "UseSoundboard" | "CreateGuildExpressions" | "CreateEvents" | "UseExternalSounds" | "SendVoiceMessages" | "SendPolls" | "UseExternalApps")[];
}
declare const kData: unique symbol;
declare const kClone: unique symbol;
declare const kPatch: unique symbol;
declare const kExpiresTimestamp: unique symbol;
declare const kCreatedTimestamp: unique symbol;
declare const kArchiveTimestamp: unique symbol;
declare const kAllow: unique symbol;
declare const kDeny: unique symbol;
declare const kLastPinTimestamp: unique symbol;
declare const kMixinConstruct: unique symbol;
declare const kMixinToJSON: unique symbol;
declare const DataTemplatePropertyName = "DataTemplate";
declare const OptimizeDataPropertyName = "optimizeData";
/**
* Represents a data model from the Discord API
*
* @privateRemarks
* Explanation of the type complexity surround Structure:
*
* There are two layers of Omitted generics, one here, which allows omitting things at the library level so we do not accidentally
* access them, in addition to whatever the user does at the layer above.
*
* The second layer, in the exported structure is effectively a type cast that allows the getters types to match whatever data template is used
*
* In order to safely set and access this data, the constructor and patch take data as "partial" and forcibly assigns it to kData. To accommodate this,
* kData stores properties as `unknown` when it is omitted, which allows accessing the property in getters even when it may not actually be present.
* This is the most technically correct way of representing the value, especially since there is no way to guarantee runtime matches the "type cast."
*/
declare abstract class Structure<DataType extends {}, Omitted extends keyof DataType | '' = ''> {
/**
* A construct function used when mixing to allow mixins to set optimized property defaults
*
* @internal
* @remarks This should only be used to set defaults, setting optimized values should be done
* in the mixins `optimizeData` method, which will be called automatically.
* @param data - The full API data received by the Structure
*/
protected [kMixinConstruct]?(data: Partial<DataType>): void;
/**
* A function used when mixing to allow mixins to add properties to the result of toJSON
*
* @internal
* @remarks This should only be used to add properties that the mixin optimizes, if the raw
* JSON data is unchanged the property will already be returned.
* @param data - The result of the base class toJSON Structure before it gets returned
*/
protected [kMixinToJSON]?(data: Partial<DataType>): void;
/**
* The template used for removing data from the raw data stored for each Structure.
*
* @remarks This template should be overridden in all subclasses to provide more accurate type information.
* The template in the base {@link Structure} class will have no effect on most subclasses for this reason.
*/
protected static readonly DataTemplate: Record<string, unknown>;
/**
* @returns A cloned version of the data template, ready to create a new data object.
*/
private getDataTemplate;
/**
* The raw data from the API for this structure
*
* @internal
*/
protected [kData]: Readonly<ReplaceOmittedWithUnknown<Omitted, DataType>>;
/**
* Creates a new structure to represent API data
*
* @param data - the data from the API that this structure will represent
* @remarks To be made public in subclasses
* @internal
*/
constructor(data: Readonly<Partial<DataType>>, ..._rest: unknown[]);
/**
* Patches the raw data of this object in place
*
* @param data - the updated data from the API to patch with
* @remarks To be made public in subclasses
* @returns this
* @internal
*/
protected [kPatch](data: Readonly<Partial<DataType>>): this;
/**
* Creates a clone of this structure
*
* @returns a clone of this
* @internal
*/
protected [kClone](patchPayload?: Readonly<Partial<DataType>>): typeof this;
/**
* Function called to ensure stored raw data is in optimized formats, used in tandem with a data template
*
* @example created_timestamp is an ISO string, this can be stored in optimized form as a number
* @param _data - the raw data received from the API to optimize
* @remarks Implementation to be done in subclasses and mixins where needed.
* For typescript users, mixins must use the closest ancestors access modifier.
* @remarks Automatically called in Structure[kPatch] but must be called manually in the constructor
* of any class implementing this method.
* @remarks Additionally, when implementing, ensure to call `super._optimizeData` if any class in the super chain aside
* from Structure contains an implementation.
* Note: mixins do not need to call super ever as the process of mixing walks the prototype chain.
* @virtual
* @internal
*/
protected optimizeData(_data: Partial<DataType>): void;
/**
* Transforms this object to its JSON format with raw API data (or close to it),
* automatically called by `JSON.stringify()` when this structure is stringified
*
* @remarks
* The type of this data is determined by omissions at runtime and is only guaranteed for default omissions
* @privateRemarks
* When omitting properties at the library level, this must be overridden to re-add those properties
*/
toJSON(): DataType;
}
interface ChannelPermissionMixin<Type extends Exclude<GuildChannelType, ChannelType.GuildDirectory | ThreadChannelType> = Exclude<GuildChannelType, ChannelType.GuildDirectory | ThreadChannelType>> extends Channel<Type> {
}
/**
* @remarks has an array of sub-structures {@link PermissionOverwrite} that extending mixins should add to their DataTemplate and _optimizeData
*/
declare class ChannelPermissionMixin<Type extends Exclude<GuildChannelType, ChannelType.GuildDirectory | ThreadChannelType> = Exclude<GuildChannelType, ChannelType.GuildDirectory | ThreadChannelType>> {
/**
* The sorting position of the channel
*/
get position(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["position"];
/**
* Indicates whether this channel can have permission overwrites
*/
isPermissionCapable(): this is ChannelPermissionMixin & this;
}
interface ChannelWebhookMixin<Type extends ChannelType.GuildForum | ChannelType.GuildMedia | Exclude<GuildTextChannelType, ThreadChannelType> = ChannelType.GuildForum | ChannelType.GuildMedia | Exclude<GuildTextChannelType, ThreadChannelType>> extends Channel<Type> {
}
declare class ChannelWebhookMixin<Type extends ChannelType.GuildForum | ChannelType.GuildMedia | Exclude<GuildTextChannelType, ThreadChannelType> = ChannelType.GuildForum | ChannelType.GuildMedia | Exclude<GuildTextChannelType, ThreadChannelType>> {
/**
* Indicates whether this channel can have webhooks
*/
isWebhookCapable(): this is ChannelWebhookMixin & this;
}
interface DMChannelMixin<Type extends ChannelType.DM | ChannelType.GroupDM = ChannelType.DM | ChannelType.GroupDM> extends Channel<Type> {
}
/**
* @remarks has recipients, an array of sub-structures {@link User} that extending mixins should add to their DataTemplate and _optimizeData
*/
declare class DMChannelMixin<Type extends ChannelType.DM | ChannelType.GroupDM = ChannelType.DM | ChannelType.GroupDM> {
/**
* The URL to this channel.
*/
get url(): `https://discord.com/channels/@me/${ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["id"]}`;
/**
* Indicates whether this channel is a DM or DM Group
*/
isDMBased(): this is DMChannelMixin & this;
}
interface GuildChannelMixin<Type extends GuildChannelType = GuildChannelType> extends Channel<Type> {
}
declare class GuildChannelMixin<Type extends GuildChannelType = GuildChannelType> {
/**
* The flags that are applied to the channel.
*
* @privateRemarks The type of `flags` can be narrowed in Guild Channels and DMChannel to ChannelFlags, and in GroupDM channel
* to null, respecting Omit behaviors
*/
get flags(): ChannelFlagsBitField | null;
/**
* THe id of the guild this channel is in.
*/
get guildId(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["guild_id"]>;
/**
* The URL to this channel.
*/
get url(): `https://discord.com/channels/${NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["guild_id"]>}/${ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["id"]}`;
/**
* Indicates whether this channel is in a guild
*/
isGuildBased(): this is GuildChannelMixin & this;
}
interface TextChannelMixin<Type extends TextChannelType = TextChannelType> extends Channel<Type> {
}
declare class TextChannelMixin<Type extends TextChannelType = TextChannelType> {
/**
* The id of the last message sent in this channel.
*/
get lastMessageId(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["last_message_id"] | undefined;
/**
* Indicates whether this channel can contain messages
*/
isTextBased(): this is TextChannelMixin & this;
}
interface ThreadChannelMixin<Type extends ThreadChannelType = ThreadChannelType> extends Channel<Type> {
}
/**
* @remarks has a sub-structure {@link ThreadMetadata} that extending mixins should add to their DataTemplate and _optimizeData
*/
declare class ThreadChannelMixin<Type extends ThreadChannelType = ThreadChannelType> {
/**
* The approximate count of users in a thread, stops counting at 50
*/
get memberCount(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["member_count"] | undefined;
/**
* The number of messages (not including the initial message or deleted messages) in a thread.
*/
get messageCount(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["message_count"] | undefined;
/**
* The number of messages ever sent in a thread, it's similar to message_count on message creation,
* but will not decrement the number when a message is deleted.
*/
get totalMessageSent(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["total_message_sent"] | undefined;
/**
* Indicates whether this channel is a thread channel
*/
isThread(): this is ThreadChannelMixin & this;
}
interface ThreadOnlyChannelMixin<Type extends ChannelType.GuildForum | ChannelType.GuildMedia = ChannelType.GuildForum | ChannelType.GuildMedia> extends Channel<Type> {
}
/**
* @remarks has an array of sub-structures {@link ForumTag} that extending mixins should add to their DataTemplate and _optimizeData
*/
declare class ThreadOnlyChannelMixin<Type extends ChannelType.GuildForum | ChannelType.GuildMedia = ChannelType.GuildForum | ChannelType.GuildMedia> {
/**
* The emoji to show in the add reaction button on a thread in this channel.
*/
get defaultReactionEmoji(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["default_reaction_emoji"];
/**
* The default sort order type used to order posts in this channel.
*
* @defaultValue `null` – indicates a preferred sort order hasn't been set.
*/
get defaultSortOrder(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["default_sort_order"]>;
/**
* Indicates whether this channel only allows thread creation
*/
isThreadOnly(): this is ThreadOnlyChannelMixin & this;
}
interface VoiceChannelMixin<Type extends ChannelType.GuildStageVoice | ChannelType.GuildVoice = ChannelType.GuildStageVoice | ChannelType.GuildVoice> extends Channel<Type> {
}
declare class VoiceChannelMixin<Type extends ChannelType.GuildStageVoice | ChannelType.GuildVoice = ChannelType.GuildStageVoice | ChannelType.GuildVoice> extends TextChannelMixin<Type> {
/**
* The bitrate (in bits) of the voice channel.
*/
get bitrate(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["bitrate"]>;
/**
* The voice region id for this channel, automatic when set to null.
*/
get rtcRegion(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["rtc_region"]>;
/**
* The camera video quality mode of the voice channel, {@link discord-api-types/v10#(VideoQualityMode:enum) | Auto} when not present.
*/
get videoQualityMode(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["video_quality_mode"]>;
/**
* The user limit of the voice channel.
*/
get userLimit(): NonNullable<ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["user_limit"]>;
/**
* Indicates whether this channel has voice connection capabilities
*/
isVoiceBased(): this is VoiceChannelMixin & this;
}
type PartialChannel = Channel<ChannelType, Exclude<keyof APIChannel, keyof APIPartialChannel>>;
/**
* The data stored by a {@link Channel} structure based on its {@link (Channel:class)."type"} property.
*/
type ChannelDataType<Type extends ChannelType | 'unknown'> = Type extends ChannelType ? Extract<APIChannel, {
type: Type;
}> : APIPartialChannel;
/**
* Represents any channel on Discord.
*
* @typeParam Type - Specify the type of the channel being constructed for more accurate data types
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
* @remarks Although this class _can_ be instantiated directly for any channel type,
* it's intended to be subclassed with the appropriate mixins for each channel type.
*/
declare class Channel<Type extends ChannelType | 'unknown' = ChannelType, Omitted extends keyof ChannelDataType<Type> | '' = ''> extends Structure<ChannelDataType<Type>, Omitted> {
/**
* The template used for removing data from the raw data stored for each Channel.
*
* @remarks This template is only guaranteed to apply to channels constructed directly via `new Channel()`.
* Use the appropriate subclass template to remove data from that channel type.
*/
static readonly DataTemplate: Partial<APIChannel>;
/**
* @param data - The raw data received from the API for the channel
*/
constructor(data: Partialize<ChannelDataType<Type>, Omitted>);
/**
* {@inheritDoc Structure.[kPatch]}
*
* @internal
*/
[kPatch](data: Partial<ChannelDataType<Type>>): this;
/**
* The id of the channel
*/
get id(): ReplaceOmittedWithUnknown<Omitted, ChannelDataType<Type>>["id"];
/**
* The type of the channel
*/
get type(): Type extends "unknown" ? number : Type;
/**
* The name of the channel, null for DMs
*
* @privateRemarks The type of `name` can be narrowed in Guild Channels and DM channels to string and null respectively,
* respecting Omit behaviors
*/
get name(): ReplaceOmittedWithUnknown<Omitted, ChannelDataType<Type>>["name"] | undefined;
/**
* The flags that are applied to the channel.
*
* @privateRemarks The type of `flags` can be narrowed in Guild Channels and DMChannel to ChannelFlags, and in GroupDM channel
* to null, respecting Omit behaviors
*/
get flags(): ChannelFlagsBitField | null;
/**
* The timestamp the channel was created at
*/
get createdTimestamp(): number | null;
/**
* The time the channel was created at
*/
get createdAt(): Date | null;
/**
* Indicates whether this channel is a thread channel
*
* @privateRemarks Overridden to `true` on `ThreadChannelMixin`
*/
isThread(): this is ThreadChannelMixin & this;
/**
* Indicates whether this channel can contain messages
*
* @privateRemarks Overridden to `true` on `TextChannelMixin`
*/
isTextBased(): this is TextChannelMixin & this;
/**
* Indicates whether this channel is in a guild
*
* @privateRemarks Overridden to `true` on `GuildChannelMixin`
*/
isGuildBased(): this is GuildChannelMixin & this;
/**
* Indicates whether this channel is a DM or DM Group
*
* @privateRemarks Overridden to `true` on `DMChannelMixin`
*/
isDMBased(): this is DMChannelMixin & this;
/**
* Indicates whether this channel has voice connection capabilities
*
* @privateRemarks Overridden to `true` on `VoiceChannelMixin`
*/
isVoiceBased(): this is VoiceChannelMixin & this;
/**
* Indicates whether this channel only allows thread creation
*
* @privateRemarks Overridden to `true` on `ThreadOnlyChannelMixin`
*/
isThreadOnly(): this is ThreadOnlyChannelMixin & this;
/**
* Indicates whether this channel can have permission overwrites
*
* @privateRemarks Overridden to `true` on `ChannelPermissionsMixin`
*/
isPermissionCapable(): this is ChannelPermissionMixin & this;
/**
* Indicates whether this channel can have webhooks
*
* @privateRemarks Overridden to `true` on `ChannelWebhooksMixin`
*/
isWebhookCapable(): this is ChannelWebhookMixin & this;
}
interface AppliedTagsMixin extends Channel<ChannelType.PublicThread> {
}
declare class AppliedTagsMixin {
/**
* The ids of the set of tags that have been applied to a thread in a {@link (ForumChannel:class)} or a {@link (MediaChannel:class)}.
*/
get appliedTags(): readonly string[] | null;
}
interface ChannelOwnerMixin<Type extends ChannelType.GroupDM | ThreadChannelType> extends Channel<Type> {
}
declare class ChannelOwnerMixin<Type extends ChannelType.GroupDM | ThreadChannelType> {
/**
* The id of the creator of the group DM or thread
*/
get ownerId(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["owner_id"] | undefined;
}
declare class ChannelParentMixin<Type extends Exclude<GuildChannelType, ChannelType.GuildCategory | ChannelType.GuildDirectory>> extends GuildChannelMixin<Type> {
/**
* The id of the parent category for a channel (each parent category can contain up to 50 channels) or id of the parent channel for a thread
*/
get parentId(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["parent_id"] | undefined;
/**
* Whether the channel is nsfw
*/
get nsfw(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["nsfw"] | undefined;
}
interface ChannelPinMixin<Type extends ChannelType.DM | ChannelType.GuildAnnouncement | ChannelType.GuildText | ThreadChannelType> extends Channel<Type> {
}
declare class ChannelPinMixin<Type extends ChannelType.DM | ChannelType.GuildAnnouncement | ChannelType.GuildText | ThreadChannelType> {
/**
* The timestamp of when the last pin in the channel happened
*/
protected [kLastPinTimestamp]: number | null;
/**
* The template used for removing data from the raw data stored for each Channel.
*/
static readonly DataTemplate: Partial<ChannelDataType<ChannelType.DM | ChannelType.GuildAnnouncement | ChannelType.GuildText | ThreadChannelType>>;
[kMixinConstruct](): void;
/**
* {@inheritDoc Structure.optimizeData}
*/
protected optimizeData(data: Partial<ChannelDataType<Type>>): void;
/**
* The timestamp of when the last pin in the channel happened.
*/
get lastPinTimestamp(): number | null;
/**
* The Date of when the last pin in the channel happened
*/
get lastPinAt(): Date | null;
/**
* Adds data from optimized properties omitted from [kData].
*
* @param data - the result of {@link (Structure:class).toJSON}
*/
protected [kMixinToJSON](data: Partial<ChannelDataType<Type>>): void;
}
declare class ChannelSlowmodeMixin<Type extends GuildTextChannelType> extends TextChannelMixin<Type> {
/**
* The rate limit per user (slowmode) of this channel.
*/
get rateLimitPerUser(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["rate_limit_per_user"] | undefined;
}
interface ChannelTopicMixin<Type extends ChannelType.GuildAnnouncement | ChannelType.GuildForum | ChannelType.GuildMedia | ChannelType.GuildText> extends Channel<Type> {
}
declare class ChannelTopicMixin<Type extends ChannelType.GuildAnnouncement | ChannelType.GuildForum | ChannelType.GuildMedia | ChannelType.GuildText> extends ChannelWebhookMixin<Type> {
/**
* The topic of this channel.
*/
get topic(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["topic"] | undefined;
/**
* The duration after which new threads get archived by default on this channel.
*/
get defaultAutoArchiveDuration(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["default_auto_archive_duration"] | undefined;
/**
* The default value for rate limit per user (slowmode) on new threads in this channel.
*/
get defaultThreadRateLimitPerUser(): ReplaceOmittedWithUnknown<"", ChannelDataType<Type>>["default_thread_rate_limit_per_user"] | undefined;
}
interface GroupDMMixin extends Channel<ChannelType.GroupDM> {
}
declare class GroupDMMixin {
/**
* The icon hash of the group DM.
*/
get icon(): string | null | undefined;
/**
* Whether the channel is managed by an application via the `gdm.join` OAuth2 scope.
*/
get managed(): boolean | undefined;
/**
* The application id of the group DM creator if it is bot-created.
*/
get applicationId(): string | undefined;
}
/**
* Represents metadata of a thread channel on Discord.
*
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
*/
declare class ForumTag<Omitted extends keyof APIGuildForumTag | '' = ''> extends Structure<APIGuildForumTag, Omitted> {
constructor(data: Partialize<APIGuildForumTag, Omitted>);
/**
* The id of the tag.
*/
get id(): "id" extends infer T ? T extends "id" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never;
/**
* The name of the tag.
*/
get name(): "name" extends infer T ? T extends "name" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never;
/**
* Whether this tag can only be added to or removed from threads by a member with the {@link discord-api-types/v10#(PermissionFlagsBits:variable) | ManageThreads} permission.
*/
get moderated(): "moderated" extends infer T ? T extends "moderated" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never;
/**
* The id of a guild's custom emoji.
*/
get emojiId(): "emoji_id" extends infer T ? T extends "emoji_id" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never;
/**
* The unicode character of the emoji.
*/
get emojiName(): "emoji_name" extends infer T ? T extends "emoji_name" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never;
/**
* The textual representation of this tag's emoji. Either a unicode character or a guild emoji mention.
*/
get emoji(): string | NonNullable<"emoji_name" extends infer T ? T extends "emoji_name" ? T extends Omitted ? unknown : APIGuildForumTag[T] : never : never>;
}
/**
* Represents metadata of a thread channel on Discord.
*
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
*/
declare class PermissionOverwrite<Omitted extends keyof APIOverwrite | '' = 'allow' | 'deny'> extends Structure<APIOverwrite, Omitted> {
protected [kAllow]: bigint | null;
protected [kDeny]: bigint | null;
constructor(data: Partialize<APIOverwrite, Omitted>);
/**
* The template used for removing data from the raw data stored for each ThreadMetadata
*
* @remarks This template has defaults, if you want to remove additional data and keep the defaults,
* use `Object.defineProperties`. To override the defaults, set this value directly.
*/
static readonly DataTemplate: Partial<APIOverwrite>;
/**
* {@inheritDoc Structure.optimizeData}
*/
protected optimizeData(data: Partial<APIOverwrite>): void;
/**
* The permission bit set allowed by this overwrite.
*/
get allow(): PermissionsBitField | null;
/**
* The permission bit set denied by this overwrite.
*/
get deny(): PermissionsBitField | null;
/**
* The role or user id for this overwrite.
*/
get id(): "id" extends infer T ? T extends "id" ? T extends Omitted ? unknown : APIOverwrite[T] : never : never;
/**
* The type of this overwrite.
*/
get type(): "type" extends infer T ? T extends "type" ? T extends Omitted ? unknown : APIOverwrite[T] : never : never;
/**
* {@inheritDoc Structure.toJSON}
*/
toJSON(): APIOverwrite;
}
/**
* Represents metadata of a thread channel on Discord.
*
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
*/
declare class ThreadMetadata<Omitted extends keyof APIThreadMetadata | '' = 'archive_timestamp' | 'create_timestamp'> extends Structure<APIThreadMetadata, Omitted> {
protected [kArchiveTimestamp]: number | null;
protected [kCreatedTimestamp]: number | null;
constructor(data: Partialize<APIThreadMetadata, Omitted>);
/**
* The template used for removing data from the raw data stored for each ThreadMetadata
*
* @remarks This template has defaults, if you want to remove additional data and keep the defaults,
* use `Object.defineProperties`. To override the defaults, set this value directly.
*/
static readonly DataTemplate: Partial<APIThreadMetadata>;
/**
* {@inheritDoc Structure.optimizeData}
*/
protected optimizeData(data: Partial<APIThreadMetadata>): void;
/**
* Whether the thread is archived.
*/
get archived(): "archived" extends infer T ? T extends "archived" ? T extends Omitted ? unknown : APIThreadMetadata[T] : never : never;
/**
* The timestamp when the thread's archive status was last changed, used for calculating recent activity.
*/
get archivedTimestamp(): number | null;
/**
* The timestamp when the thread was created; only populated for threads created after 2022-01-09.
*/
get createdTimestamp(): number | null;
/**
* The thread will stop showing in the channel list after auto_archive_duration minutes of inactivity,
*/
get autoArchiveDuration(): "auto_archive_duration" extends infer T ? T extends "auto_archive_duration" ? T extends Omitted ? unknown : APIThreadMetadata[T] : never : never;
/**
* Whether non-moderators can add other non-moderators to a thread; only available on private threads.
*/
get invitable(): ("invitable" extends infer T ? T extends "invitable" ? T extends Omitted ? unknown : APIThreadMetadata[T] : never : never) | undefined;
/**
* Whether the thread is locked; when a thread is locked, only users with {@link discord-api-types/v10#(PermissionFlagsBits:variable) | ManageThreads} can unarchive it.
*/
get locked(): "locked" extends infer T ? T extends "locked" ? T extends Omitted ? unknown : APIThreadMetadata[T] : never : never;
/**
* The time the thread was archived at
*/
get archivedAt(): Date | null;
/**
* The time the thread was created at
*/
get createdAt(): Date | null;
/**
* {@inheritDoc Structure.toJSON}
*/
toJSON(): APIThreadMetadata;
}
type Mixinable<ClassType> = new (...args: unknown[]) => ClassType;
type MixinBase<BaseClass extends Structure<{}>> = BaseClass extends Structure<infer DataType, infer Omitted> ? Structure<DataType, Omitted> : never;
/**
* Copies the prototype (getters, setters, and methods) of all mixins to the destination class.
* For type information see {@link MixinTypes}
*
* @param destination - The class to apply the mixins to, must extend the base that the mixins expect it to.
* @param mixins - Classes that contain "pure" prototypes to be copied on top of the destination class prototype
* @remarks All mixins should be "pure" in that they only contain getters, setters, and methods.
* The runtime code will only copy these, and adding properties to the class only results
* in the types of the mixed class being wrong.
* @example
* ```
* // Interface merging on the mixin to give type access to props on the base and kData that are available once copied
* interface TextMixin extends Channel {}
* class TextMixin {
* // Methods / getters
* }
*
* // Interface merging on the mixed class to give it accurate type information within the declaration and when instantiated
* interface TextChannel extends MixinTypes<Channel, [TextMixin]> {}
* class TextChannel extends Channel {}
*
* // Apply for runtime
* Mixin(TextChannel, [TextMixin])
* ```
* @typeParam DestinationClass - The class to be mixed, ensures that the mixins provided can be used with this destination
*/
declare function Mixin<DestinationClass extends typeof Structure<{}>>(destination: DestinationClass, mixins: Mixinable<MixinBase<DestinationClass['prototype']>>[]): void;
/**
* Type utility to provide accurate types for the runtime effects of {@link Mixin}
*
* @typeParam BaseClass - The class that is being directly extended, must match the class that the mixins are expecting
* @typeParam Mixins - The mixins that will be applied to this class via a {@link Mixin} call
*/
type MixinTypes<BaseClass extends Structure<{}>, Mixins extends readonly MixinBase<BaseClass>[]> = CollapseUnion<
BaseClass extends Structure<infer DataType, infer Omitted>
? Mixins[number] extends Structure<DataType, Omitted>
? // prettier-ignore
Structure<DataType, Omitted>[typeof kData] extends
// @ts-expect-error kData is protected
Mixins[number][typeof kData]
? Omit<MergePrototypes<Mixins>, keyof BaseClass | typeof kMixinConstruct>
: never
: never
: never
>;
interface AnnouncementChannel<Omitted extends keyof APINewsChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildAnnouncement>, [
TextChannelMixin<ChannelType.GuildAnnouncement>,
ChannelParentMixin<ChannelType.GuildAnnouncement>,
ChannelPermissionMixin<ChannelType.GuildAnnouncement>,
ChannelPinMixin<ChannelType.GuildAnnouncement>,
ChannelSlowmodeMixin<ChannelType.GuildAnnouncement>,
ChannelTopicMixin<ChannelType.GuildAnnouncement>
]> {
}
/**
* Sample Implementation of a structure for announcement channels, usable by direct end consumers.
*/
declare class AnnouncementChannel<Omitted extends keyof APINewsChannel | '' = ''> extends Channel<ChannelType.GuildAnnouncement, Omitted> {
constructor(data: Partialize<APINewsChannel, Omitted>);
}
interface AnnouncementThreadChannel<Omitted extends keyof APIAnnouncementThreadChannel | '' = ''> extends MixinTypes<Channel<ChannelType.AnnouncementThread>, [
TextChannelMixin<ChannelType.AnnouncementThread>,
ChannelOwnerMixin<ChannelType.AnnouncementThread>,
ChannelParentMixin<ChannelType.AnnouncementThread>,
ChannelPinMixin<ChannelType.AnnouncementThread>,
ChannelSlowmodeMixin<ChannelType.AnnouncementThread>,
GuildChannelMixin<ChannelType.AnnouncementThread>,
ThreadChannelMixin<ChannelType.AnnouncementThread>
]> {
}
/**
* Sample Implementation of a structure for announcement threads, usable by direct end consumers.
*/
declare class AnnouncementThreadChannel<Omitted extends keyof APIAnnouncementThreadChannel | '' = ''> extends Channel<ChannelType.AnnouncementThread, Omitted> {
constructor(data: Partialize<APIAnnouncementThreadChannel, Omitted>);
}
interface CategoryChannel<Omitted extends keyof APIGuildCategoryChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildCategory>, [
ChannelPermissionMixin<ChannelType.GuildCategory>,
GuildChannelMixin<ChannelType.GuildCategory>
]> {
}
/**
* Sample Implementation of a structure for category channels, usable by direct end consumers.
*/
declare class CategoryChannel<Omitted extends keyof APIGuildCategoryChannel | '' = ''> extends Channel<ChannelType.GuildCategory, Omitted> {
constructor(data: Partialize<APIGuildCategoryChannel, Omitted>);
}
interface DMChannel<Omitted extends keyof APIDMChannel | '' = ''> extends MixinTypes<Channel<ChannelType.DM>, [
DMChannelMixin<ChannelType.DM>,
TextChannelMixin<ChannelType.DM>,
ChannelPinMixin<ChannelType.DM>
]> {
}
/**
* Sample Implementation of a structure for dm channels, usable by direct end consumers.
*/
declare class DMChannel<Omitted extends keyof APIDMChannel | '' = ''> extends Channel<ChannelType.DM, Omitted> {
constructor(data: Partialize<APIDMChannel, Omitted>);
}
interface ForumChannel<Omitted extends keyof APIGuildForumChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildForum>, [
ChannelParentMixin<ChannelType.GuildForum>,
ChannelPermissionMixin<ChannelType.GuildForum>,
ChannelTopicMixin<ChannelType.GuildForum>,
ThreadOnlyChannelMixin<ChannelType.GuildForum>
]> {
}
/**
* Sample Implementation of a structure for forum channels, usable by direct end consumers.
*/
declare class ForumChannel<Omitted extends keyof APIGuildForumChannel | '' = ''> extends Channel<ChannelType.GuildForum, Omitted> {
constructor(data: Partialize<APIGuildForumChannel, Omitted>);
/**
* The default forum layout view used to display posts in this channel.
* Defaults to 0, which indicates a layout view has not been set by a channel admin.
*/
get defaultForumLayout(): "default_forum_layout" extends infer T ? T extends "default_forum_layout" ? T extends Omitted ? unknown : APIGuildForumChannel[T] : never : never;
}
interface GroupDMChannel<Omitted extends keyof APIGroupDMChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GroupDM>, [
DMChannelMixin<ChannelType.GroupDM>,
TextChannelMixin<ChannelType.GroupDM>,
ChannelOwnerMixin<ChannelType.GroupDM>,
GroupDMMixin
]> {
}
/**
* Sample Implementation of a structure for group dm channels, usable by direct end consumers.
*/
declare class GroupDMChannel<Omitted extends keyof APIGroupDMChannel | '' = ''> extends Channel<ChannelType.GroupDM, Omitted> {
constructor(data: Partialize<APIGroupDMChannel, Omitted>);
}
interface MediaChannel<Omitted extends keyof APIGuildMediaChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildMedia>, [
ChannelParentMixin<ChannelType.GuildMedia>,
ChannelPermissionMixin<ChannelType.GuildMedia>,
ChannelTopicMixin<ChannelType.GuildMedia>,
ThreadOnlyChannelMixin<ChannelType.GuildMedia>
]> {
}
/**
* Sample Implementation of a structure for media channels, usable by direct end consumers.
*/
declare class MediaChannel<Omitted extends keyof APIGuildMediaChannel | '' = ''> extends Channel<ChannelType.GuildMedia, Omitted> {
constructor(data: Partialize<APIGuildMediaChannel, Omitted>);
}
interface PrivateThreadChannel<Omitted extends keyof APIPrivateThreadChannel | '' = ''> extends MixinTypes<Channel<ChannelType.PrivateThread>, [
TextChannelMixin<ChannelType.PrivateThread>,
ChannelOwnerMixin<ChannelType.PrivateThread>,
ChannelParentMixin<ChannelType.PrivateThread>,
ChannelPinMixin<ChannelType.PrivateThread>,
ChannelSlowmodeMixin<ChannelType.PrivateThread>,
ThreadChannelMixin<ChannelType.PrivateThread>
]> {
}
/**
* Sample Implementation of a structure for private thread channels, usable by direct end consumers.
*/
declare class PrivateThreadChannel<Omitted extends keyof APIPrivateThreadChannel | '' = ''> extends Channel<ChannelType.PrivateThread, Omitted> {
constructor(data: Partialize<APIPrivateThreadChannel, Omitted>);
}
interface PublicThreadChannel<Omitted extends keyof APIPublicThreadChannel | '' = ''> extends MixinTypes<Channel<ChannelType.PublicThread>, [
TextChannelMixin<ChannelType.PublicThread>,
ChannelOwnerMixin<ChannelType.PublicThread>,
ChannelParentMixin<ChannelType.PublicThread>,
ChannelPinMixin<ChannelType.PublicThread>,
ChannelSlowmodeMixin<ChannelType.PublicThread>,
ThreadChannelMixin<ChannelType.PublicThread>,
AppliedTagsMixin
]> {
}
/**
* Sample Implementation of a structure for public thread channels, usable by direct end consumers.
*/
declare class PublicThreadChannel<Omitted extends keyof APIPublicThreadChannel | '' = ''> extends Channel<ChannelType.PublicThread, Omitted> {
constructor(data: Partialize<APIPublicThreadChannel, Omitted>);
}
interface StageChannel<Omitted extends keyof APIGuildStageVoiceChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildStageVoice>, [
ChannelParentMixin<ChannelType.GuildStageVoice>,
ChannelPermissionMixin<ChannelType.GuildStageVoice>,
ChannelSlowmodeMixin<ChannelType.GuildStageVoice>,
ChannelWebhookMixin<ChannelType.GuildStageVoice>,
VoiceChannelMixin<ChannelType.GuildStageVoice>
]> {
}
declare class StageChannel<Omitted extends keyof APIGuildStageVoiceChannel | '' = ''> extends Channel<ChannelType.GuildStageVoice, Omitted> {
constructor(data: Partialize<APIGuildStageVoiceChannel, Omitted>);
}
interface TextChannel<Omitted extends keyof APITextChannel | '' = ''> extends MixinTypes<Channel<ChannelType.GuildText>, [
TextChannelMixin<ChannelType.GuildText>,
ChannelParentMixin<ChannelType.GuildText>,
ChannelPermissionMixin<ChannelType.GuildText