mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-12 01:23:31 +01:00
feat: message structures (#10982)
* feat: message structures * fix: docs * chore: components and more * feat: embed and more * feat: more substructures and code review suggestions * chore: tests and date conversions * chore: jsdoc strings * fix: tests * fix: tests * feat: hexColor getters * chore: remove getters for nested data * chore: apply suggestions from code review * fix: burst_colors in toJSON * docs: rephrase SectionBuilder remark * chore: add LabelComponent * fix: add name and size to file component * chore: move resolved interaction data to interactions dir * fix: code review * chore: bump discord-api-types * chore: apply code review suggestions * fix: lockfile * chore: update remark * fix: missing export * chore: code review and tests * build: fix file * fix: typo * fix: missing toJSON * fix: remove redundant patch overrides * chore: missing component suffix * chore: better name * chore: add comment explaining timestamp conversion --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
16
packages/structures/src/bitfields/AttachmentFlagsBitField.ts
Normal file
16
packages/structures/src/bitfields/AttachmentFlagsBitField.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { AttachmentFlags } from 'discord-api-types/v10';
|
||||
import { BitField } from './BitField.js';
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Attachment#flags} bitfield.
|
||||
*/
|
||||
export class AttachmentFlagsBitField extends BitField<keyof AttachmentFlags> {
|
||||
/**
|
||||
* Numeric attachment flags.
|
||||
*/
|
||||
public static override readonly Flags = AttachmentFlags;
|
||||
|
||||
public override toJSON() {
|
||||
return super.toJSON(true);
|
||||
}
|
||||
}
|
||||
16
packages/structures/src/bitfields/MessageFlagsBitField.ts
Normal file
16
packages/structures/src/bitfields/MessageFlagsBitField.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { MessageFlags } from 'discord-api-types/v10';
|
||||
import { BitField } from './BitField.js';
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Message#flags} bitfield.
|
||||
*/
|
||||
export class MessageFlagsBitField extends BitField<keyof MessageFlags> {
|
||||
/**
|
||||
* Numeric message flags.
|
||||
*/
|
||||
public static override readonly Flags = MessageFlags;
|
||||
|
||||
public override toJSON() {
|
||||
return super.toJSON(true);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from './BitField.js';
|
||||
|
||||
export * from './AttachmentFlagsBitField.js';
|
||||
export * from './ChannelFlagsBitField.js';
|
||||
export * from './MessageFlagsBitField.js';
|
||||
export * from './PermissionsBitField.js';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { DiscordSnowflake } from '@sapphire/snowflake';
|
||||
import type { APIChannel, APIPartialChannel, ChannelType, ChannelFlags } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { ChannelFlagsBitField } from '../bitfields/ChannelFlagsBitField.js';
|
||||
import { kData, kPatch } from '../utils/symbols.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import { isIdSet } from '../utils/type-guards.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
import type { ChannelPermissionMixin } from './mixins/ChannelPermissionMixin.js';
|
||||
@@ -50,15 +50,6 @@ export class Channel<
|
||||
super(data as ChannelDataType<Type>);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<ChannelDataType<Type>>) {
|
||||
return super[kPatch](data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the channel
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
export * from './bitfields/index.js';
|
||||
export * from './channels/index.js';
|
||||
export * from './interactions/index.js';
|
||||
export * from './invites/index.js';
|
||||
export * from './messages/index.js';
|
||||
export * from './polls/index.js';
|
||||
export * from './stickers/index.js';
|
||||
export * from './users/index.js';
|
||||
export * from './Structure.js';
|
||||
export * from './Mixin.js';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { APIInteractionDataResolved } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents data for users, members, channels, and roles in the message's auto-populated select menus.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has substructures `User`, `Channel`, `Role`, `Message`, `GuildMember`, `Attachment`, which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export abstract class ResolvedInteractionData<
|
||||
Omitted extends keyof APIInteractionDataResolved | '' = '',
|
||||
> extends Structure<APIInteractionDataResolved, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIInteractionDataResolved, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
1
packages/structures/src/interactions/index.ts
Normal file
1
packages/structures/src/interactions/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './ResolvedInteractionData.js';
|
||||
@@ -1,6 +1,7 @@
|
||||
import { type APIInvite, type APIExtendedInvite, RouteBases } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData, kExpiresTimestamp, kCreatedTimestamp, kPatch } from '../utils/symbols.js';
|
||||
import { dateToDiscordISOTimestamp } from '../utils/optimization.js';
|
||||
import { kData, kExpiresTimestamp, kCreatedTimestamp } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
export interface APIActualInvite extends APIInvite, Partial<Omit<APIExtendedInvite, keyof APIInvite>> {}
|
||||
@@ -47,16 +48,6 @@ export class Invite<Omitted extends keyof APIActualInvite | '' = 'created_at' |
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<APIActualInvite>) {
|
||||
super[kPatch](data);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
@@ -201,11 +192,11 @@ export class Invite<Omitted extends keyof APIActualInvite | '' = 'created_at' |
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kExpiresTimestamp]) {
|
||||
clone.expires_at = new Date(this[kExpiresTimestamp]).toISOString();
|
||||
clone.expires_at = dateToDiscordISOTimestamp(new Date(this[kExpiresTimestamp]));
|
||||
}
|
||||
|
||||
if (this[kCreatedTimestamp]) {
|
||||
clone.created_at = new Date(this[kCreatedTimestamp]).toISOString();
|
||||
clone.created_at = dateToDiscordISOTimestamp(new Date(this[kCreatedTimestamp]));
|
||||
}
|
||||
|
||||
return clone;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { APIApplicationCommandInteractionMetadata, InteractionType } from 'discord-api-types/v10';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
import { InteractionMetadata } from './InteractionMetadata.js';
|
||||
|
||||
/**
|
||||
* Represents metadata about the application command interaction causing a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `User` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ApplicationCommandInteractionMetadata<
|
||||
Omitted extends keyof APIApplicationCommandInteractionMetadata | '' = '',
|
||||
> extends InteractionMetadata<InteractionType.ApplicationCommand, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ApplicationCommandInteractionMetadata.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIApplicationCommandInteractionMetadata> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIApplicationCommandInteractionMetadata, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the message the command was run on
|
||||
*/
|
||||
public get targetMessageId() {
|
||||
return this[kData].target_message_id;
|
||||
}
|
||||
}
|
||||
118
packages/structures/src/messages/Attachment.ts
Normal file
118
packages/structures/src/messages/Attachment.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import type { APIAttachment, AttachmentFlags } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { AttachmentFlagsBitField } from '../bitfields/AttachmentFlagsBitField.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
export class Attachment<Omitted extends keyof APIAttachment | '' = ''> extends Structure<APIAttachment, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Attachment.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIAttachment> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIAttachment, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the attachment
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the attached file
|
||||
*/
|
||||
public get filename() {
|
||||
return this[kData].filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* The title of the file
|
||||
*/
|
||||
public get title() {
|
||||
return this[kData].title;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description for the file
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attachment's media type
|
||||
*/
|
||||
public get contentType() {
|
||||
return this[kData].content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the file in bytes
|
||||
*/
|
||||
public get size() {
|
||||
return this[kData].size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The source URL of the file
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of the file
|
||||
*/
|
||||
public get proxyURL() {
|
||||
return this[kData].proxy_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the file (if image)
|
||||
*/
|
||||
public get height() {
|
||||
return this[kData].height;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the file (if image)
|
||||
*/
|
||||
public get width() {
|
||||
return this[kData].width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this attachment is ephemeral
|
||||
*/
|
||||
public get ephemeral() {
|
||||
return this[kData].ephemeral;
|
||||
}
|
||||
|
||||
/**
|
||||
* The duration of the audio file
|
||||
*/
|
||||
public get durationSecs() {
|
||||
return this[kData].duration_secs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64 encoded bytearray representing a sampled waveform
|
||||
*/
|
||||
public get waveform() {
|
||||
return this[kData].waveform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment flags combined as a bitfield
|
||||
*/
|
||||
public get flags() {
|
||||
const flags = this[kData].flags;
|
||||
return flags ? new AttachmentFlagsBitField(this[kData].flags as AttachmentFlags) : null;
|
||||
}
|
||||
}
|
||||
54
packages/structures/src/messages/ChannelMention.ts
Normal file
54
packages/structures/src/messages/ChannelMention.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import type { APIChannelMention } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents the mention of a channel on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class ChannelMention<Omitted extends keyof APIChannelMention | '' = ''> extends Structure<
|
||||
APIChannelMention,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ChannelMention.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIChannelMention> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the channel mention
|
||||
*/
|
||||
public constructor(data: Partialize<APIChannelMention, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the mentioned channel
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the mentioned channel
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the mentioned channel
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the guild the mentioned channel is in
|
||||
*/
|
||||
public get guildId() {
|
||||
return this[kData].guild_id;
|
||||
}
|
||||
}
|
||||
48
packages/structures/src/messages/InteractionMetadata.ts
Normal file
48
packages/structures/src/messages/InteractionMetadata.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { APIMessageInteractionMetadata, InteractionType } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
export type InteractionMetadataType<Type extends InteractionType> = Extract<
|
||||
APIMessageInteractionMetadata,
|
||||
{ type: Type }
|
||||
>;
|
||||
|
||||
/**
|
||||
* Represents metadata about the interaction causing a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `User` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export abstract class InteractionMetadata<
|
||||
Type extends InteractionType,
|
||||
Omitted extends keyof InteractionMetadataType<Type> | '' = '',
|
||||
> extends Structure<InteractionMetadataType<Type>, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<InteractionMetadataType<Type>, Omitted>) {
|
||||
super(data as InteractionMetadataType<Type>);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the interaction
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the original response message, present only on follow-up messages
|
||||
*/
|
||||
public get originalResponseMessageId() {
|
||||
return this[kData].original_response_message_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of interaction
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
}
|
||||
178
packages/structures/src/messages/Message.ts
Normal file
178
packages/structures/src/messages/Message.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { DiscordSnowflake } from '@sapphire/snowflake';
|
||||
import type { APIMessage, MessageFlags } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { MessageFlagsBitField } from '../bitfields/MessageFlagsBitField.js';
|
||||
import { dateToDiscordISOTimestamp } from '../utils/optimization.js';
|
||||
import { kData, kEditedTimestamp } from '../utils/symbols.js';
|
||||
import { isIdSet } from '../utils/type-guards.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
// TODO: missing substructures: application
|
||||
|
||||
/**
|
||||
* Represents a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has substructures `Message`, `Channel`, `MessageActivity`, `MessageCall`, `MessageReference`, `Attachment`, `Application`, `ChannelMention`, `Reaction`, `Poll`, `ResolvedInteractionData`, `RoleSubscriptionData`, `Sticker`, all the different `Component`s, ... which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class Message<Omitted extends keyof APIMessage | '' = 'edited_timestamp' | 'timestamp'> extends Structure<
|
||||
APIMessage,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Message
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIMessage> = {
|
||||
set timestamp(_: string) {},
|
||||
set edited_timestamp(_: string) {},
|
||||
};
|
||||
|
||||
protected [kEditedTimestamp]: number | null = null;
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the message
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessage, Omitted>) {
|
||||
super(data);
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected override optimizeData(data: Partial<APIMessage>) {
|
||||
if (data.edited_timestamp) {
|
||||
this[kEditedTimestamp] = Date.parse(data.edited_timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The message's id
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the interaction's application, if this message is a reply to an interaction
|
||||
*/
|
||||
public get applicationId() {
|
||||
return this[kData].application_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The channel's id this message was sent in
|
||||
*/
|
||||
public get channelId() {
|
||||
return this[kData].channel_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp this message was created at
|
||||
*/
|
||||
public get createdTimestamp() {
|
||||
return isIdSet(this.id) ? DiscordSnowflake.timestampFrom(this.id) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the message was created at
|
||||
*/
|
||||
public get createdAt() {
|
||||
const createdTimestamp = this.createdTimestamp;
|
||||
return createdTimestamp ? new Date(createdTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The content of the message
|
||||
*/
|
||||
public get content() {
|
||||
return this[kData].content;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp this message was last edited at, or `null` if it never was edited
|
||||
*/
|
||||
public get editedTimestamp() {
|
||||
return this[kEditedTimestamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the message was last edited at, or `null` if it never was edited
|
||||
*/
|
||||
public get editedAt() {
|
||||
const editedTimestamp = this.editedTimestamp;
|
||||
return editedTimestamp ? new Date(editedTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The flags of this message as a bit field
|
||||
*/
|
||||
public get flags() {
|
||||
const flags = this[kData].flags;
|
||||
return flags ? new MessageFlagsBitField(this[kData].flags as MessageFlags) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nonce used when sending this message.
|
||||
*
|
||||
* @remarks This is only present in MESSAGE_CREATE event, if a nonce was provided when sending
|
||||
*/
|
||||
public get nonce() {
|
||||
return this[kData].nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this message is pinned in its channel
|
||||
*/
|
||||
public get pinned() {
|
||||
return this[kData].pinned;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generally increasing integer (there may be gaps or duplicates) that represents the approximate position of the message in a thread
|
||||
* It can be used to estimate the relative position of the message in a thread in company with `totalMessageSent` on parent thread
|
||||
*/
|
||||
public get position() {
|
||||
return this[kData].position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this message was a TTS message
|
||||
*/
|
||||
public get tts() {
|
||||
return this[kData].tts;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of message
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the message is generated by a webhook, this is the webhook's id
|
||||
*/
|
||||
public get webhookId() {
|
||||
return this[kData].webhook_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.toJSON}
|
||||
*/
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kEditedTimestamp]) {
|
||||
clone.edited_timestamp = dateToDiscordISOTimestamp(new Date(this[kEditedTimestamp]));
|
||||
}
|
||||
|
||||
const createdAt = this.createdAt;
|
||||
if (createdAt) {
|
||||
clone.timestamp = dateToDiscordISOTimestamp(createdAt);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
35
packages/structures/src/messages/MessageActivity.ts
Normal file
35
packages/structures/src/messages/MessageActivity.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { APIMessageActivity } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
export class MessageActivity<Omitted extends keyof APIMessageActivity | '' = ''> extends Structure<
|
||||
APIMessageActivity,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MessageActivity.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMessageActivity> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageActivity, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The party id from a Rich Presence event
|
||||
*/
|
||||
public get partyId() {
|
||||
return this[kData].party_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of message activity
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
}
|
||||
65
packages/structures/src/messages/MessageCall.ts
Normal file
65
packages/structures/src/messages/MessageCall.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { APIMessageCall } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { dateToDiscordISOTimestamp } from '../utils/optimization.js';
|
||||
import { kEndedTimestamp } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
export class MessageCall<Omitted extends keyof APIMessageCall | '' = 'ended_timestamp'> extends Structure<
|
||||
APIMessageCall,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MessageCall
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIMessageCall> = {
|
||||
set ended_timestamp(_: string) {},
|
||||
};
|
||||
|
||||
protected [kEndedTimestamp]: number | null = null;
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the message call
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageCall, Omitted>) {
|
||||
super(data);
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected override optimizeData(data: Partial<APIMessageCall>) {
|
||||
if (data.ended_timestamp) {
|
||||
this[kEndedTimestamp] = Date.parse(data.ended_timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp this call ended at, or `null` if it didn't end yet
|
||||
*/
|
||||
public get endedTimestamp() {
|
||||
return this[kEndedTimestamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the call ended at, or `null` if it didn't end yet
|
||||
*/
|
||||
public get endedAt() {
|
||||
const endedTimestamp = this.endedTimestamp;
|
||||
return endedTimestamp ? new Date(endedTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.toJSON}
|
||||
*/
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kEndedTimestamp]) {
|
||||
clone.ended_timestamp = dateToDiscordISOTimestamp(new Date(this[kEndedTimestamp]));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { APIMessageComponentInteractionMetadata, InteractionType } from 'discord-api-types/v10';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
import { InteractionMetadata } from './InteractionMetadata.js';
|
||||
|
||||
/**
|
||||
* Represents metadata about the message component interaction causing a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class MessageComponentInteractionMetadata<
|
||||
Omitted extends keyof APIMessageComponentInteractionMetadata | '' = '',
|
||||
> extends InteractionMetadata<InteractionType.MessageComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MessageComponentInteractionMetadata.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMessageComponentInteractionMetadata> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageComponentInteractionMetadata, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the message that contained the interactive component
|
||||
*/
|
||||
public get interactedMessageId() {
|
||||
return this[kData].interacted_message_id;
|
||||
}
|
||||
}
|
||||
54
packages/structures/src/messages/MessageReference.ts
Normal file
54
packages/structures/src/messages/MessageReference.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { MessageReferenceType, type APIMessageReference } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents the reference to another message on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class MessageReference<Omitted extends keyof APIMessageReference | '' = ''> extends Structure<
|
||||
APIMessageReference,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MessageReference.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIMessageReference> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the message reference
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageReference, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of this reference
|
||||
*/
|
||||
public get type() {
|
||||
return 'type' in this[kData] ? (this[kData].type as MessageReferenceType) : MessageReferenceType.Default;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the referenced message
|
||||
*/
|
||||
public get messageId() {
|
||||
return this[kData].message_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the channel the referenced message was sent in
|
||||
*/
|
||||
public get channelId() {
|
||||
return this[kData].channel_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the guild the referenced message was sent in
|
||||
*/
|
||||
public get guildId() {
|
||||
return this[kData].guild_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { APIModalSubmitInteractionMetadata, InteractionType } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
import { InteractionMetadata } from './InteractionMetadata.js';
|
||||
|
||||
/**
|
||||
* Represents metadata about the modal submit interaction causing a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `InteractionMetadata` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ModalSubmitInteractionMetadata<
|
||||
Omitted extends keyof APIModalSubmitInteractionMetadata | '' = '',
|
||||
> extends InteractionMetadata<InteractionType.ModalSubmit, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ModalSubmitInteractionMetadata.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIModalSubmitInteractionMetadata> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIModalSubmitInteractionMetadata, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
80
packages/structures/src/messages/Reaction.ts
Normal file
80
packages/structures/src/messages/Reaction.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { APIReaction } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kBurstColors, kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a reaction on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has substructures `Emoji`, `ReactionCountDetails` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class Reaction<Omitted extends keyof APIReaction | '' = ''> extends Structure<APIReaction, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Reaction.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIReaction> = {
|
||||
set burst_colors(_: string[]) {},
|
||||
};
|
||||
|
||||
protected [kBurstColors]: number[] | null = null;
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the reaction
|
||||
*/
|
||||
public constructor(data: Partialize<APIReaction, Omitted>) {
|
||||
super(data);
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected override optimizeData(data: Partial<APIReaction>) {
|
||||
if (data.burst_colors) {
|
||||
this[kBurstColors] = data.burst_colors.map((color) => Number.parseInt(color, 16));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount how often this emoji has been used to react (including super reacts)
|
||||
*/
|
||||
public get count() {
|
||||
return this[kData].count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user has reacted using this emoji
|
||||
*/
|
||||
public get me() {
|
||||
return this[kData].me;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user has super-reacted using this emoji
|
||||
*/
|
||||
public get meBurst() {
|
||||
return this[kData].me_burst;
|
||||
}
|
||||
|
||||
/**
|
||||
* The colors used for super reaction
|
||||
*/
|
||||
public get burstColors() {
|
||||
return this[kBurstColors];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.toJSON}
|
||||
*/
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kBurstColors]) {
|
||||
clone.burst_colors = this[kBurstColors].map((color) => `#${color.toString(16).padStart(6, '0')}`);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
40
packages/structures/src/messages/ReactionCountDetails.ts
Normal file
40
packages/structures/src/messages/ReactionCountDetails.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { APIReactionCountDetails } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents the usage count of a reaction on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class ReactionCountDetails<Omitted extends keyof APIReactionCountDetails | '' = ''> extends Structure<
|
||||
APIReactionCountDetails,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ReactionCountDetails.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIReactionCountDetails> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the reaction count details
|
||||
*/
|
||||
public constructor(data: Partialize<APIReactionCountDetails, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount how often this emoji has been used to react (excluding super reacts)
|
||||
*/
|
||||
public get normal() {
|
||||
return this[kData].normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount how often this emoji has been used to super-react
|
||||
*/
|
||||
public get burst() {
|
||||
return this[kData].burst;
|
||||
}
|
||||
}
|
||||
48
packages/structures/src/messages/RoleSubscriptionData.ts
Normal file
48
packages/structures/src/messages/RoleSubscriptionData.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { APIMessageRoleSubscriptionData } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents metadata about the role subscription causing a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export abstract class RoleSubscriptionData<
|
||||
Omitted extends keyof APIMessageRoleSubscriptionData | '' = '',
|
||||
> extends Structure<APIMessageRoleSubscriptionData, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageRoleSubscriptionData, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the SKU and listing the user is subscribed to
|
||||
*/
|
||||
public get roleSubscriptionListingId() {
|
||||
return this[kData].role_subscription_listing_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the tier the user is subscribed to
|
||||
*/
|
||||
public get tierName() {
|
||||
return this[kData].tier_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of months the user has been subscribed for
|
||||
*/
|
||||
public get totalMonthsSubscribed() {
|
||||
return this[kData].total_months_subscribed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this notification is for a renewal
|
||||
*/
|
||||
public get isRenewal() {
|
||||
return this[kData].is_renewal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { APIActionRowComponent, APIComponentInActionRow, ComponentType } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import type { ComponentDataType } from './Component.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents an action row component on a message or modal.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `Component`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ActionRowComponent<
|
||||
Type extends APIComponentInActionRow,
|
||||
Omitted extends keyof APIActionRowComponent<Type> | '' = '',
|
||||
> extends Component<ComponentDataType<ComponentType.ActionRow>, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ActionRowComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<ComponentDataType<ComponentType.ActionRow>> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the action row
|
||||
*/
|
||||
public constructor(data: Partialize<ComponentDataType<ComponentType.ActionRow>, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { APIButtonComponent, APIButtonComponentWithCustomId, ButtonStyle } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* The data stored by a {@link ButtonComponent} structure based on its {@link (ButtonComponent:class)."style"} property.
|
||||
*/
|
||||
export type ButtonDataType<Style extends ButtonStyle> = Style extends
|
||||
| ButtonStyle.Danger
|
||||
| ButtonStyle.Primary
|
||||
| ButtonStyle.Secondary
|
||||
| ButtonStyle.Success
|
||||
? APIButtonComponentWithCustomId
|
||||
: Extract<APIButtonComponent, { style: Style }>;
|
||||
|
||||
export abstract class ButtonComponent<
|
||||
Style extends ButtonStyle,
|
||||
Omitted extends keyof ButtonDataType<Style> | '' = '',
|
||||
> extends Component<ButtonDataType<Style>, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the button
|
||||
*/
|
||||
public constructor(data: Partialize<ButtonDataType<Style>, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The style of the button
|
||||
*/
|
||||
public get style() {
|
||||
return this[kData].style;
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the button
|
||||
*/
|
||||
public get disabled() {
|
||||
return typeof this[kData].disabled === 'boolean' ? this[kData].disabled : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { APIChannelSelectComponent, ChannelType } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { SelectMenuComponent } from './SelectMenuComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a channel select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `SelectMenuDefaultValue`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ChannelSelectMenuComponent<
|
||||
Omitted extends keyof APIChannelSelectComponent | '' = '',
|
||||
> extends SelectMenuComponent<APIChannelSelectComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ChannelSelectMenuComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIChannelSelectComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the channel select menu
|
||||
*/
|
||||
public constructor(data: Partialize<APIChannelSelectComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of channel types to include in the channel select component
|
||||
*/
|
||||
public get channelTypes() {
|
||||
return Array.isArray(this[kData].channel_types) ? (this[kData].channel_types as readonly ChannelType[]) : null;
|
||||
}
|
||||
}
|
||||
36
packages/structures/src/messages/components/Component.ts
Normal file
36
packages/structures/src/messages/components/Component.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { APIBaseComponent, APIMessageComponent, APIModalComponent, ComponentType } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* The data stored by a {@link Component} structure based on its {@link (Component:class)."type"} property.
|
||||
*/
|
||||
export type ComponentDataType<Type extends ComponentType | 'unknown'> = Type extends ComponentType
|
||||
? Extract<APIMessageComponent | APIModalComponent, { type: Type }>
|
||||
: APIBaseComponent<ComponentType>;
|
||||
export abstract class Component<
|
||||
Type extends APIMessageComponent | APIModalComponent,
|
||||
Omitted extends keyof Type | '' = '',
|
||||
> extends Structure<Type, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the component
|
||||
*/
|
||||
public constructor(data: Partialize<Type, Omitted>) {
|
||||
super(data as Type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 32 bit integer used as an optional identifier for component
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the component
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { APIMessageComponentEmoji } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
export class ComponentEmoji<Omitted extends keyof APIMessageComponentEmoji | '' = ''> extends Structure<
|
||||
APIMessageComponentEmoji,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ComponentEmoji.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMessageComponentEmoji> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the component emoji
|
||||
*/
|
||||
public constructor(data: Partialize<APIMessageComponentEmoji, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the emoji
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the emoji
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this emoji is animated
|
||||
*/
|
||||
public get animated() {
|
||||
return this[kData].animated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { APIContainerComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a container component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `Component`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ContainerComponent<Omitted extends keyof APIContainerComponent | '' = ''> extends Component<
|
||||
APIContainerComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ContainerComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIContainerComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the container
|
||||
*/
|
||||
public constructor(data: Partialize<APIContainerComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Color for the accent on the container as RGB
|
||||
*/
|
||||
public get accentColor() {
|
||||
return this[kData].accent_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hexadecimal version of the accent color, with a leading hash
|
||||
*/
|
||||
public get hexAccentColor() {
|
||||
const accentColor = this.accentColor;
|
||||
if (typeof accentColor !== 'number') return accentColor;
|
||||
return `#${accentColor.toString(16).padStart(6, '0')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the container should be a spoiler (or blurred out)
|
||||
*/
|
||||
public get spoiler() {
|
||||
return this[kData].spoiler;
|
||||
}
|
||||
}
|
||||
48
packages/structures/src/messages/components/FileComponent.ts
Normal file
48
packages/structures/src/messages/components/FileComponent.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { APIFileComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a file component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `UnfurledMediaItem` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class FileComponent<Omitted extends keyof APIFileComponent | '' = ''> extends Component<
|
||||
APIFileComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each FileComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIFileComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the file component
|
||||
*/
|
||||
public constructor(data: Partialize<APIFileComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the media should be a spoiler (or blurred out)
|
||||
*/
|
||||
public get spoiler() {
|
||||
return this[kData].spoiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the file
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the file in bytes
|
||||
*/
|
||||
public get size() {
|
||||
return this[kData].size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { APIFileUploadComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a file upload component on a modal.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class FileUploadComponent<Omitted extends keyof APIFileUploadComponent | '' = ''> extends Component<
|
||||
APIFileUploadComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each FileUploadComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIFileUploadComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the file upload component
|
||||
*/
|
||||
public constructor(data: Partialize<APIFileUploadComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id to be sent in the interaction when the modal gets submitted
|
||||
*/
|
||||
public get customId() {
|
||||
return this[kData].custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of items that can be uploaded
|
||||
*/
|
||||
public get maxValues() {
|
||||
return this[kData].max_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum number of items that must be uploaded
|
||||
*/
|
||||
public get minValues() {
|
||||
return this[kData].min_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the file upload requires files to be uploaded before submitting the modal
|
||||
*/
|
||||
public get required() {
|
||||
return this[kData].required;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { APIButtonComponentWithCustomId, ButtonStyle } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import type { ButtonDataType } from './ButtonComponent.js';
|
||||
import { LabeledButtonComponent } from './LabeledButtonComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a button causing a message component interaction on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class InteractiveButtonComponent<
|
||||
Style extends ButtonStyle.Danger | ButtonStyle.Primary | ButtonStyle.Secondary | ButtonStyle.Success,
|
||||
Omitted extends keyof APIButtonComponentWithCustomId | '' = '',
|
||||
> extends LabeledButtonComponent<Style, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each InteractiveButtonComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIButtonComponentWithCustomId> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the interactive button
|
||||
*/
|
||||
public constructor(data: Partialize<APIButtonComponentWithCustomId, Omitted>) {
|
||||
super(data as ButtonDataType<Style>);
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id to be sent in the interaction when clicked
|
||||
*/
|
||||
public get customId() {
|
||||
return this[kData].custom_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { APILabelComponent, ComponentType } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import type { ComponentDataType } from './Component.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a label component on a modal.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `Component`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class LabelComponent<Omitted extends keyof APILabelComponent | '' = ''> extends Component<
|
||||
ComponentDataType<ComponentType.Label>,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each LabelComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<ComponentDataType<ComponentType.Label>> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the label
|
||||
*/
|
||||
public constructor(data: Partialize<ComponentDataType<ComponentType.Label>, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The label text
|
||||
*/
|
||||
public get label() {
|
||||
return this[kData].label;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional description text for the label
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { ButtonStyle } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import type { ButtonDataType } from './ButtonComponent.js';
|
||||
import { ButtonComponent } from './ButtonComponent.js';
|
||||
|
||||
/**
|
||||
* Base class for all buttons that can have a label on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `ComponentEmoji` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export abstract class LabeledButtonComponent<
|
||||
Style extends Exclude<ButtonStyle, ButtonStyle.Premium>,
|
||||
Omitted extends keyof ButtonDataType<Style> | '' = '',
|
||||
> extends ButtonComponent<Style, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the button
|
||||
*/
|
||||
public constructor(data: Partialize<ButtonDataType<Style>, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The label to be displayed on the button
|
||||
*/
|
||||
public get label() {
|
||||
return this[kData].label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { APIButtonComponentWithURL, ButtonStyle } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { LabeledButtonComponent } from './LabeledButtonComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a button linking to an URL on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class LinkButtonComponent<
|
||||
Omitted extends keyof APIButtonComponentWithURL | '' = '',
|
||||
> extends LabeledButtonComponent<ButtonStyle.Link, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each LinkButtonComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIButtonComponentWithURL> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the link button
|
||||
*/
|
||||
public constructor(data: Partialize<APIButtonComponentWithURL, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to direct users to when clicked
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { APIMediaGalleryComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a media gallery component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `MediaGalleryItem`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class MediaGalleryComponent<Omitted extends keyof APIMediaGalleryComponent | '' = ''> extends Component<
|
||||
APIMediaGalleryComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MediaGalleryComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMediaGalleryComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the media gallery
|
||||
*/
|
||||
public constructor(data: Partialize<APIMediaGalleryComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { APIMediaGalleryItem } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents an item in a media gallery on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `UnfurledMediaItem` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class MediaGalleryItem<Omitted extends keyof APIMediaGalleryItem | '' = ''> extends Structure<
|
||||
APIMediaGalleryItem,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MediaGalleryItem.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMediaGalleryItem> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the media gallery item
|
||||
*/
|
||||
public constructor(data: Partialize<APIMediaGalleryItem, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt text for the media
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the media should be a spoiler (or blurred out)
|
||||
*/
|
||||
public get spoiler() {
|
||||
return this[kData].spoiler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { APIMentionableSelectComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { SelectMenuComponent } from './SelectMenuComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a mentionable select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `SelectMenuDefaultValue`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class MentionableSelectMenuComponent<
|
||||
Omitted extends keyof APIMentionableSelectComponent | '' = '',
|
||||
> extends SelectMenuComponent<APIMentionableSelectComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each MentionableSelectMenuComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIMentionableSelectComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the mentionable select menu
|
||||
*/
|
||||
public constructor(data: Partialize<APIMentionableSelectComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { APIButtonComponentWithSKUId, ButtonStyle } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { ButtonComponent } from './ButtonComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a button used to buy an SKU from a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class PremiumButtonComponent<
|
||||
Omitted extends keyof APIButtonComponentWithSKUId | '' = '',
|
||||
> extends ButtonComponent<ButtonStyle.Premium, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each PremiumButtonComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIButtonComponentWithSKUId> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the premium button
|
||||
*/
|
||||
public constructor(data: Partialize<APIButtonComponentWithSKUId, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id for a purchasable SKU
|
||||
*/
|
||||
public get skuId() {
|
||||
return this[kData].sku_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { APIRoleSelectComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { SelectMenuComponent } from './SelectMenuComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a role select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `SelectMenuDefaultValue`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class RoleSelectMenuComponent<
|
||||
Omitted extends keyof APIRoleSelectComponent | '' = '',
|
||||
> extends SelectMenuComponent<APIRoleSelectComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each RoleSelectMenuComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIRoleSelectComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the role select menu
|
||||
*/
|
||||
public constructor(data: Partialize<APIRoleSelectComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { APISectionComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a section component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `Component`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class SectionComponent<Omitted extends keyof APISectionComponent | '' = ''> extends Component<
|
||||
APISectionComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each SectionComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APISectionComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the section
|
||||
*/
|
||||
public constructor(data: Partialize<APISectionComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { APISelectMenuComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
export abstract class SelectMenuComponent<
|
||||
Type extends APISelectMenuComponent,
|
||||
Omitted extends keyof Type | '' = '',
|
||||
> extends Component<Type, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the select menu
|
||||
*/
|
||||
public constructor(data: Partialize<Type, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The customId to be sent in the interaction when a selection is made
|
||||
*/
|
||||
public get customId() {
|
||||
return this[kData].custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the select menu is disabled
|
||||
*/
|
||||
public get disabled() {
|
||||
return this[kData].disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of items that can be chosen
|
||||
*/
|
||||
public get maxValues() {
|
||||
return this[kData].max_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum number of items that must be chosen
|
||||
*/
|
||||
public get minValues() {
|
||||
return this[kData].min_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom placeholder text if nothing is selected
|
||||
*/
|
||||
public get placeholder() {
|
||||
return this[kData].placeholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a selection is required
|
||||
*/
|
||||
public get required() {
|
||||
return this[kData].required;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { APISelectMenuDefaultValue, SelectMenuDefaultValueType } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
export class SelectMenuDefaultValue<
|
||||
Type extends SelectMenuDefaultValueType,
|
||||
Omitted extends keyof APISelectMenuDefaultValue<Type> | '' = '',
|
||||
> extends Structure<APISelectMenuDefaultValue<Type>, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each SelectMenuDefaultValue.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APISelectMenuDefaultValue<SelectMenuDefaultValueType>> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the select menu default value
|
||||
*/
|
||||
public constructor(data: Partialize<APISelectMenuDefaultValue<Type>, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { APISeparatorComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a separator component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class SeparatorComponent<Omitted extends keyof APISeparatorComponent | '' = ''> extends Component<
|
||||
APISeparatorComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each SeparatorComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APISeparatorComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the separator
|
||||
*/
|
||||
public constructor(data: Partialize<APISeparatorComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a visual divider should be displayed in the component
|
||||
*/
|
||||
public get divider() {
|
||||
return this[kData].divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the separator padding
|
||||
*/
|
||||
public get spacing() {
|
||||
return this[kData].spacing;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { APIStringSelectComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { SelectMenuComponent } from './SelectMenuComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a string select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `StringSelectMenuOption`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class StringSelectMenuComponent<
|
||||
Omitted extends keyof APIStringSelectComponent | '' = '',
|
||||
> extends SelectMenuComponent<APIStringSelectComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each StringSelectMenuComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIStringSelectComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the string select menu
|
||||
*/
|
||||
public constructor(data: Partialize<APIStringSelectComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type { APISelectMenuOption } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents an option in a string select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `ComponentEmoji` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class StringSelectMenuOption<Omitted extends keyof APISelectMenuOption | '' = ''> extends Structure<
|
||||
APISelectMenuOption,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each StringSelectMenuOption.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APISelectMenuOption> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the string select menu option
|
||||
*/
|
||||
public constructor(data: Partialize<APISelectMenuOption, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this option should be already-selected by default
|
||||
*/
|
||||
public get default() {
|
||||
return this[kData].default;
|
||||
}
|
||||
|
||||
/**
|
||||
* An additional description of the option
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user-facing name of the option
|
||||
*/
|
||||
public get label() {
|
||||
return this[kData].label;
|
||||
}
|
||||
|
||||
/**
|
||||
* The dev-defined value of the option
|
||||
*/
|
||||
public get value() {
|
||||
return this[kData].value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { APITextDisplayComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a text display component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class TextDisplayComponent<Omitted extends keyof APITextDisplayComponent | '' = ''> extends Component<
|
||||
APITextDisplayComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each TextDisplayComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APITextDisplayComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the text display
|
||||
*/
|
||||
public constructor(data: Partialize<APITextDisplayComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Text that will be displayed similar to a message
|
||||
*/
|
||||
public get content() {
|
||||
return this[kData].content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import type { APITextInputComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a text input component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class TextInputComponent<Omitted extends keyof APITextInputComponent | '' = ''> extends Component<
|
||||
APITextInputComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each TextInputComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APITextInputComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the text input
|
||||
*/
|
||||
public constructor(data: Partialize<APITextInputComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id for the text input
|
||||
*/
|
||||
public get customId() {
|
||||
return this[kData].custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text that appears on top of the text input field
|
||||
*/
|
||||
public get label() {
|
||||
return this[kData].label;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximal length of text input
|
||||
*/
|
||||
public get maxLength() {
|
||||
return this[kData].max_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimal length of text input
|
||||
*/
|
||||
public get minLength() {
|
||||
return this[kData].min_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* The placeholder for the text input
|
||||
*/
|
||||
public get placeholder() {
|
||||
return this[kData].placeholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this text input is required
|
||||
*/
|
||||
public get required() {
|
||||
return this[kData].required;
|
||||
}
|
||||
|
||||
/**
|
||||
* One of text input styles
|
||||
*/
|
||||
public get style() {
|
||||
return this[kData].style;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pre-filled text in the text input
|
||||
*/
|
||||
public get value() {
|
||||
return this[kData].value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { APIThumbnailComponent } from 'discord-api-types/v10';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { Component } from './Component.js';
|
||||
|
||||
/**
|
||||
* Represents a thumbnail component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `UnfurledMediaItem` which needs to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class ThumbnailComponent<Omitted extends keyof APIThumbnailComponent | '' = ''> extends Component<
|
||||
APIThumbnailComponent,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each ThumbnailComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIThumbnailComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the thumbnail
|
||||
*/
|
||||
public constructor(data: Partialize<APIThumbnailComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt text for the media
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the thumbnail should be a spoiler (or blurred out)
|
||||
*/
|
||||
public get spoiler() {
|
||||
return this[kData].spoiler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { APIUnfurledMediaItem } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
// TODO: add `flags` as a BitField class and appropriate getter, once it gets properly documented
|
||||
|
||||
/**
|
||||
* Represents a media item in a component on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class UnfurledMediaItem<Omitted extends keyof APIUnfurledMediaItem | '' = ''> extends Structure<
|
||||
APIUnfurledMediaItem,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each UnfurledMediaItem.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIUnfurledMediaItem> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the unfurled media item
|
||||
*/
|
||||
public constructor(data: Partialize<APIUnfurledMediaItem, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the uploaded attachment
|
||||
*/
|
||||
public get attachmentId() {
|
||||
return this[kData].attachment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The media type of the content
|
||||
*/
|
||||
public get contentType() {
|
||||
return this[kData].content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the media item (if image)
|
||||
*/
|
||||
public get height() {
|
||||
return this[kData].height;
|
||||
}
|
||||
|
||||
/**
|
||||
* The proxied URL of the media item
|
||||
*/
|
||||
public get proxyURL() {
|
||||
return this[kData].proxy_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports arbitrary URLs and attachment:// references
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the media item (if image)
|
||||
*/
|
||||
public get width() {
|
||||
return this[kData].width;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { APIUserSelectComponent } from 'discord-api-types/v10';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
import { SelectMenuComponent } from './SelectMenuComponent.js';
|
||||
|
||||
/**
|
||||
* Represents a user select menu component.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has `SelectMenuDefaultValue`s as substructures which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class UserSelectMenuComponent<
|
||||
Omitted extends keyof APIUserSelectComponent | '' = '',
|
||||
> extends SelectMenuComponent<APIUserSelectComponent, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each UserSelectMenuComponent.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIUserSelectComponent> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the user select menu
|
||||
*/
|
||||
public constructor(data: Partialize<APIUserSelectComponent, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
28
packages/structures/src/messages/components/index.ts
Normal file
28
packages/structures/src/messages/components/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
export * from './ActionRowComponent.js';
|
||||
export * from './ButtonComponent.js';
|
||||
export * from './ChannelSelectMenuComponent.js';
|
||||
export * from './Component.js';
|
||||
export * from './ContainerComponent.js';
|
||||
export * from './FileComponent.js';
|
||||
export * from './FileUploadComponent.js';
|
||||
export * from './InteractiveButtonComponent.js';
|
||||
export * from './LinkButtonComponent.js';
|
||||
export * from './MediaGalleryComponent.js';
|
||||
export * from './MentionableSelectMenuComponent.js';
|
||||
export * from './LabeledButtonComponent.js';
|
||||
export * from './PremiumButtonComponent.js';
|
||||
export * from './RoleSelectMenuComponent.js';
|
||||
export * from './SectionComponent.js';
|
||||
export * from './SelectMenuComponent.js';
|
||||
export * from './SeparatorComponent.js';
|
||||
export * from './StringSelectMenuComponent.js';
|
||||
export * from './TextDisplayComponent.js';
|
||||
export * from './TextInputComponent.js';
|
||||
export * from './ThumbnailComponent.js';
|
||||
export * from './UserSelectMenuComponent.js';
|
||||
|
||||
export * from './ComponentEmoji.js';
|
||||
export * from './MediaGalleryItem.js';
|
||||
export * from './SelectMenuDefaultValue.js';
|
||||
export * from './StringSelectMenuOption.js';
|
||||
export * from './UnfurledMediaItem.js';
|
||||
104
packages/structures/src/messages/embeds/Embed.ts
Normal file
104
packages/structures/src/messages/embeds/Embed.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { APIEmbed } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { dateToDiscordISOTimestamp } from '../../utils/optimization.js';
|
||||
import { kCreatedTimestamp, kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has substructures `EmbedAuthor`, `EmbedFooter`, `EmbedField`, `EmbedImage`, `EmbedThumbnail`, `EmbedProvider`, `EmbedVideo` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class Embed<Omitted extends keyof APIEmbed | '' = ''> extends Structure<APIEmbed, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Embed.
|
||||
*/
|
||||
public static override readonly DataTemplate: Partial<APIEmbed> = {
|
||||
set timestamp(_: string) {},
|
||||
};
|
||||
|
||||
protected [kCreatedTimestamp]: number | null = null;
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbed, Omitted>) {
|
||||
super(data);
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected override optimizeData(data: Partial<APIEmbed>) {
|
||||
if (data.timestamp) {
|
||||
this[kCreatedTimestamp] = Date.parse(data.timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The color code of the embed
|
||||
*/
|
||||
public get color() {
|
||||
return this[kData].color;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hexadecimal version of the embed color, with a leading hash
|
||||
*/
|
||||
public get hexColor() {
|
||||
const color = this.color;
|
||||
if (typeof color !== 'number') return color;
|
||||
return `#${color.toString(16).padStart(6, '0')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of the embed
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* THe title of the embed
|
||||
*/
|
||||
public get title() {
|
||||
return this[kData].title;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp of the embed content
|
||||
*/
|
||||
public get timestamp() {
|
||||
return this[kCreatedTimestamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of embed (always "rich" for webhook embeds)
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the embed
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.toJSON}
|
||||
*/
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kCreatedTimestamp]) {
|
||||
clone.timestamp = dateToDiscordISOTimestamp(new Date(this[kCreatedTimestamp]));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
46
packages/structures/src/messages/embeds/EmbedAuthor.ts
Normal file
46
packages/structures/src/messages/embeds/EmbedAuthor.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { APIEmbedAuthor } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents author data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedAuthor<Omitted extends keyof APIEmbedAuthor | '' = ''> extends Structure<APIEmbedAuthor, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedAuthor, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the author
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of author icon
|
||||
*/
|
||||
public get iconURL() {
|
||||
return this[kData].icon_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of author icon
|
||||
*/
|
||||
public get proxyIconURL() {
|
||||
return this[kData].proxy_icon_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the author
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
39
packages/structures/src/messages/embeds/EmbedField.ts
Normal file
39
packages/structures/src/messages/embeds/EmbedField.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { APIEmbedField } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a field's data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedField<Omitted extends keyof APIEmbedField | '' = ''> extends Structure<APIEmbedField, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedField, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the field
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the field
|
||||
*/
|
||||
public get value() {
|
||||
return this[kData].value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this field should display inline
|
||||
*/
|
||||
public get inline() {
|
||||
return this[kData].inline;
|
||||
}
|
||||
}
|
||||
39
packages/structures/src/messages/embeds/EmbedFooter.ts
Normal file
39
packages/structures/src/messages/embeds/EmbedFooter.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { APIEmbedFooter } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents footer data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedFooter<Omitted extends keyof APIEmbedFooter | '' = ''> extends Structure<APIEmbedFooter, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedFooter, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The footer text
|
||||
*/
|
||||
public get text() {
|
||||
return this[kData].text;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the footer icon
|
||||
*/
|
||||
public get iconURL() {
|
||||
return this[kData].icon_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of the footer icon
|
||||
*/
|
||||
public get proxyIconURL() {
|
||||
return this[kData].proxy_icon_url;
|
||||
}
|
||||
}
|
||||
46
packages/structures/src/messages/embeds/EmbedImage.ts
Normal file
46
packages/structures/src/messages/embeds/EmbedImage.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { APIEmbedImage } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents image data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedImage<Omitted extends keyof APIEmbedImage | '' = ''> extends Structure<APIEmbedImage, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedImage, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the image
|
||||
*/
|
||||
public get height() {
|
||||
return this[kData].height;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the image
|
||||
*/
|
||||
public get width() {
|
||||
return this[kData].width;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of the image
|
||||
*/
|
||||
public get proxyURL() {
|
||||
return this[kData].proxy_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Source URL of the image
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
35
packages/structures/src/messages/embeds/EmbedProvider.ts
Normal file
35
packages/structures/src/messages/embeds/EmbedProvider.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { APIEmbedProvider } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents provider data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedProvider<Omitted extends keyof APIEmbedProvider | '' = ''> extends Structure<
|
||||
APIEmbedProvider,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedProvider, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the provider
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the provider
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
49
packages/structures/src/messages/embeds/EmbedThumbnail.ts
Normal file
49
packages/structures/src/messages/embeds/EmbedThumbnail.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { APIEmbedThumbnail } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents thumbnail data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedThumbnail<Omitted extends keyof APIEmbedThumbnail | '' = ''> extends Structure<
|
||||
APIEmbedThumbnail,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedThumbnail, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the thumbnail
|
||||
*/
|
||||
public get height() {
|
||||
return this[kData].height;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the thumbnail
|
||||
*/
|
||||
public get width() {
|
||||
return this[kData].width;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of the thumbnail
|
||||
*/
|
||||
public get proxyURL() {
|
||||
return this[kData].proxy_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The source URL of the thumbnail
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
46
packages/structures/src/messages/embeds/EmbedVideo.ts
Normal file
46
packages/structures/src/messages/embeds/EmbedVideo.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { APIEmbedVideo } from 'discord-api-types/v10';
|
||||
import { Structure } from '../../Structure.js';
|
||||
import { kData } from '../../utils/symbols.js';
|
||||
import type { Partialize } from '../../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents video data in an embed on a message.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class EmbedVideo<Omitted extends keyof APIEmbedVideo | '' = ''> extends Structure<APIEmbedVideo, Omitted> {
|
||||
/**
|
||||
* @param data - The raw data received from the API for the connection
|
||||
*/
|
||||
public constructor(data: Partialize<APIEmbedVideo, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the video
|
||||
*/
|
||||
public get height() {
|
||||
return this[kData].height;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the video
|
||||
*/
|
||||
public get width() {
|
||||
return this[kData].width;
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxied URL of the video
|
||||
*/
|
||||
public get proxyURL() {
|
||||
return this[kData].proxy_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The source URL of the video
|
||||
*/
|
||||
public get url() {
|
||||
return this[kData].url;
|
||||
}
|
||||
}
|
||||
8
packages/structures/src/messages/embeds/index.ts
Normal file
8
packages/structures/src/messages/embeds/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './Embed.js';
|
||||
export * from './EmbedAuthor.js';
|
||||
export * from './EmbedField.js';
|
||||
export * from './EmbedFooter.js';
|
||||
export * from './EmbedImage.js';
|
||||
export * from './EmbedProvider.js';
|
||||
export * from './EmbedThumbnail.js';
|
||||
export * from './EmbedVideo.js';
|
||||
16
packages/structures/src/messages/index.ts
Normal file
16
packages/structures/src/messages/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export * from './components/index.js';
|
||||
export * from './embeds/index.js';
|
||||
|
||||
export * from './ApplicationCommandInteractionMetadata.js';
|
||||
export * from './Attachment.js';
|
||||
export * from './ChannelMention.js';
|
||||
export * from './InteractionMetadata.js';
|
||||
export * from './Message.js';
|
||||
export * from './MessageActivity.js';
|
||||
export * from './MessageCall.js';
|
||||
export * from './MessageComponentInteractionMetadata.js';
|
||||
export * from './MessageReference.js';
|
||||
export * from './ModalSubmitInteractionMetadata.js';
|
||||
export * from './Reaction.js';
|
||||
export * from './ReactionCountDetails.js';
|
||||
export * from './RoleSubscriptionData.js';
|
||||
87
packages/structures/src/polls/Poll.ts
Normal file
87
packages/structures/src/polls/Poll.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import type { APIPoll } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { dateToDiscordISOTimestamp } from '../utils/optimization.js';
|
||||
import { kData, kExpiresTimestamp } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a poll on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has substructures `PollMedia`, `PollAnswer`, `PollResults` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class Poll<Omitted extends keyof APIPoll | '' = ''> extends Structure<APIPoll, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each Poll.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIPoll> = {
|
||||
set expiry(_: string) {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Optimized storage of {@link discord-api-types/v10#(APIPoll:interface).expiry}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected [kExpiresTimestamp]: number | null = null;
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the poll
|
||||
*/
|
||||
public constructor(data: Partialize<APIPoll, Omitted>) {
|
||||
super(data);
|
||||
this.optimizeData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.optimizeData}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected override optimizeData(data: Partial<APIPoll>) {
|
||||
if (data.expiry) {
|
||||
this[kExpiresTimestamp] = Date.parse(data.expiry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a user can select multiple answers
|
||||
*/
|
||||
public get allowMultiselect() {
|
||||
return this[kData].allow_multiselect;
|
||||
}
|
||||
|
||||
/**
|
||||
* The layout type of the poll
|
||||
*/
|
||||
public get layoutType() {
|
||||
return this[kData].layout_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp this poll will expire at
|
||||
*/
|
||||
public get expiresTimestamp() {
|
||||
return this[kExpiresTimestamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the poll will expire at
|
||||
*/
|
||||
public get expiresAt() {
|
||||
const expiresTimestamp = this.expiresTimestamp;
|
||||
return expiresTimestamp ? new Date(expiresTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.toJSON}
|
||||
*/
|
||||
public override toJSON() {
|
||||
const clone = super.toJSON();
|
||||
if (this[kExpiresTimestamp]) {
|
||||
clone.expiry = dateToDiscordISOTimestamp(new Date(this[kExpiresTimestamp]));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
31
packages/structures/src/polls/PollAnswer.ts
Normal file
31
packages/structures/src/polls/PollAnswer.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { APIPollAnswer } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents an answer to a poll on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `PollMedia` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class PollAnswer<Omitted extends keyof APIPollAnswer | '' = ''> extends Structure<APIPollAnswer, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each PollAnswer.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIPollAnswer> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the poll answer
|
||||
*/
|
||||
public constructor(data: Partialize<APIPollAnswer, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the poll answer
|
||||
*/
|
||||
public get answerId() {
|
||||
return this[kData].answer_id;
|
||||
}
|
||||
}
|
||||
47
packages/structures/src/polls/PollAnswerCount.ts
Normal file
47
packages/structures/src/polls/PollAnswerCount.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { APIPollAnswerCount } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents the counts of answers to a poll on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class PollAnswerCount<Omitted extends keyof APIPollAnswerCount | '' = ''> extends Structure<
|
||||
APIPollAnswerCount,
|
||||
Omitted
|
||||
> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each PollAnswerCount.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIPollAnswerCount> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the poll answer count
|
||||
*/
|
||||
public constructor(data: Partialize<APIPollAnswerCount, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the poll answer
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of votes for this answer
|
||||
*/
|
||||
public get count() {
|
||||
return this[kData].count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user voted for this answer
|
||||
*/
|
||||
public get meVoted() {
|
||||
return this[kData].me_voted;
|
||||
}
|
||||
}
|
||||
31
packages/structures/src/polls/PollMedia.ts
Normal file
31
packages/structures/src/polls/PollMedia.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { APIPollMedia } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a field of a poll on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `Emoji` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class PollMedia<Omitted extends keyof APIPollMedia | '' = ''> extends Structure<APIPollMedia, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each PollMedia.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIPollMedia> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the poll media
|
||||
*/
|
||||
public constructor(data: Partialize<APIPollMedia, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The text of the poll field
|
||||
*/
|
||||
public get text() {
|
||||
return this[kData].text;
|
||||
}
|
||||
}
|
||||
31
packages/structures/src/polls/PollResults.ts
Normal file
31
packages/structures/src/polls/PollResults.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { APIPollResults } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents the results of a poll on a message on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
* @remarks has a substructure `PollAnswerCount` which need to be instantiated and stored by an extending class using it
|
||||
*/
|
||||
export class PollResults<Omitted extends keyof APIPollResults | '' = ''> extends Structure<APIPollResults, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each PollResults.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APIPollResults> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the poll results
|
||||
*/
|
||||
public constructor(data: Partialize<APIPollResults, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the votes have been precisely counted
|
||||
*/
|
||||
public get isFinalized() {
|
||||
return this[kData].is_finalized;
|
||||
}
|
||||
}
|
||||
5
packages/structures/src/polls/index.ts
Normal file
5
packages/structures/src/polls/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './Poll.js';
|
||||
export * from './PollAnswer.js';
|
||||
export * from './PollAnswerCount.js';
|
||||
export * from './PollMedia.js';
|
||||
export * from './PollResults.js';
|
||||
72
packages/structures/src/stickers/Sticker.ts
Normal file
72
packages/structures/src/stickers/Sticker.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { APISticker } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Represents a sticker on Discord.
|
||||
*
|
||||
* @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate`
|
||||
*/
|
||||
export class Sticker<Omitted extends keyof APISticker | '' = ''> extends Structure<APISticker, Omitted> {
|
||||
/**
|
||||
* The template used for removing data from the raw data stored for each SitckerItem.
|
||||
*/
|
||||
public static override DataTemplate: Partial<APISticker> = {};
|
||||
|
||||
/**
|
||||
* @param data - The raw data received from the API for the sticker item
|
||||
*/
|
||||
public constructor(data: Partialize<APISticker, Omitted>) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the sticker
|
||||
*/
|
||||
public get id() {
|
||||
return this[kData].id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the sticker
|
||||
*/
|
||||
public get name() {
|
||||
return this[kData].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The format type of the sticker
|
||||
*/
|
||||
public get formatType() {
|
||||
return this[kData].format_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this guild sticker can be used, may be false due to loss of Server Boosts
|
||||
*/
|
||||
public get available() {
|
||||
return this[kData].available;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of the sticker
|
||||
*/
|
||||
public get description() {
|
||||
return this[kData].description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The autocomplete/suggestion tags for the sticker
|
||||
*/
|
||||
public get tags() {
|
||||
return this[kData].tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of this sticker
|
||||
*/
|
||||
public get type() {
|
||||
return this[kData].type;
|
||||
}
|
||||
}
|
||||
1
packages/structures/src/stickers/index.ts
Normal file
1
packages/structures/src/stickers/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Sticker.js';
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { APIConnection } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData, kPatch } from '../utils/symbols.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
@@ -21,15 +21,6 @@ export class Connection<Omitted extends keyof APIConnection | '' = ''> extends S
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<APIConnection>) {
|
||||
return super[kPatch](data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the connection account
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DiscordSnowflake } from '@sapphire/snowflake';
|
||||
import type { APIUser } from 'discord-api-types/v10';
|
||||
import { Structure } from '../Structure.js';
|
||||
import { kData, kPatch } from '../utils/symbols.js';
|
||||
import { kData } from '../utils/symbols.js';
|
||||
import { isIdSet } from '../utils/type-guards.js';
|
||||
import type { Partialize } from '../utils/types.js';
|
||||
|
||||
@@ -24,15 +24,6 @@ export class User<Omitted extends keyof APIUser | '' = ''> extends Structure<API
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Structure.[kPatch]}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public override [kPatch](data: Partial<APIUser>) {
|
||||
return super[kPatch](data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user's id
|
||||
*/
|
||||
|
||||
@@ -8,3 +8,15 @@ export function extendTemplate<SuperTemplate extends Record<string, unknown>>(
|
||||
> &
|
||||
SuperTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a JavaScript Date object into the timestamp format used by Discord in payloads.
|
||||
* E.g. `2025-11-16T14:09:25.239000+00:00`
|
||||
*
|
||||
* @private
|
||||
* @param date a Date instance
|
||||
* @returns an ISO8601 timestamp with microseconds precision and explicit +00:00 timezone
|
||||
*/
|
||||
export function dateToDiscordISOTimestamp(date: Date) {
|
||||
return `${date.getUTCFullYear()}-${(date.getUTCMonth() + 1).toString().padStart(2, '0')}-${date.getUTCDate().toString().padStart(2, '0')}T${date.getUTCHours().toString().padStart(2, '0')}:${date.getUTCMinutes().toString().padStart(2, '0')}:${date.getUTCSeconds().toString().padStart(2, '0')}.${date.getUTCMilliseconds().toString().padEnd(6, '0')}+00:00`;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ export const kData = Symbol.for('djs.structures.data');
|
||||
export const kClone = Symbol.for('djs.structures.clone');
|
||||
export const kPatch = Symbol.for('djs.structures.patch');
|
||||
export const kExpiresTimestamp = Symbol.for('djs.structures.expiresTimestamp');
|
||||
export const kEndedTimestamp = Symbol.for('djs.structures.endedTimestamp');
|
||||
export const kCreatedTimestamp = Symbol.for('djs.structures.createdTimestamp');
|
||||
export const kEditedTimestamp = Symbol.for('djs.structures.editedTimestamp');
|
||||
export const kArchiveTimestamp = Symbol.for('djs.structures.archiveTimestamp');
|
||||
@@ -9,6 +10,8 @@ export const kArchiveTimestamp = Symbol.for('djs.structures.archiveTimestamp');
|
||||
export const kAllow = Symbol.for('djs.structures.allow');
|
||||
export const kDeny = Symbol.for('djs.structures.deny');
|
||||
|
||||
export const kBurstColors = Symbol.for('djs.structures.burstColors');
|
||||
|
||||
export const kLastPinTimestamp = Symbol.for('djs.structures.lastPinTimestamp');
|
||||
|
||||
export const kMixinConstruct = Symbol.for('djs.structures.mixin.construct');
|
||||
|
||||
Reference in New Issue
Block a user