diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9161e12e8..81b10b6db 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v2 - uses: denolib/setup-deno@v2 - name: Run fmt check script - run: deno fmt --check --ignore=./src/types/util.ts + run: deno fmt --check - name: Run lint script - run: deno lint src/** test/** --unstable + run: deno lint src/** test/** --unstable --ignore=./src/types/ diff --git a/src/types/README.md b/src/types/README.md new file mode 100644 index 000000000..37a5133e4 --- /dev/null +++ b/src/types/README.md @@ -0,0 +1,166 @@ +# Discordeno Typings Guidelines / Explanations + +Discordeno has a certain standard guidelines for our typings. Please follow this +as best as possible when contributing to the library. + +1. Discordeno Types + +These types will be specifically used by the end user for functions inside +Discordeno. + +Example: + +```ts +interface EditMemberOptions { + /** Value to set users nickname to. Requires MANAGE_NICKNAMES permission. */ + nick?: string; + /** Array of role ids the member will have after this edit. Useful for adding/removing multiple roles in 1 API call. Requires MANAGE_ROLES permission. */ + roles?: string[]; + /** Whether the user is muted in voice channels. Requires MUTE_MEMBERS permission. */ + mute?: boolean; + /** Whether the user is deafened in voice channels. Requires DEAFEN_MEMBERS permission. */ + deaf?: boolean; + /** The id of the channel to move user to if they are connected to voice. To kick the user from their current channel, set to null. Requires MOVE_MEMBERS permission. When moving members to channels, must have permissions to both CONNECT to the channel and have the MOVE_MEMBER permission. */ + channelID?: string; +} +``` + +Rules: + +- Camel Case +- Do not allow `null` +- Everything should have a comment explaining it +- These typings should be kept in the file with the function. + - Example: EditMemberOptions is at the bottom of the file where editMember() + is declared. + +2. Discord Types Incoming + +These types are meant for the payloads that we receive from Discord, whether +through gateway or REST. + +Example: + +```ts +export interface MemberCreatePayload { + /** The user this guild member represents */ + user: UserPayload; + /** The user's guild nickname if one is set. */ + nick?: string; + /** Array of role ids that the member has */ + roles: string[]; + /** When the user joined the guild. */ + joined_at: string; + /** When the user used their nitro boost on the server. */ + premium_since?: string; + /** Whether the user is deafened in voice channels */ + deaf: boolean; + /** Whether the user is muted in voice channels */ + mute: boolean; + /** Whether the user has passed the guild's Membership Screening requirements */ + pending?: boolean; +} +``` + +Rules: + +- Snake case (Or whatever discord uses. Everything here should be letter to + letter in accordance with discord's docs.) +- Everything should have a comment explaining it +- Kept in the src/types/api/incoming folder + +3. Discord Types Outgoing + +These types are meant **US** as we develop Discordeno. These will help us +prevent bugs when we are sending payloads to Discord whether through gateway or +REST. + +Example: + +```ts +export interface EditMemberPayload { + /** Value to set users nickname to. Requires MANAGE_NICKNAMES permission. */ + nick?: string; + /** Array of role ids the member is assigned. Requires MANAGE_ROLES permission. */ + roles?: string[]; + /** Whether the user is muted in voice channels. Requires MUTE_MEMBERS permission. */ + mute?: boolean; + /** Whether the user is deafened in voice channels. Requires DEAFEN_MEMBERS permission. */ + deaf?: boolean; + /** The id of the channel to move user to if they are connected to voice. To kick the user from their current channel, set to null. Requires MOVE_MEMBERS permission. When moving members to channels, must have permissions to both CONNECT to the channel and have the MOVE_MEMBER permission. */ + channel_id?: string | null; +} +``` + +Rules: + +- Snake case (Or whatever discord uses. Everything here should be letter to + letter in accordance with discord's docs.) +- Everything should have a comment explaining it +- Kept in the src/types/api/outgoing folder + +## Minimalistic + +Since Discord uses `snake_case` but we use `camelCase` we will end up with +redundant typings. In order to solve this, we have the `Camelize` type which +helps create a type using the snake case. + +If we have the base payload for Discord's `User` as follows: + +```ts +export interface DiscordUserPayload { + /** The user's id */ + id: string; + /** the user's username, not unique across the platform */ + username: string; + /** The user's 4 digit discord tag */ + discriminator: string; + /** The user's avatar hash */ + avatar: string | null; + /** Whether the user is a bot */ + bot?: boolean; + /** Whether the user is an official discord system user (part of the urgent message system.) */ + system?: boolean; + /** Whether the user has two factor enabled on their account */ + "mfa_enabled"?: boolean; + /** the user's chosen language option */ + locale?: string; + /** Whether the email on this account has been verified */ + verified?: boolean; + /** The user's email */ + email?: string; + /** The flags on a user's account. */ + flags?: number; + /** The type of Nitro subscription on a user's account. */ + premium_type?: number; +} +``` + +To create the Discordeno version for this it would be done as: + +```ts +export interface UserPayload extends Camelize {} +``` + +Now we have 2 unique interfaces, without having all the extra work or headaches +of maintaing 2 different interfaces. + +Similarily, for any outgoing Discord types, we can also camelize them to have +better user experience for users. + +Example: + +```ts +export interface DiscordBanOptions { + /** number of days to delete messages for (0-7) */ + delete_message_days?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; + /** The reason for the ban. */ + reason?: string; +} +``` + +To create the Discordeno version for this it would be done as: + +```ts +export interface BanOptions extends Camelize {} +``` diff --git a/src/types/api/auditlog.ts b/src/types/api/auditlog.ts new file mode 100644 index 000000000..a2047f362 --- /dev/null +++ b/src/types/api/auditlog.ts @@ -0,0 +1,205 @@ +import { + DiscordIntegration, + DiscordOverwrite, + DiscordRole, + DiscordUser, + DiscordWebhook, +} from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-object */ +export interface DiscordAuditLogPayload { + /** list of webhooks found in the audit log */ + webhooks: DiscordWebhook[]; + /** list of users found in the audit log */ + users: DiscordUser[]; + /** list of audit log entries */ + audit_log_entries: DiscordAuditLogEntry[]; + /** list of partial integration objects */ + integrations: Partial[]; +} + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-entry-structure */ +export interface DiscordAuditLogEntry { + /** id of the affected entity (webhook, user, role, etc.) */ + target_id: string | null; + /** changes made to the target_id */ + changes?: DiscordAuditLogChange[]; + /** the user who made the changes */ + user_id: string; + /** id of the entry */ + id: string; + /** type of action that occured */ + action_type: DiscordAuditLogEvent; + /** additional info for certain action types */ + options?: DiscordOptionalAuditEntryInfoParam; + /** the reason for the change (0-512 characters) */ + reason?: string; +} + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events */ +export enum DiscordAuditLogEvent { + GUILD_UPDATE = 1, + CHANNEL_CREATE = 10, + CHANNEL_UPDATE, + CHANNEL_DELETE, + CHANNEL_OVERWRITE_CREATE, + CHANNEL_OVERWRITE_UPDATE, + CHANNEL_OVERWRITE_DELETE, + MEMBER_KICK = 20, + MEMBER_PRUNE, + MEMBER_BAN_ADD, + MEMBER_BAN_REMOVE, + MEMBER_UPDATE, + MEMBER_ROLE_UPDATE, + MEMBER_MOVE, + MEMBER_DISCONNECT, + BOT_ADD, + ROLE_CREATE = 30, + ROLE_UPDATE, + ROLE_DELETE, + INVITE_CREATE = 40, + INVITE_UPDATE, + INVITE_DELETE, + WEBHOOK_CREATE = 50, + WEBHOOK_UPDATE, + WEBHOOK_DELETE, + EMOJI_CREATE = 60, + EMOJI_UPDATE, + EMOJI_DELETE, + MESSAGE_DELETE = 72, + MESSAGE_BULK_DELETE, + MESSAGE_PIN, + MESSAGE_UNPIN, + INTEGRATION_CREATE = 80, + INTEGRATION_UPDATE, + INTEGRATION_DELETE, +} + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info */ +export interface DiscordOptionalAuditEntryInfoParam { + /** number of days after which inactive members were kicked, type: MEMBER_PRUNE */ + delete_member_days: string; + /** number of members removed by the prune, type: MEMBER_PRUNE */ + members_removed: string; + /** channel in which the entities were targeted, types: MEMBER_MOVE & MESSAGE_PIN & MESSAGE_UNPIN & MESSAGE_DELETE */ + channel_id: string; + /** id of the message that was targeted, types: MESSAGE_PIN & MESSAGE_UNPIN */ + message_id: string; + /** number of entities that were targeted, types: MESSAGE_DELETE & MESSAGE_BULK_DELETE & MEMBER_DISCONNECT & MEMBER_MOVE */ + count: string; + /** id of the overwritten entity, types CHANNEL_OVERWRITE_CREATE & CHANNEL_OVERWRITE_UPDATE & CHANNEL_OVERWRITE_DELETE */ + id: string; + /** type of overwritten entity - "0", for "role", or "1" for "member", types: CHANNEL_OVERWRITE_CREATE & CHANNEL_OVERWRITE_UPDATE & CHANNEL_OVERWRITE_DELETE */ + type: string; + /** name of the role if type is "0" (not present if type is "1"), types: CHANNEL_OVERWRITE_CREATE & CHANNEL_OVERWRITE_UPDATE & CHANNEL_OVERWRITE_DELETE */ + role_name: string; +} + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure */ +export interface DiscordAuditLogChange { + /** new value of the key */ + new_value?: DiscordAuditLogChangeValue; + /** old value of the key */ + old_value?: DiscordAuditLogChangeValue; + /** name of audit log change key */ + key: string; +} + +/** https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure */ +export type DiscordAuditLogChangeValue = + | { + new_value: string; + old_value: string; + key: + | "name" + | "icon_hash" + | "splash_hash" + | "owner_id" + | "region" + | "afk_channel_id" + | "vanity_url_code" + | "widget_channel_id" + | "system_channel_id" + | "topic" + | "application_id" + | "permissions" + | "allow" + | "deny" + | "code" + | "channel_id" + | "inviter_id" + | "nick" + | "avatar_hash" + | "id"; + } + | { + new_value: number; + old_value: number; + key: + | "afk_timeout" + | "mfa_level" + | "verification_level" + | "explicit_content_filter" + | "default_messagae_notifications" + | "prune_delete_days" + | "position" + | "bitrate" + | "rate_limit_per_user" + | "color" + | "max_uses" + | "uses" + | "max_age" + | "expire_behavior" + | "expire_grace_period"; + } + | { + new_value: Partial; + old_value: Partial; + key: "$add" | "$remove"; + } + | { + new_value: boolean; + old_value: boolean; + key: + | "widget_enabled" + | "nsfw" + | "hoist" + | "mentionable" + | "temporary" + | "deaf" + | "mute" + | "enable_emoticons"; + } + | { + new_value: DiscordOverwrite[]; + old_value: DiscordOverwrite[]; + key: "permission_overwrites"; + } + | { + new_value: string | number; + old_value: string | number; + key: "type"; + }; + +/** https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log-query-string-parameters */ +export interface DiscordGetGuildAuditLogParams { + /** filter the log for actions made by a user */ + user_id: string; + /** the type of audit log event */ + action_type: DiscordAuditLogEvent; + /** filter the log before a certain entry id */ + before: string; + /** how many entries are returned (default 50, minimum 1, maximum 100) */ + limit: number; +} + +export interface DiscordGetAuditLogsOptions { + /** Filter the logs for actions made by this user. */ + user_id?: string; + /** The type of audit log. */ + action_type?: DiscordAuditLogEvent; + /** Filter the logs before a certain log entry. */ + before?: string; + /** How many entries are returned. Between 1-100. Default 50. */ + limit?: number; +} diff --git a/src/types/api/channel.ts b/src/types/api/channel.ts new file mode 100644 index 000000000..31b7f79fc --- /dev/null +++ b/src/types/api/channel.ts @@ -0,0 +1,107 @@ +import { DiscordOverwrite, DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/channel#channel-object-channel-types */ +export enum DiscordChannelTypes { + /** a text channel within a server */ + GUILD_TEXT, + /** a direct message between users */ + DM, + /** a voice channel within a server */ + GUILD_VOICE, + /** a direct message between multiple users */ + GROUP_DM, + /** an organizational category that contains up to 50 channels */ + GUILD_CATEGORY, + /** a channel that users can follow and crosspost into their own server */ + GUILD_NEWS, + /** a channel in which game developers can sell their game on Discord */ + GUILD_STORE, +} + +/** https://discord.com/developers/docs/resources/channel#channel-object-channel-structure */ +export interface DiscordChannel { + /** the id of this channel */ + id: string; + /** the type of channel */ + type: DiscordChannelTypes; + /** the id of the guild */ + guild_id?: string; + /** sorting position of the channel */ + position?: number; + /** explicit permission overwrites for members and roles */ + permission_overwrites?: DiscordOverwrite[]; + /** the name of the channel (2-100 characters) */ + name?: string; + /** the channel topic (0-1024 characters) */ + topic?: string | null; + /** whether the channel is nsfw */ + nsfw?: boolean; + /** the id of the last message sent in this channel (may not point to an existing or valid message) */ + last_message_id?: string | null; + /** the bitrate (in bits) of the voice channel */ + bitrate?: number; + /** the user limit of the voice channel */ + user_limit?: number; + /** amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages or manage_channel, are unaffected */ + rate_limit_per_user?: number; + /** the recipients of the DM */ + recipients?: DiscordUser[]; + /** icon hash */ + icon?: string | null; + /** id of the DM creator */ + owner_id?: string; + /** application id of the group DM creator if it is bot-created */ + application_id?: string; + /** id of the parent category for a channel (each parent category can contain up to 50 channels) */ + parent_id?: string | null; + /** when the last pinned message was pinned. This may be null in events such as GUILD_CREATE when a message is not pinned. */ + last_pin_timestamp?: string | null; +} + +/** https://discord.com/developers/docs/resources/channel#followed-channel-object-followed-channel-structure */ +export interface DiscordFollowedChannel { + /** source channel id */ + channel_id: string; + /** created target webhook id */ + webhook_id: string; +} + +/** https://discord.com/developers/docs/resources/channel#modify-channel-json-params */ +export interface DiscordModifyChannelParams { + /** 2-100 character channel name */ + name?: string; + /** the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature */ + type?: DiscordChannelTypes; + /** the position of the channel in the left-hand listing */ + position?: number | null; + /** 0-1024 character channel topic */ + topic?: string | null; + /** whether the channel is nsfw */ + nsfw?: boolean | null; + /** amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected */ + rate_limit_per_user?: number | null; + /** the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers) */ + bitrate?: number | null; + /** the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit */ + user_limit?: number | null; + /** channel or category-specific permissions */ + permission_overwrites?: DiscordOverwrite[] | null; + /** id of the new parent category for a channel */ + parent_id?: string | null; +} + +/** https://discord.com/developers/docs/resources/channel#edit-channel-permissions-json-params */ +export interface DiscordEditChannelPermissions { + /** the bitwise value of all allowed permissions */ + allow: string; + /** the bitwise value of all disallowed permissions */ + deny: string; + /** 0 for a role or 1 for a member */ + type: number; +} + +/** https://discord.com/developers/docs/resources/channel#follow-news-channel-json-params */ +export interface DiscordFollowNewsChannelParams { + /** id of target channel */ + webhook_channel_id: string; +} diff --git a/src/types/api/code.ts b/src/types/api/code.ts new file mode 100644 index 000000000..db12b5de4 --- /dev/null +++ b/src/types/api/code.ts @@ -0,0 +1,188 @@ +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#opcodes-and-status-codes */ +export enum DiscordGatewayOpcodes { + Dispatch, + Heartbeat, + Identify, + PresenceUpdate, + VoiceStateUpdate, + Resume = 6, + Reconnect, + RequestGuildMembers, + InvalidSession, + Hello, + HeartbeatACK, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#opcodes-and-status-codes */ +export enum DiscordGatewayCloseEventCodes { + UnknownError = 4000, + UnknownOpcode, + DecodeError, + NotAuthenticated, + AuthenticationFailed, + AlreadyAuthenticated, + InvalidSeq = 4007, + RateLimited, + SessionTimedOut, + InvalidShard, + ShardingRequired, + InvalidApiVersion, + InvalidIntents, + DisallowedIntents, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice */ +export enum DiscordVoiceOpcodes { + Identify, + SelectProtocol, + Ready, + Heartbeat, + SessionDescription, + Speaking, + HeartbeatACK, + Resume, + Hello, + Resumed, + ClientDisconnect = 13, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice */ +export enum DiscordVoiceCloseEventCodes { + UnknownOpcode = 4001, + FailedToDecodePayload, + NotAuthenticated, + AuthenticationFailed, + AlreadyAuthenticated, + SessionNoLongerValid, + SessionTimedOut = 4009, + ServerNotFound = 4011, + UnknownProtocol, + Disconnect = 4014, + VoiceServerCrashed, + UnknownEncryptionMode, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#http */ +export enum DiscordHTTPResponseCodes { + Ok = 200, + Created, + NoContent = 204, + NotModified = 304, + BadRequest = 400, + Unauthorized, + Forbidden = 403, + NotFound, + MethodNotAllowed, + TooManyRequests = 429, + GatewayUnavailable = 502, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#json */ +export enum DiscordJsonErrorCodes { + GeneralError, + UnknownAccount = 10001, + UnknownApplication, + UnknownChannel, + UnknownGuild, + UnknownIntegration, + UnknownInvite, + UnknownMember, + UnknownMessage, + UnknownPermissionOverwrite, + UnknownProvider, + UnknownRole, + UnknownToken, + UnknownUser, + UnknownEmoji, + UnknownWebhook, + UnknownBan = 10026, + UnknownSKU, + UnknownStoreListing, + UnknownEntitlement, + UnknownBuild, + UnknownLobby, + UnknownBranch, + UnknownRedistributable = 10036, + UnknownGuildTemplate = 10057, + UnknownApplicationCommand = 10063, + BotsCannotUseThisEndpoint = 20001, + OnlyBotsCanUseThisEndpoint, + ThisMessageCannotBeEditedDueToAnnouncementRateLimits = 20022, + TheChannelYouAreWritingHasHitTheWriteRateLimit = 20028, + MaximumNumberOfGuildsReached = 30001, + MaximumNumberOfFriendsReached, + MaximumNumberOfPinsReachedForTheChannel, + MaximumNumberOfGuildRolesReached = 30005, + MaximumNumberOfWebhooksReached = 30007, + MaximumNumberOfReactionsReached = 30010, + MaximumNumberOfGuildChannelsReached = 30013, + MaximumNumberOfAttachmentsInAMessageReached = 30015, + MaximumNumberOfInvitesReached, + GuildAlreadyHasTemplate = 30031, + UnauthorizedProvideAValidTokenAndTryAgain = 40001, + YouNeedToVerifyYourAccountInOrderToPerformThisAction, + RequestEntityTooLargeTrySendingSomethingSmallerInSize = 40005, + ThisFeatureHasBeenTemporarilyDisabledServerSide, + ThisUserBannedFromThisGuild, + ThisMessageHasAlreadyBeenCrossposted = 40033, + MissingAccess = 50001, + InvalidAccountType, + CannotExecuteActionOnADMChannel, + GuildWidgetDisabled, + CannotEditMessageAuthoredByAnotherUser, + CannotSendAnEmptyMessage, + CannotSendMessagesToThisUser, + CannotSendMessagesInAVoiceChannel, + ChannelVerificationLevelIsTooHighForYouToGainAccess, + Oauth2ApplicationDoesNotHaveABot, + Oauth2ApplicationLimitReached, + InvalidOauth2State, + YouLackPermissionsToPerformThatAction, + InvalidAuthenticationTokenProvided, + NoteWasTooLong, + ProvidedTooFewOrTooManyMessagesToDeleteMustProvideAtLeast2AndFewerThan100MessagesToDelete, + AMessageCanOnlyBePinnedInTheChannelItWasSentIn = 50019, + InviteCodeWasEitherInvalidOrTaken, + CannotExecuteActionOnASystemMessage, + CannotExecuteActionOnThisChannelType = 50024, + InvalidOauth2AccessTokenProvided, + InvalidRecipients = 50033, + AMessageProvidedWasTooOldToBulkDelete, + InvalidFormBodyOrContentTypeProvided, + AnInviteWasAcceptedToAGuildTheApplicationsBotIsNotIn, + InvalidApiVersionProvided = 50041, + CannotDeleteAChannelRequiredForCommunityGuilds = 50074, + InvalidStickerSent = 50081, + ReqctionWasBlocked = 90001, + ApiResourceIsCurrentlyOverloadedTryAgainALittleLater = 130000, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */ +export enum DiscordRpcErrorCodes { + UnknownError = 1000, + InvalidPayload = 4000, + InvalidCommand = 4002, + InvalidGuild, + InvalidEvent, + InvalidChannel, + InvalidPermissions, + InvalidClientID, + InvalidOrigin, + InvalidToken, + InvalidUser, + OAuth2Error = 5000, + SelectChannelTimedOut, + GetGuildTimedOut, + SelectVoiceForceRequired, + CaptureShortcutAlreadyListening, +} + +/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */ +export enum DiscordRpcCloseEventCodes { + InvalidClientID = 4000, + InvalidOrigin, + RateLimited, + TokenRevoked, + InvalidVersion, + InvalidEncoding, +} diff --git a/src/types/api/embed.ts b/src/types/api/embed.ts new file mode 100644 index 000000000..2188c3c11 --- /dev/null +++ b/src/types/api/embed.ts @@ -0,0 +1,115 @@ +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-structure */ +export interface DiscordEmbed { + /** title of embed */ + title?: string; + /** type of embed (always "rich" for webhook embeds) */ + type?: string; + /** description of embed */ + description?: string; + /** url of embed */ + url?: string; + /** timestamp of embed content */ + timestamp?: string; + /** color code of the embed */ + color?: number; + /** footer information */ + footer?: DiscordEmbedFooter; + /** image information */ + image?: DiscordEmbedImage; + /** thumbnail information */ + thumbnail?: DiscordEmbedThumbnail; + /** video information */ + video?: DiscordEmbedVideo; + /** provider information */ + provider?: DiscordEmbedProvider; + /** author information */ + author?: DiscordEmbedAuthor; + /** fields information */ + fields?: DiscordEmbedField[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-types + * @deprecated + */ +export type EmbedTypes = + | "rich" + | "image" + | "video" + | "gifv" + | "article" + | "link"; + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure */ +export interface DiscordEmbedThumbnail { + /** source url of thumbnail (only supports http(s) and attachments) */ + url?: string; + /** a proxied url of the thumbnail */ + proxy_url?: string; + /** height of thumbnail */ + height?: number; + /** width of thumbnail */ + width?: number; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure */ +export interface DiscordEmbedVideo { + /** source url of video */ + url?: string; + /** height of video */ + height?: number; + /** width of video */ + width?: number; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure */ +export interface DiscordEmbedImage { + /** source url of image (only supports http(s) and attachments) */ + url?: string; + /** a proxied url of the image */ + proxy_url?: string; + /** height of image */ + height?: number; + /** width of image */ + width?: number; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure */ +export interface DiscordEmbedProvider { + /** name of provider */ + name?: string; + /** url of provider */ + url?: string; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure */ +export interface DiscordEmbedAuthor { + /** name of author */ + name?: string; + /** url of author */ + url?: string; + /** url of author icon (only supports http(s) and attachments) */ + icon_url?: string; + /** a proxied url of author icon */ + proxy_icon_url?: string; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure */ +export interface DiscordEmbedFooter { + /** footer text */ + text: string; + /** url of footer icon (only supports http(s) and attachments) */ + icon_url?: string; + /** a proxied url of footer icon */ + proxy_icon_url?: string; +} + +/** https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure */ +export interface DiscordEmbedField { + /** name of the field */ + name: string; + /** value of the field */ + value: string; + /** whether or not this field should display inline */ + inline?: boolean; +} diff --git a/src/types/api/emoji.ts b/src/types/api/emoji.ts new file mode 100644 index 000000000..6a8943da6 --- /dev/null +++ b/src/types/api/emoji.ts @@ -0,0 +1,39 @@ +import { DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure */ +export interface DiscordEmoji { + /** emoji id */ + id: string | null; + /** emoji name */ + name: string | null; + /** roles this emoji is whitelisted to */ + roles?: string[]; + /** user that created this emoji */ + user?: DiscordUser; + /** whether this emoji must be wrapped in colons */ + require_colons?: boolean; + /** whether this emoji is managed */ + managed?: boolean; + /** whether this emoji is animated */ + animated?: boolean; + /** whether this emoji can be used, may be false due to loss of Server Boosts */ + available?: boolean; +} + +/** https://discord.com/developers/docs/resources/emoji#create-guild-emoji */ +export interface DiscordCreateGuildEmojiParams { + /** name of the emoji */ + name: string; + /** the 128x128 emoji image (Data URI scheme) */ + image: string; + /** roles for which this emoji will be whitelisted */ + roles: string[]; +} + +/** https://discord.com/developers/docs/resources/emoji#modify-guild-emoji */ +export interface DiscordModifyGuildEmojiParams { + /** name of the emoji */ + name?: string; + /** roles to which this emoji will be whitelisted */ + roles?: string[] | null; +} diff --git a/src/types/api/event.ts b/src/types/api/event.ts new file mode 100644 index 000000000..38c8bc0bf --- /dev/null +++ b/src/types/api/event.ts @@ -0,0 +1,350 @@ +import { + DiscordActivity, + DiscordApplication, + DiscordClientStatus, + DiscordEmoji, + DiscordIntegration, + DiscordMember, + DiscordRole, + DiscordStatusTypes, + DiscordUnavailableGuild, + DiscordUser, +} from "./mod.ts"; + +/** https://discord.com/developers/docs/topics/gateway#hello */ +export interface DiscordHelloEvent { + /** the interval (in milliseconds) the client should heartbeat with */ + heartbeat_interval: number; +} + +/** https://discord.com/developers/docs/topics/gateway#ready */ +export interface DiscordReadyEvent { + /** gateway version */ + v: number; + /** information about the user including email */ + user: DiscordUser; + /** empty array */ + private_channels: []; + /** the guilds the user is in */ + guilds: DiscordUnavailableGuild[]; + /** used for resuming connections */ + session_id: string; + /** the shard information associated with this session, if sent when identifying */ + shard?: [number, number]; + /** contains id and flags */ + application: Pick; +} + +/** https://discord.com/developers/docs/topics/gateway#channel-pins-update-channel-pins-update-event-fields */ +export interface DiscordChannelPinsUpdateEvent { + /** the id of the guild */ + guild_id?: string; + /** the id of the channel */ + channel_id: string; + /** the time at which the most recent pinned message was pinned */ + last_pin_timestamp?: string | null; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-ban-add-guild-ban-add-event-fields */ +export interface DiscordGuildBanAddEvent { + /** id of the guild */ + guild_id: string; + /** the banned user */ + user: DiscordUser; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-ban-remove-guild-ban-remove-event-fields */ +export interface DiscordGuildBanRemoveEvent { + /** id of the guild */ + guild_id: string; + /** the unbanned user */ + user: DiscordUser; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-emojis-update-guild-emojis-update-event-fields */ +export interface DiscordGuildEmojisUpdateEvent { + /** id of the guild */ + guild_id: string; + /** array of emojis */ + emojis: DiscordEmoji[]; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-integrations-update-guild-integrations-update-event-fields */ +export interface DiscordGuildIntegrationsUpdateEvent { + /** id of the guild whose integrations were updated */ + guild_id: string; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-member-add-guild-member-add-extra-fields */ +export interface DiscordGuildMemberAddExtra extends DiscordMember { + /** id of the guild */ + guild_id: string; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-member-remove-guild-member-remove-event-fields */ +export interface DiscordGuildMemberRemoveEvent { + /** the id of the guild */ + guild_id: string; + /** the user who was removed */ + user: DiscordUser; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-member-update-guild-member-update-event-fields */ +export interface DiscordGuildMemberUpdateEvent { + /** the id of the guild */ + guild_id: string; + /** user role ids */ + roles: string[]; + /** the user */ + user: DiscordUser; + /** nickname of the user in the guild */ + nick?: string | null; + /** when the user joined the guild */ + joied_at: string; + /** when the user starting boosting the guild */ + premium_since?: string | null; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-members-chunk-guild-members-chunk-event-fields */ +export interface DiscordGuildMembersChunkEvent { + /** the id of the guild */ + guild_id: string; + /** set of guild members */ + members: DiscordMember[]; + /** the chunk index in the expected chunks for this response (0 <= chunk_index < chunk_count) */ + chunk_index: number; + /** the total number of expected chunks for this response */ + chunk_count: number; + /** if passing an invalid id to REQUEST_GUILD_MEMBERS, it will be returned here */ + not_found?: []; + /** if passing true REQUEST_GUILD_MEMBERS, presences of the returned members will be here */ + presences?: DiscordPresenceUpdateEvent[]; + /** the nonce used in the Guild Members Request */ + nonce?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-role-create-guild-role-create-event-fields */ +export interface DiscordGuildRoleCreateEvent { + /** the id of the guild */ + guild_id: string; + /** the role created */ + role: DiscordRole; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-role-update-guild-role-update-event-fields */ +export interface DiscordGuildRoleUpdateEvent { + /** the id of the guild */ + guild_id: string; + /** the role updated */ + role: DiscordRole; +} + +/** https://discord.com/developers/docs/topics/gateway#guild-role-delete-guild-role-delete-event-fields */ +export interface DiscordGuildRoleDeleteEvent { + /** id of the guild */ + guild_id: string; + /** id of the role */ + role_id: string; +} + +// TODO: Add the documentation Link +export interface DiscordIntegrationCreate extends DiscordIntegration { + /** id of the guild */ + guild_id: string; +} + +export interface DiscordIntegrationUpdate extends DiscordIntegration { + /** id of the guild */ + guild_id: string; +} + +export interface DiscordIntegrationDelete { + /** integration id */ + id: string; + /** id of the guild */ + guild_id: string; + /** id of the bot/OAuth2 application for this discordd integration */ + application_id?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#invite-create-invite-create-event-fields */ +export interface DiscordInviteCreateEvent { + /** the channel the invite is for */ + channel_id: string; + /** the unique invite code */ + code: string; + /** the time at which the invite was created */ + created_at: string; + /** the guild of the invite */ + guild_id?: string; + /** the user that created the invite */ + inviter?: DiscordUser; + /** how long the invite is valid for (in seconds) */ + max_age: number; + /** the maximum number of times the invite can be used */ + max_uses: number; + /** the target user for this invite */ + target_user?: Partial; + /** the type of user target for this invite */ + target_user_type?: number; + /** whether or not the invite is temporary (invited users will be kicked on disconnect unless they're assigned a role) */ + temporary: boolean; + /** how many times the invite has been used (always will be 0) */ + uses: number; +} + +/** https://discord.com/developers/docs/topics/gateway#invite-delete-invite-delete-event-fields */ +export interface DiscordInviteDeleteEvent { + /** the channel of the invite */ + channel_id: string; + /** the guild of the invite */ + guild_id?: string; + /** the unique invite code */ + code: string; +} + +/** https://discord.com/developers/docs/topics/gateway#message-delete-message-delete-event-fields */ +export interface DiscordMessageDeleteEvent { + /** the id of the message */ + id: string; + /** the id of the channel */ + channel_id: string; + /** the id of the guild */ + guild_id?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#message-delete-bulk-message-delete-bulk-event-fields */ +export interface DiscordMessageDeleteBulkEvent { + /** the ids of the messages */ + ids: string[]; + /** the id of the channel */ + channel_id: string; + /** the id of the guild */ + guild_id?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#message-reaction-add-message-reaction-add-event-fields */ +export interface DiscordMessageReactionAddEvent { + /** the id of the user */ + user_id: string; + /** the id of the channel */ + channel_id: string; + /** the id of the message */ + message_id: string; + /** the id of the guild */ + guild_id?: string; + /** the member who reacted if this happened in a guild */ + member?: DiscordMember; + /** the emoji used to react */ + emoji: Partial; +} + +/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-message-reaction-remove-event-fields */ +export interface DiscordMessageReactionRemoveEvent { + /** the id of the user */ + user_id: string; + /** the id of the channel */ + channel_id: string; + /** the id of the message */ + message_id: string; + /** the id of the guild */ + guild_id?: string; + /** the emoji used to react */ + emoji: Partial; +} + +/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all-message-reaction-remove-all-event-fields */ +export interface DiscordMessageReactionRemoveAllEvent { + /** the id of the channel */ + channel_id: string; + /** the id of the message */ + message_id: string; + /** the id of the guild */ + guild_id?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji-message-reaction-remove-emoji */ +export interface DiscordMessageReactionRemoveEmoji { + /** the id of the channel */ + channel_id: string; + /** the id of the guild */ + guild_id?: string; + /** the id of the message */ + message_id: string; + /** the emoji that was removed */ + emoji: Partial; +} + +/** https://discord.com/developers/docs/topics/gateway#presence-update-presence-update-event-fields */ +export interface DiscordPresenceUpdateEvent { + /** the user presence is being updated for */ + user: DiscordUser; + /** id of the guild */ + guild_id: string; + /** either "idle", "dnd", "online", or "offline" */ + status: DiscordStatusTypes; + /** user's current activities */ + activities: DiscordActivity[]; + /** user's platform-dependent status */ + client_status: DiscordClientStatus; +} + +/** https://discord.com/developers/docs/topics/gateway#typing-start-typing-start-event-fields */ +export interface DiscordTypingStartEvent { + /** id of the channel */ + channel_id: string; + /** id of the guild */ + guild_id?: string; + /** id of the user */ + user_id: string; + /** unix time (in seconds) of when the user started typing */ + timestamp: number; + /** the member who started typing if this happened in a guild */ + member?: DiscordMember; +} + +/** https://discord.com/developers/docs/topics/gateway#voice-server-update-voice-server-update-event-fields */ +export interface DiscordVoiceServerUpdateEvent { + /** voice connection token */ + token: string; + /** the guildd this voice server update is for */ + guild_id: string; + /** the voice server host */ + endpoint: string; +} + +/** https://discord.com/developers/docs/topics/gateway#webhooks-update-webhook-update-event-fields */ +export interface DiscordWebhooksUpdateEvent { + /** id of the guild */ + guild_id: string; + /** id of the channel */ + channel_id: string; +} + +/** https://discord.com/developers/docs/resources/voice#voice-resource */ +export interface DiscordVoiceStateUpdateEvent { + /** the guild id this voice state is for */ + guild_id?: string; + /** the channel id this user is connected to */ + channel_id: string; + /** the user id this voice state is for */ + user_id: string; + /** the guild member this voice state is for */ + member?: DiscordMember; + /** the session id for this voice state */ + session_id: string; + /** whether this user is deafened by the server */ + deaf: boolean; + /** whether this user is muted by the server */ + mute: boolean; + /** whether this user is locally deafened */ + self_deaf: boolean; + /** whether this user is locally muted */ + self_mute: boolean; + /** whether this user is streaming using "Go Live" */ + self_stream?: boolean; + /** whether this user's camera is enabled */ + self_video: boolean; + /** whether this user is muted by the current user */ + suppress: boolean; +} diff --git a/src/types/api/gateway.ts b/src/types/api/gateway.ts new file mode 100644 index 000000000..cfe4864be --- /dev/null +++ b/src/types/api/gateway.ts @@ -0,0 +1,487 @@ +import { DiscordInteractionCommand } from "./interaction.ts"; +import { + DiscordChannel, + DiscordChannelPinsUpdateEvent, + DiscordGatewayOpcodes, + DiscordGuild, + DiscordGuildBanAddEvent, + DiscordGuildBanRemoveEvent, + DiscordGuildEmojisUpdateEvent, + DiscordGuildIntegrationsUpdateEvent, + DiscordGuildMemberAddExtra, + DiscordGuildMemberRemoveEvent, + DiscordGuildMembersChunkEvent, + DiscordGuildMemberUpdateEvent, + DiscordGuildRoleCreateEvent, + DiscordGuildRoleDeleteEvent, + DiscordGuildRoleUpdateEvent, + DiscordHelloEvent, + DiscordIntegrationCreate, + DiscordIntegrationDelete, + DiscordIntegrationUpdate, + DiscordInviteCreateEvent, + DiscordInviteDeleteEvent, + DiscordMember, + DiscordMessage, + DiscordMessageDeleteBulkEvent, + DiscordMessageDeleteEvent, + DiscordMessageReactionAddEvent, + DiscordMessageReactionRemoveAllEvent, + DiscordMessageReactionRemoveEmoji, + DiscordMessageReactionRemoveEvent, + DiscordPresenceUpdateEvent, + DiscordReadyEvent, + DiscordTypingStartEvent, + DiscordUnavailableGuild, + DiscordUser, + DiscordVoiceServerUpdateEvent, + DiscordVoiceStateUpdateEvent, + DiscordWebhooksUpdateEvent, +} from "./mod.ts"; + +/** https://discord.com/developers/docs/topics/gateway#payloads */ +export interface DiscordGateway { + /** opcode for the payload */ + op: DiscordGatewayOpcodes; + /** event data */ + d: DiscordGatewayDTypes; + /** sequence number, used for resuming sessions and heartbeats */ + s: number | null; + /** the event name for this payload */ + t: DiscordGatewayTTypes; +} + +/** GatewayPayload event data type list */ +export type DiscordGatewayDTypes = + | DiscordHelloEvent + | DiscordReadyEvent + | DiscordResume + | DiscordChannel + | DiscordChannelPinsUpdateEvent + | DiscordGuild + | DiscordUnavailableGuild + | DiscordGuildBanAddEvent + | DiscordGuildBanRemoveEvent + | DiscordGuildEmojisUpdateEvent + | DiscordGuildIntegrationsUpdateEvent + | DiscordMember + | DiscordGuildMemberAddExtra + | DiscordGuildMemberRemoveEvent + | DiscordGuildMemberUpdateEvent + | DiscordGuildMembersChunkEvent + | DiscordGuildRoleCreateEvent + | DiscordGuildRoleUpdateEvent + | DiscordGuildRoleDeleteEvent + | DiscordIntegrationCreate + | DiscordIntegrationUpdate + | DiscordIntegrationDelete + | DiscordInviteCreateEvent + | DiscordInviteDeleteEvent + | DiscordMessage + | DiscordMessageDeleteEvent + | DiscordMessageDeleteBulkEvent + | DiscordMessageReactionAddEvent + | DiscordMessageReactionRemoveEvent + | DiscordMessageReactionRemoveAllEvent + | DiscordMessageReactionRemoveEmoji + | DiscordPresenceUpdateEvent + | DiscordTypingStartEvent + | DiscordUser + | DiscordVoiceStateUpdateEvent + | DiscordVoiceServerUpdateEvent + | DiscordWebhooksUpdateEvent + | DiscordInteractionCommand + | false + | null; + +/** GatewayPayload event name list */ +export type DiscordGatewayTTypes = + | "HELLO" + | "READY" + | "RESUMED" + | "RECONNECT" + | "INVALID_SESSION" + | "CHANNEL_CREATE" + | "CHANNEL_UPDATE" + | "CHANNEL_DELETE" + | "CHANNEL_PINS_UPDATE" + | "GUILD_CREATE" + | "GUILD_UPDATE" + | "GUILD_DELETE" + | "GUILD_BAN_ADD" + | "GUILD_BAN_REMOVE" + | "GUILD_EMOJIS_UPDATE" + | "GUILD_INTEGRATIONS_UPDATE" + | "GUILD_MEMBER_ADD" + | "GUILD_MEMBER_REMOVE" + | "GUILD_MEMBER_UPDATE" + | "GUILD_MEMBERS_CHUNK" + | "GUILD_ROLE_CREATE" + | "GUILD_ROLE_UPDATE" + | "GUILD_ROLE_DELETE" + | "INTEGRATION_CREATE" + | "INTEGRATION_UPDATE" + | "INTEGRATION_DELETE" + | "INVITE_CREATE" + | "INVITE_DELETE" + | "MESSAGE_CREATE" + | "MESSAGE_UPDATE" + | "MESSAGE_DELETE" + | "MESSAGE_DELETE_BULK" + | "MESSAGE_REACTION_ADD" + | "MESSAGE_REACTION_REMOVE" + | "MESSAGE_REACTION_REMOVE_ALL" + | "MESSAGE_REACTION_REMOVE_EMOJI" + | "PRESENCE_UPDATE" + | "TYPING_START" + | "USER_UPDATE" + | "VOICE_STATE_UPDATE" + | "VOICE_SERVER_UPDATE" + | "WEBHOOKS_UPDATE" + | "INTERACTION_CREATE" + // Not in DC documentation + | "APPLICATION_COMMAND_CREATE" + | null; + +/** https://discord.com/developers/docs/topics/gateway#connecting-to-the-gateway */ +export interface DiscordGatewayURLParams { + /** gateway Version to use */ + v: number; + /** the encoding of recieved gateway packets */ + encoding: string; + /** the (optional) compression of gateway packets */ + compress?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#gateway-intents */ +export enum DiscordGatewayIntents { + /** Enables the following events: + * - GUILD_CREATE + * - GUILD_DELETE + * - GUILD_ROLE_CREATE + * - GUILD_ROLE_UPDATE + * - GUILD_ROLE_DELETE + * - CHANNEL_CREATE + * - CHANNEL_UPDATE + * - CHANNEL_DELETE + * - CHANNEL_PINS_UPDATE + */ + GUILDS = 1 << 0, + /** Enables the following events: + * - GUILD_MEMBER_ADD + * - GUILD_MEMBER_UPDATE + * - GUILD_MEMBER_REMOVE + */ + GUILD_MEMBERS = 1 << 1, + /** Enables the following events: + * - GUILD_BAN_ADD + * - GUILD_BAN_REMOVE + */ + GUILD_BANS = 1 << 2, + /** Enables the following events: + * - GUILD_EMOJIS_UPDATE + */ + GUILD_EMOJIS = 1 << 3, + /** Enables the following events: + * - GUILD_INTEGRATIONS_UPDATE + * - INTEGRATION_CREATE + * - INTEGRATION_UPDATE + * - INTEGRATION_DELETE + */ + GUILD_INTEGRATIONS = 1 << 4, + /** Enables the following events: + * - WEBHOOKS_UPDATE + */ + GUILD_WEBHOOKS = 1 << 5, + /** Enables the following events: + * - INVITE_CREATE + * - INVITE_DELETE + */ + GUILD_INVITES = 1 << 6, + /** Enables the following events: + * - VOICE_STATE_UPDATE + */ + GUILD_VOICE_STATES = 1 << 7, + /** Enables the following events: + * - PRESENCE_UPDATE + */ + GUILD_PRESENCES = 1 << 8, + /** Enables the following events: + * - MESSAGE_CREATE + * - MESSAGE_UPDATE + * - MESSAGE_DELETE + */ + GUILD_MESSAGES = 1 << 9, + /** Enables the following events: + * - MESSAGE_REACTION_ADD + * - MESSAGE_REACTION_REMOVE + * - MESSAGE_REACTION_REMOVE_ALL + * - MESSAGE_REACTION_REMOVE_EMOJI + */ + GUILD_MESSAGE_REACTIONS = 1 << 10, + /** Enables the following events: + * - TYPING_START + */ + GUILD_MESSAGE_TYPING = 1 << 11, + /** Enables the following events: + * - CHANNEL_CREATE + * - MESSAGE_CREATE + * - MESSAGE_UPDATE + * - MESSAGE_DELETE + * - CHANNEL_PINS_UPDATE + */ + DIRECT_MESSAGES = 1 << 12, + /** Enables the following events: + * - MESSAGE_REACTION_ADD + * - MESSAGE_REACTION_REMOVE + * - MESSAGE_REACTION_REMOVE_ALL + * - MESSAGE_REACTION_REMOVE_EMOJI + */ + DIRECT_MESSAGE_REACTIONS = 1 << 13, + /** Enables the following events: + * - TYPING_START + */ + DIRECT_MESSAGE_TYPING = 1 << 14, +} + +/** https://discord.com/developers/docs/topics/gateway#identify */ +export interface DiscordIdentify { + /** authentication token */ + token: string; + /** connection properties */ + properties: DiscordIdentifyConnectionProps; + /** whether this connection supports compression of packets, default: false */ + compress?: boolean; + /** value between 50 and 250, total number of members where the gateway will stop sending offline members in the guild member list, default: 50 */ + large_threshold?: number; + /** used for Guild Sharding */ + shard: [number, number]; + /** presence structure for initial presence information */ + presence?: DiscordUpdateStatus; + /** enables dispatching of guild subscription events (presence and typing events), default: true */ + guild_subscriptions?: boolean; + /** the Gateway Intents you wish to receive */ + intents: number; +} + +/** https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties */ +export interface DiscordIdentifyConnectionProps { + /** your operating system */ + $os: string; + /** your library name */ + $browser: string; + /** your library name */ + $device: string; +} + +/** https://discord.com/developers/docs/topics/gateway#resume */ +export interface DiscordResume { + /** session token */ + token: string; + /** session id */ + session_id: string; + /** last sequence number received */ + seq: number; +} + +/** https://discord.com/developers/docs/topics/gateway#request-guild-members */ +export interface DiscordRequestGuildMembers { + /** id of the guild to get members for */ + guild_id: string; + /** string that username starts with, or an empty string to return all members */ + query?: string; + /** maximum number of members to send matching the query; a limit of 0 can be used with an empty string query to return all members */ + limit: number; + /** used to specify if we want the presence of the matched members */ + presences?: boolean; + /** used to specify which users you wish to fetch */ + user_ids?: string | string[]; + /** nonce to identify the Guild Members Chunk response */ + nonce?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#update-voice-state */ +export interface DiscordUpdateVoiceState { + /** id of the guild */ + guild_id: string; + /** id of the voice channel client wants to join (null if disconnecting) */ + channel_id: string | null; + /** is the client muted */ + self_mute: boolean; + /** is the client deafened */ + self_deaf: boolean; +} + +/** https://discord.com/developers/docs/topics/gateway#update-status */ +export interface DiscordUpdateStatus { + /** unix time (in milliseconds) of when the client went idle, or null if the client is not idle */ + since: number | null; + /** null, or the user's activities */ + activities: DiscordActivity[]; + /** the user's new status */ + status: DiscordStatusTypes; + /** whether or not the client is afk */ + afk: boolean; +} + +/** https://discord.com/developers/docs/topics/gateway#update-status-status-types */ +export enum DiscordStatusTypes { + ONLINE = "online", + DND = "dnd", + IDLE = "idle", + INVISIBLE = "invisible", + OFFLINE = "offline", +} + +/** https://discord.com/developers/docs/topics/gateway#client-status-object */ +export interface DiscordClientStatus { + /** the user's status set for an active desktop (Windows, Linux, Mac) application session */ + desktop?: string; + /** the user's status set for an active mobile (iOS, Android) application session */ + mobile?: string; + /** the user's status set for an active web (browser, bot account) application session */ + web?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object */ +export interface DiscordActivity { + /** the activity's id */ + id?: string; + /** the activity's name */ + name: string; + /** activity type */ + type: DiscordActivityTypes; + /** stream url, is validated when type is 1 */ + url?: string | null; + /** unix timestamp of when the activity was added to the user's session */ + created_at: number; + /** unix timestamps for start and/or end of the game */ + timestamps?: DiscordActivityTimestamps; + /** the id of the song on Spotify */ + sync_id?: string; + /** the platform the game is being played on ("desktop", "samsung", or "xbox") */ + platform?: string; + /** application id for the game */ + application_id?: string; + /** what the player is currently doing */ + details?: string | null; + /** the user's current party status */ + state?: string | null; + /** the emoji used for a custom status */ + emoji?: DiscordActivityEmoji | null; + /** the id of the game or Spotify session */ + session_id?: string; + /** information for the current party of the player */ + party?: DiscordActivityParty; + /** images for the presence and their hover texts */ + assets?: DiscordActivityAssets; + /** secrets for Rich Presence joining and spectating */ + secrets?: DiscordActivitySecrets; + /** whether or not the activity is an instanced game session */ + instance?: boolean; + /** activity flags OR d together, describes what the payload includes */ + flags?: DiscordActivityFlags; + /** the custom buttons shown in the Rich Presence (max 2) */ + buttons?: DiscordActivityButton[]; +} + +export interface DiscordActivityButton { + /** the text shown on the button (1-32 characters) */ + label: string; + /** the url opened when clicking the button (1-512 characters) */ + url: string; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-types */ +export enum DiscordActivityTypes { + /** Playing {name} */ + GAME, + /** Streaming {details} */ + STREAMING, + /** Listening to {name} */ + LISTENING, + /** {emoji} {name} */ + CUSTOM = 4, + /** Competing in {name} */ + COMPETING, +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-timestamps */ +export interface DiscordActivityTimestamps { + /** unix time (in milliseconds) of when the activity started */ + start?: number; + /** unix time (in milliseconds) of when the activity ends */ + end?: number; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji */ +export interface DiscordActivityEmoji { + /** the name of the emoji */ + name: string; + /** the id of the emoji */ + id?: string; + /** whether this emoji is animated */ + animated?: boolean; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-party */ +export interface DiscordActivityParty { + /** the id of the party */ + id?: string; + /** used to show the party's currrent and maximum size */ + size?: [number, number]; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets */ +export interface DiscordActivityAssets { + /** the id for a large asset of the activity, usually a snowflake */ + large_image?: string; + /** text displayed when hovering over the large image of the activity */ + large_text?: string; + /** the id for a small asset of the activity, usually a snowflake */ + small_image?: string; + /** text displlayed when hovering over the small image of the activity */ + small_text?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets */ +export interface DiscordActivitySecrets { + /** the secret for joining a party */ + join?: string; + /** the secret for spectating a game */ + spectate?: string; + /** the secret for a specific instanced match */ + match?: string; +} + +/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags */ +export enum DiscordActivityFlags { + INSTANCE = 1 << 0, + JOIN = 1 << 1, + SPECTATE = 1 << 2, + JOIN_REQUEST = 1 << 3, + SYNC = 1 << 4, + PLAY = 1 << 5, +} + +/** https://discord.com/developers/docs/topics/gateway#get-gateway-bot-json-response */ +export interface DiscordGetGatewayBot { + /** the WSS URL that can be used for connecting to the gateway */ + url: string; + /** the recommended number of shards to use when connecting */ + shards: number; + /** information on the current session start limit */ + session_start_limit: DiscordSessionStartLimit; +} + +/** https://discord.com/developers/docs/topics/gateway#session-start-limit-object-session-start-limit-structure */ +export interface DiscordSessionStartLimit { + /** the total number of session starts the current user is allowed */ + total: number; + /** the remaining number of session starts the current user is allowed */ + remaining: number; + /** the number of milliseconds after which the limit resets */ + reset_after: number; + /** the number of identify requests allowed per 5 seconds */ + max_concurrency: number; +} diff --git a/src/types/api/guild.ts b/src/types/api/guild.ts new file mode 100644 index 000000000..4dcff62bd --- /dev/null +++ b/src/types/api/guild.ts @@ -0,0 +1,465 @@ +import { + DiscordChannel, + DiscordChannelTypes, + DiscordEmoji, + DiscordMember, + DiscordOverwrite, + DiscordPresenceUpdateEvent, + DiscordRole, + DiscordUser, + DiscordVoiceStateUpdateEvent, +} from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/guild#guild-object */ +export interface DiscordGuild { + /** guild id */ + id: string; + /** guild name (2-100 characaters, excluding trailing and leading whitespace) */ + name: string; + /** icon hash */ + icon: string | null; + /** icon hash, returned when in the template object */ + icon_hash?: string | null; + /** splash hash */ + splash: string | null; + /** discovery splash hash; only present for guilds with the "DISCOVERABLE" feature */ + discovery_splash: string | null; + /** true if the user is the owner of the guild */ + owner?: boolean; + /** id of the owner */ + owner_id: string; + /** total permissions for the user in the guild (execludes overrides) */ + permissions?: string; + /** voice region id for the guild */ + region: string; + /** id of afk channel */ + afk_channel_id: string | null; + /** afk timeout in seconds */ + afk_timeout: number; + /** true if the server widget is enabled */ + widget_enabled?: boolean; + /** the channel id that the widget will generate an invite to, or null if set to no invite */ + widget_channel_id?: string | null; + /** verification level required for the guild */ + verification_level: DiscordVerificationLevel; + /** default message notifications level */ + default_message_notifications: DiscordDefaultMessageNotificationLevel; + /** explicit content filter level */ + explicit_content_filter: DiscordExplicitContentFilterLevel; + /** roles in the guild */ + roles: DiscordRole[]; + /** custom guild emojis */ + emojis: DiscordEmoji[]; + /** enabled guild features */ + features: DiscordGuildFeatures[]; + /** required MFA level for the guild */ + mfa_level: DiscordMFALevel; + /** application id of the guild creator if it is bot-created */ + application_id: string | null; + /** the id of the channel where guild notices such as welcome messages and boost events are posted */ + system_channel_id: string | null; + /** system channel flags */ + system_channel_flags: DiscordSystemChannelFlags; + /** the id of the channel where community guilds can display rules and/or guidelines */ + rules_channel_id: string | null; + /** when this guild was joined at */ + joined_at?: string; + /** true if this is considered a large guild */ + large?: boolean; + /** true if this guild is unavailable due to an outage */ + unavailable?: boolean; + /** total number of members in this guild */ + member_count?: number; + /** states of members currently in voice channels; lacks the guild_id key */ + voice_states?: Partial[]; + /** users in the guild */ + members?: DiscordMember[]; + /** channels in the guild */ + channels?: DiscordChannel[]; + /** presences of the members in the guild, will only include non-offline members if the size is greater than large threshold */ + presences?: Partial[]; + /** the maximum number of presences for the guild (the default value, currently 25000, is in effect when null is returned) */ + max_presences?: number | null; + /** the maximum number of members for the guild */ + max_members?: number; + /** the vaniy url code for the guild */ + vanity_url_code: string | null; + /** the description for the guild, if the guild is discoverable */ + description: string | null; + /** banner hash */ + banner: string | null; + /** premium tier (Server Boost level) */ + premium_tier: DiscordPremiumTier; + /** the number of boosts this guild currently has */ + premium_subscription_count?: number; + /** the preferred locale of a Community guild; used in server discovery and notices from Discord; defaults to "en-US" */ + preferred_locale: string; + /** the id of the channel where admins and moderators of Community guilds receive notices from Discord */ + public_updates_channel_id: string | null; + /** the maximum amount of users in a video channel */ + max_video_channel_users?: number; + /** approximate number of members in this guild, returned from the GET /guilds/ endpoint when with_counts is true */ + approximate_member_count?: number; + /** approximate number of non-offline members in this guild, returned from the GET /guilds/ endpoint when with_counts is true */ + approximate_presence_count?: number; +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level */ +export enum DiscordDefaultMessageNotificationLevel { + ALL_MESSAGES, + ONLY_MENTIONS, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level */ +export enum DiscordExplicitContentFilterLevel { + DISABLED, + MEMBERS_WITHOUT_ROLES, + ALL_MEMBERS, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-mfa-level */ +export enum DiscordMFALevel { + NONE, + ELEVATED, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-verification-level */ +export enum DiscordVerificationLevel { + NONE, + LOW, + MEDIUM, + HIGH, + VERY_HIGH, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-premium-tier */ +export enum DiscordPremiumTier { + NONE, + TIER_1, + TIER_2, + TIER_3, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags */ +export enum DiscordSystemChannelFlags { + SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0, + SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1, +} + +/** https://discord.com/developers/docs/resources/guild#guild-object-guild-features */ +export enum DiscordGuildFeatures { + INVITE_SPLASH, + VIP_REGIONS, + VANITY_URL, + VERIFIED, + PARTNERED, + COMMUNITY, + COMMERCE, + NEWS, + DISCOVERABLE, + FEATURABLE, + ANIMATED_ICON, + BANNER, + WELCOME_SCREEN_ENABLED, + MEMBER_VERIFICATION_GATE_ENABLED, + PREVIEW_ENABLED, +} + +/** https://discord.com/developers/docs/resources/guild#unavailable-guild-object */ +export type DiscordUnavailableGuild = Pick; + +/** https://discord.com/developers/docs/resources/guild#guild-preview-object */ +export interface DiscordGuildPreview { + /** guild id */ + id: string; + /** guild name (2-100 characters) */ + name: string; + /** icon hash */ + icon: string | null; + /** splash hash */ + splash: string | null; + /** discovery splash hash */ + discovery_splash: string | null; + /** custom guild emojis */ + emojis: DiscordEmoji[]; + /** enabled guild features */ + features: DiscordGuildFeatures[]; + /** approximate number of members in this guild */ + approximate_member_count: number; + /** approximate number of online members in this guild */ + approximate_presence_count: number; + /** the description for the guild */ + description: string | null; +} + +/** https://discord.com/developers/docs/resources/guild#guild-widget-object-guild-widget-structure */ +export interface DiscordGuildWidget { + /** whether the widget is enabled */ + enabled: boolean; + /** the widget channel id */ + channel_id: string | null; +} + +/** https://discord.com/developers/docs/resources/guild#ban-object */ +export interface DiscordBan { + /** the reason for the ban */ + reason: string | null; + /** the banned user */ + user: DiscordUser; +} + +export interface DiscordMembershipScreening { + /** when the fields were last updated */ + version: string; + /** the steps in the screening form */ + form_fields: DiscordMembershipScreeningField[]; + /** the server description shown in the screening form */ + description: string | null; +} + +export interface DiscordMembershipScreeningField { + /** the type of field (currently "TERMS" is the only type) */ + field_type: DiscordMembershipScreeningFieldTypes; + /** the title of the field */ + label: string; + /** the list of rules */ + values?: string[]; + /** whether the user has to fill out this field */ + required: boolean; +} + +export enum DiscordMembershipScreeningFieldTypes { + /** Server Rules */ + TERMS = "TERMS", +} + +/** https://discord.com/developers/docs/resources/guild#create-guild */ +export interface DiscordCreateGuildParams { + /** name of the guild (2-100 characters) */ + name: string; + /** voice region id */ + region?: string; + /** base64 128x128 image for the guild icon */ + icon?: string; + /** verification level */ + verification_level?: DiscordVerificationLevel; + /** default message notification level */ + default_message_notifications?: DiscordDefaultMessageNotificationLevel; + /** explicit content filter level */ + explicit_content_filter?: DiscordExplicitContentFilterLevel; + /** new guild roles (first role is the everyone role) */ + roles?: DiscordRole[]; + /** new guild's channels */ + channels?: Partial[]; + /** id for afk channel */ + afk_channel_id?: string; + /** afk timeout in seconds */ + afk_timeout?: number; + /** the id of the channel where guild notices such as welcome messages and boost events are posted */ + system_channel_id?: string; +} + +/** https://discord.com/developers/docs/resources/guild#get-guild */ +export interface DiscordGetGuildParams { + /** when true, will return approximate member and presence counts for the guild */ + with_counts?: boolean; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild */ +export interface DiscordModifyGuildParams { + /** guild name */ + name?: string; + /** guild voice region id */ + region?: string | null; + /** verification level */ + verification_level?: DiscordVerificationLevel | null; + /** default message notification filter level */ + default_message_notifications?: DiscordDefaultMessageNotificationLevel | null; + /** explicit content filter level */ + explicit_content_filter?: DiscordExplicitContentFilterLevel | null; + /** id for afk channel */ + afk_channel_id?: string | null; + /** afk timeout in seconds */ + afk_timeout?: number; + /** base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the server has ANIMATED_ICON feature) */ + icon?: string | null; + /** user id to transfer guild ownershop to (must be owner) */ + owner_id?: string; + /** base64 16:9 png/jpeg image for the guild splash (when the server has INVITE_SPLASH feature) */ + splash?: string | null; + /** base64 16:9 png/jpeg image for the guild banner (when the server has BANNER feature) */ + banner?: string | null; + /** the id of the channel where guild notices such as welcome messages and boost events are posted */ + system_channel_id?: string | null; + /** the id of the channel where Community guilds display rules and/or guidelines */ + rules_channel_id?: string | null; + /** the id of the channel where admins and moderators of Community guilds receive notices from Discord */ + public_updates_channel_id?: string | null; + /** the preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" */ + preferred_locale?: string | null; +} + +/** https://discord.com/developers/docs/resources/guild#create-guild-channel */ +export interface DiscordCreateGuildChannelParams { + /** channel name (2-100 characters) */ + name: string; + /** the type of channel */ + type?: DiscordChannelTypes; + /** channel topic (0-1024 characters) */ + topic?: string; + /** the bitrate (in bits) of the voice channel (voice only) */ + bitrate?: number; + /** the user limit of the voice channel (voice only) */ + user_limit?: number; + /** amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages or manage_channel, are unaffected */ + rate_limit_per_user?: number; + /** sorting position of the channel */ + position?: number; + /** the channel's permission overwrites */ + permission_overwrites?: DiscordOverwrite[]; + /** id of the parent category for a channel */ + parent_id?: string; + /** whether the channel is nsfw */ + nsfw?: boolean; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions */ +export interface DiscordModifyGuildChannelPositionsParam { + /** channel id */ + id: string; + /** sorting position of the channel */ + position: number | null; +} + +/** https://discord.com/developers/docs/resources/guild#list-guild-members */ +export interface DiscordListGuildMembersParams { + /** max number of members to return (1-1000), default 1 */ + limit: number; + /** the highest user id in the previous page, default 0 */ + after: string; +} + +/** https://discord.com/developers/docs/resources/guild#add-guild-member */ +export interface DiscordAddGuildMemberParams { + /** an oauth2 access token granted with the guilds.join to the bot's application for the user you want to add to the guild */ + access_token: string; + /** value to set users nickname to. Requires the MANAGE_NICKNAMES permission */ + nick?: string; + /** array of role ids the member is assigned. Requires the MANAGE_ROLES permission */ + roles?: string[]; + /** whether the user is muted in voice channels. Requires the MUTE_MEMBERS permission */ + mute?: boolean; + /** whether the user is deafened in voice channels. Requires the DEAFEN_MEMBERS permission */ + deaf?: boolean; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-member */ +export interface DiscordModifyGuildMemberParams { + /** value to set users nickname to. Requires the MANAGE_NICKNAMES permission */ + nick?: string | null; + /** array of role ids the member is assigned. Requires the MANAGE_ROLES permission */ + roles?: string[] | null; + /** whether the user is muted in voice channels. Will throw a 400 if the user is not in a voice channel. Requires the MUTE_MEMBERS permission */ + mute?: boolean | null; + /** whether the user is deafened in voice channels. Will throw a 400 if the user is not in a voice channel. Requires the MOVE_MEMBERS permission */ + deaf?: boolean | null; + /** id of channel to move user to (if they are connected to voice). Requires the MOVE_MEMBERS permission */ + channel_id: string | null; +} + +/** https://discord.com/developers/docs/resources/guild#modify-current-user-nick */ +export interface DiscordModifyCurrentUserNickParams { + /** value to set users nickname to. Requires the CHANGE_NICKNAME permission */ + nick?: string | null; +} + +/** https://discord.com/developers/docs/resources/guild#create-guild-ban */ +export interface DiscordCreateGuildBan { + /** number of days to delete messages for (0-7) */ + delete_message_days?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; + /** reason for the ban */ + reason?: string; +} + +/** https://discord.com/developers/docs/resources/guild#create-guild-role */ +export interface DiscordCreateGuildRoleParams { + /** name of the role, default: "new role" */ + name?: string; + /** bitwise value of the enabled/disabled permissions, default: everyone permissions in guild */ + permissions?: string; + /** RGB color value, default: 0 */ + color?: number; + /** whether the role should be displayed separately in the sidebar, default: false */ + hoist?: boolean; + /** whether the role should be mentionable, default: false */ + mentionable?: boolean; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-role-positions */ +export interface DiscordModifyGuildRolePositionsParams { + /** role id */ + id: string; + /** sorting position of the role */ + position?: number | null; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-role */ +export interface DiscordModifyGuildRoleParams { + /** name of the role */ + name?: string | null; + /** bitwise value of the enabled/disabled permissions */ + permissions?: string | null; + /** RGB color value */ + color?: number | null; + /** whether the role should be displayed seperately in the sidebar */ + hoist?: boolean | null; + /** whether the role should be mentionable */ + mentionable?: boolean | null; +} + +/** https://discord.com/developers/docs/resources/guild#get-guild-prune-count */ +export interface DiscordGetGuildPruneCountParams { + /** number of days to count prune for (1 or more), default: 7 */ + days?: number; + /** role(s) to include, default: none */ + include_roles: string | string[]; +} + +/** https://discord.com/developers/docs/resources/guild#begin-guild-prune */ +export interface DiscordBeginGuildPruneParams { + /** number of days to prune (1 or more), default: 7 */ + days?: number; + /** whether 'pruned' is returned, discouraged for large guilds, default: true */ + compute_prune_count?: boolean; + /** role(s) ro include, default: none */ + include_roles?: string[]; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-integration */ +export interface DiscordGetGuildWidgetImageParams { + /** style of the widget returned, default: shield */ + style?: DiscordGetGuildWidgetImageStyleOptions; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-integration */ +export enum DiscordGetGuildWidgetImageStyleOptions { + /** shield style widget with Discord icon and guild members online count */ + SHIELD = "shield", + /** large image with guild icon, name and online count. "POWERED BY DISCORD" as the footer of the widget */ + BANNER_1 = "banner1", + /** smaller widget style with guild icon, name and online count. Split on the right with Discord logo */ + BANNER_2 = "banner2", + /** large image with guild icon, name and online count. In the footer, Discord logo on the left and "Chat Now" on the right */ + BANNER_3 = "banner3", + /** large Discord logo at the top of the widget. Guild icon, name and online count in the middle portion of the widget and a "JOIN MY SERVER" button at the bottom */ + BANNER_4 = "banner4", +} + +export interface DiscordModifyGuildMembershipScreeningFormParams { + /** whether Membership Screening is enabled */ + enabled: boolean; + /** arrray of field objects serialized in a string */ + form_fields: string; + /** the server description to show in the screening form */ + description: string; +} diff --git a/src/types/api/image.ts b/src/types/api/image.ts new file mode 100644 index 000000000..68d266f23 --- /dev/null +++ b/src/types/api/image.ts @@ -0,0 +1,3 @@ +/** https://discord.com/developers/docs/reference#image-formatting */ +export type DiscordImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048; +export type DiscordImageFormat = "jpg" | "jpeg" | "png" | "webp" | "gif"; diff --git a/src/types/api/integration.ts b/src/types/api/integration.ts new file mode 100644 index 000000000..e7b056d3e --- /dev/null +++ b/src/types/api/integration.ts @@ -0,0 +1,145 @@ +import { DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/guild#integration-object-integration-structure */ +export interface DiscordIntegration { + /** integration id */ + id: string; + /** integration name */ + name: string; + /** integration type (twitch, youtube, or discord) */ + type: string; + /** is this integration enabled */ + enabled: boolean; + /** is this integration syncing */ + syncing?: boolean; + /** id that this integration uses for "subscribers" */ + role_id?: string; + /** whether emoticons should be synced for this integration (twitch only currently) */ + enable_emoticons?: boolean; + /** the behavior of expiring subscribers */ + expire_behavior?: DiscordIntegrationExpireBehavior; + /** the grace period (in days) before expiring subscribers */ + expire_grace_period?: number; + /** user for this integration */ + user?: DiscordUser; + /** integration account information */ + account: DiscordIntegrationAccount; + /** when this integration was last synced */ + synced_at?: string; + /** how many subscribers this integration has */ + subscriber_count: number; + /** has this integration been revoked */ + revoked?: boolean; + /** the bot/OAuth2 application for discord integrations */ + application?: DiscordIntegrationApplication; +} + +/** https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors */ +export enum DiscordIntegrationExpireBehavior { + REMOVE_ROLE, + KICK, +} + +/** https://discord.com/developers/docs/resources/guild#integration-account-object */ +export interface DiscordIntegrationAccount { + /** id of the account */ + id: string; + /** name of the account */ + name: string; +} + +/** https://discord.com/developers/docs/resources/guild#integration-application-object */ +export interface DiscordIntegrationApplication { + /** the id of the app */ + id: string; + /** the name of the app */ + name: string; + /** the icon hash of the app */ + icon: string | null; + /** the description of the app */ + description: string; + /** the summary of the app */ + summary: string; + /** If this application is a game sold on Discord, this field will be the hash of the image on store embeds */ + cover_image?: string; + /** the bot associated with this application */ + bot?: DiscordUser; +} + +/** https://discord.com/developers/docs/resources/guild#integration-object-integration-structure */ +export interface DiscordIntegration { + /** integration id */ + id: string; + /** integration name */ + name: string; + /** integration type (twitch, youtube, or discord) */ + type: string; + /** is this integration enabled */ + enabled: boolean; + /** is this integration syncing */ + syncing?: boolean; + /** id that this integration uses for "subscribers" */ + role_id?: string; + /** whether emoticons should be synced for this integration (twitch only currently) */ + enable_emoticons?: boolean; + /** the behavior of expiring subscribers */ + expire_behavior?: DiscordIntegrationExpireBehavior; + /** the grace period (in days) before expiring subscribers */ + expire_grace_period?: number; + /** user for this integration */ + user?: DiscordUser; + /** integration account information */ + account: DiscordIntegrationAccount; + /** when this integration was last synced */ + synced_at?: string; + /** how many subscribers this integration has */ + subscriber_count: number; + /** has this integration been revoked */ + revoked?: boolean; + /** the bot/OAuth2 application for discord integrations */ + application?: DiscordIntegrationApplication; +} + +/** https://discord.com/developers/docs/resources/guild#integration-account-object */ +export interface DiscordIntegrationAccount { + /** id of the account */ + id: string; + /** name of the account */ + name: string; +} + +/** https://discord.com/developers/docs/resources/guild#integration-application-object */ +export interface DiscordIntegrationApplication { + /** the id of the app */ + id: string; + /** the name of the app */ + name: string; + /** the icon hash of the app */ + icon: string | null; + /** the description of the app */ + description: string; + /** the summary of the app */ + summary: string; + /** If this application is a game sold on Discord, this field will be the hash of the image on store embeds */ + cover_image?: string; + /** the bot associated with this application */ + bot?: DiscordUser; +} + +/** https://discord.com/developers/docs/resources/guild#create-guild-integration */ +export interface DiscordCreateGuildIntegrationParams { + /** the integration type */ + type: string; + /** the integration id */ + id: string; +} + +/** https://discord.com/developers/docs/resources/guild#modify-guild-integration */ +export interface DiscordModifyGuildIntegration { + /** the behavior when an integration subscription lapses (see the integration expire behaviors documentation) */ + expire_behavior?: number | null; + /** perios (in days) where the integration will ignore lapsed subscriptions */ + expire_grace_period?: number | null; + /** whether emoticons should be synced for this integration (twitch only currently) */ + enable_emoticons?: boolean | null; +} diff --git a/src/types/api/interaction.ts b/src/types/api/interaction.ts new file mode 100644 index 000000000..d9cb62f7c --- /dev/null +++ b/src/types/api/interaction.ts @@ -0,0 +1,102 @@ +import { DiscordMember } from "./mod.ts"; + +export interface DiscordInteractionCommand { + /** id of the interaction */ + id: string; + /** the type of interaction */ + type: DiscordInteractionType; + /** the command data payload */ + data?: DiscordInteractionData; + /** the guild it was sent from */ + guild_id: string; + /** the channel it was sent from */ + channel_id: string; + /** guild member data for the invoking user */ + member: DiscordMember; + /** a continuation token for responding to the interaction */ + token: string; + /** read-only property, always 1 */ + version: number; +} + +export enum DiscordInteractionType { + /** This type is for ACK on webhook only setup. Discord may send these which require. In a sense its a heartbeat. */ + PING = 1, + /** Slash commands */ + APPLICATION_COMMAND, +} + +export interface DiscordInteractionData { + /** the ID of the invoked command */ + id: string; + /** the name of the invoked command */ + name: string; + /** the params + values from the user */ + options: DiscordInteractionDataOption[]; +} + +export interface DiscordInteractionDataOption { + /** the name of the parameter */ + name: string; + /** the value of the pair. present if there was no more options */ + value?: string | number; + /** present if this option is a group or subcommand */ + options?: DiscordInteractionDataOption[]; +} + +/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommand */ +export interface DiscordApplicationCommand { + /** unique id of the command */ + id: string; + /** unique id of the parent application */ + "application_id": string; + /** 3-32 character name matching `^[\w-]{3,32}$` */ + name: string; + /** 1-100 character description */ + description: string; + /** the parameters for the command */ + options?: DiscordApplicationCommandOption[]; +} + +/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption */ +export interface DiscordApplicationCommandOption { + /** the type of the option */ + type: DiscordApplicationCommandOptionType; + /** 1-32 character name matching `^[\w-]{1,32}$` */ + name: string; + /** 1-100 character description */ + description: string; + /** the first `required` option for the user to complete--only one option can be `default` */ + default?: boolean; + /** if the parameter is required or optional--default `false` */ + required?: boolean; + /** choices for `string` and `int` types for the user to pick from */ + choices?: DiscordApplicationCommandOptionChoice[]; + /** if the option is a subcommand or subcommand group type, this nested options will be the parameters */ + options?: DiscordApplicationCommandOption[]; +} + +/** https://discord.com/developers/docs/interactions/slash-commands#Discordapplicationcommandoptiontype */ +export enum DiscordApplicationCommandOptionType { + SUB_COMMAND = 1, + SUB_COMMAND_GROUP, + STRING, + INTEGER, + BOOLEAN, + USER, + CHANNEL, + ROLE, +} + +/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice */ +export interface DiscordApplicationCommandOptionChoice { + /** 1-100 character choice name */ + name: string; + /** value of the choice */ + value: string | number; +} + +export type DiscordApplicationCommandEvent = DiscordApplicationCommand & { + /** id of the guild the command is in */ + guild_id?: string; +}; diff --git a/src/types/api/invite.ts b/src/types/api/invite.ts new file mode 100644 index 000000000..f45613a9d --- /dev/null +++ b/src/types/api/invite.ts @@ -0,0 +1,46 @@ +import { DiscordChannel, DiscordGuild, DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/invite#invite-object */ +export interface DiscordInvite { + /** the invite code (unique ID) */ + code: string; + /** the guild this invite is for */ + guild?: Partial; + /** the channel this invite is for */ + channel: Partial; + /** the user who created the invite */ + inviter?: DiscordUser; + /** the target user for this invite */ + target_user?: Partial; + /** the type of user target for this invite */ + target_user_type?: DiscordInviteTargetUserTypes; + /** approximate count of online members (only present when target_user is set) */ + approximate_presence_count?: number; + /** approximate count of total members */ + approximate_member_count: number; +} + +/** https://discord.com/developers/docs/resources/invite#invite-resource */ +export enum DiscordInviteTargetUserTypes { + STREAM = 1, +} + +/** https://discord.com/developers/docs/resources/invite#invite-resource */ +export interface DiscordInviteMetadata extends DiscordInvite { + /** number of times this invite has been used */ + uses: number; + /** max number of times this invite can be used */ + max_uses: number; + /** duration (in seconds) after which the invite expires */ + max_age: number; + /** whether this invite only grants temporary membership */ + temporary: boolean; + /** when this invite was created */ + created_at: string; +} + +/** https://discord.com/developers/docs/resources/invite#get-invite */ +export interface DiscordGetInviteURLParams { + /** whether the invite should contain approximate member counts */ + with_counts?: boolean; +} diff --git a/src/types/api/member.ts b/src/types/api/member.ts new file mode 100644 index 000000000..e17403cb0 --- /dev/null +++ b/src/types/api/member.ts @@ -0,0 +1,89 @@ +export interface DiscordBaseUser { + /** the user's id */ + id: string; + /** the user's username, not unique across the platform */ + username: string; + /** the user's 4-digit discord-tag */ + discriminator: string; + /** the user's avatar hash */ + avatar: string | null; +} + +/** https://discord.com/developers/docs/resources/user#users-resource */ +export interface DiscordUser extends DiscordBaseUser { + /** the user's id */ + id: string; + /** the user's username, not unique across the platform */ + username: string; + /** the user's 4-digit discord-tag */ + discriminator: string; + /** the user's avatar hash */ + avatar: string | null; + /** whether the user belongs to an OAuth2 application */ + bot?: boolean; + /** whether the user is an Official Discord System user (part of the urgent message system) */ + system?: boolean; + /** whether the user has two factor enabled on their account */ + mfa_enabled?: boolean; + /** the user's chosen language option */ + locale?: string; + /** whether the email on this account has been verified */ + verified?: boolean; + /** the user's email */ + email?: string | null; + /** the flags on a user's account */ + flags?: DiscordUserFlags; + /** the type of Nitro subscription on a user's account */ + premium_type?: DiscordPremiumTypes; + /** the public flags on a user's account */ + public_flags?: DiscordUserFlags; +} + +/** https://discord.com/developers/docs/resources/user#users-resource */ +export enum DiscordUserFlags { + NONE = 0, + DISCORD_EMPLOYEE = 1 << 0, + PARTNERED_SERVER_OWNER = 1 << 1, + HYPE_SQUAD_EVENTS = 1 << 2, + BUG_HUNTER_LEVEL_1 = 1 << 3, + HOUSE_BRAVERY = 1 << 6, + HOUSE_BRILLIANCE = 1 << 7, + HOUSE_BALANCE = 1 << 8, + EARLY_SUPPORTER = 1 << 9, + TEAM_USER = 1 << 10, + SYSTEM = 1 << 12, + BUG_HUNTER_LEVEL_2 = 1 << 14, + VERIFIED_BOT = 1 << 16, + EARLY_VERIFIED_BOT_DEVELOPER = 1 << 17, +} + +/** https://discord.com/developers/docs/resources/user#users-resource */ +export enum DiscordPremiumTypes { + NONE = 0, + NITRO_CLASSIC = 1, + NITRO = 2, +} + +/** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure */ +export interface DiscordBaseMember { + /** this users guild nickname */ + nick: string | null; + /** array of role payload ids */ + roles: string[]; + /** when the user joined the guild */ + joined_at: string; + /** when the user started boosting the guild */ + premium_since?: string | null; + /** whether the user is deafened in voice channels */ + deaf: boolean; + /** whether the user is muted in voice channels */ + mute: boolean; + /** whether the user has not yet passed the guild's Membership Screening requirements */ + pending?: boolean; +} + +/** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure */ +export interface DiscordMember { + /** the user this guild member represents */ + user?: DiscordUser; +} diff --git a/src/types/api/message.ts b/src/types/api/message.ts new file mode 100644 index 000000000..d05de3392 --- /dev/null +++ b/src/types/api/message.ts @@ -0,0 +1,290 @@ +import { DiscordMember } from "./member.ts"; +import { + DiscordBaseMember, + DiscordChannelTypes, + DiscordEmbed, + DiscordEmoji, + DiscordUser, +} from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/channel#message-object-message-structure */ +export interface DiscordMessage { + /** id of the message */ + id: string; + /** id of the channel the message was sent in */ + channel_id: string; + /** id of the guild the message was sent in */ + guild_id?: string; + /** the author of this message (not guaranteed to be a valid user) */ + author: DiscordUser; + /** member properties for this message's author */ + member?: DiscordBaseMember; + /** contents of the message */ + content: string; + /** when this message was sent */ + timestamp: string; + /** when this message was edited (or null if never) */ + edited_timestamp: string | null; + /** whether this was a TTS message */ + tts: boolean; + /** whether this message mentions everyone */ + mention_everyone: boolean; + /** users specifically mentioned in the message */ + mentions: (DiscordUser & Partial)[]; + /** roles specifically mentioned in this message */ + mention_roles: string[]; + /** channels specifically mentioned in this message */ + mention_channels?: DiscordChannelMention[]; + /** any attached files */ + attachments: DiscordAttachment[]; + /** any embedded content */ + embeds: DiscordEmbed[]; + /** reactions to the message */ + reactions?: DiscordReaction[]; + /** used for validating a message was sent */ + nonce?: number | string; + /** whether this message is pinned */ + pinned: boolean; + /** if the message is generated by a webhook, this is the webhook's id */ + webhook_id?: string; + /** type of message */ + type: DiscordMessageTypes; + /** sent with Rich Presence-related chat embeds */ + activity?: DiscordMessageActivity; + /** sent with Rich Presence-related chat embeds */ + application?: DiscordMessageApplication; + /** reference data sent with crossposted messages and replies */ + message_reference?: DiscordMessageReference; + /** message flags combined as a bitfield */ + flags?: DiscordMessageFlags; + /** the stickers sent with the message (bots currently can only receive messages with stickers, not send) */ + stickers?: DiscordMessageSticker[]; + /** the message associated with the `message_reference` */ + referenced_message?: DiscordMessage | null; +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-types */ +export enum DiscordMessageTypes { + DEFAULT, + RECIPIENT_ADD, + RECIPIENT_REMOVE, + CALL, + CHANNEL_NAME_CHANGE, + CHANNEL_ICON_CHANGE, + CHANNEL_PINNED_MESSAGE, + GUILD_MEMBER_JOIN, + USER_PREMIUM_GUILD_SUBSCRIPTION, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3, + CHANNEL_FOLLOW_ADD, + GUILD_DISCOVERY_DISQUALIFIED = 14, + GUILD_DISCOVERY_REQUALIFIED, + GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING, + GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING, + REPLY = 19, + APPLICATION_COMMAND, +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-activity-structure */ +export interface DiscordMessageActivity { + /** type of message activity */ + type: DiscordMessageActivityTypes; + /** party_id from a Rich Presence event */ + party_id?: string; +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-application-structure */ +export interface DiscordMessageApplication { + /** id of the application */ + id: string; + /** id of the embed's image asset */ + cover_image?: string; + /** application's description */ + description: string; + /** id of the application's icon */ + icon: string | null; + /** name of the application */ + name: string; +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure */ +export interface DiscordMessageReference { + /** id of the originating message */ + message_id?: string; + /** id of the originating message's channel */ + channel_id?: string; + /** id of the originating message's guild */ + guild_id?: string; +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-activity-types */ +export enum DiscordMessageActivityTypes { + JOIN = 1, + SPECTATE, + LISTEN, + JOIN_REQUEST = 5, +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-flags */ +export enum DiscordMessageFlags { + /** this message has been published to subscribed channels (via Channel Following) */ + CROSSPOSTED = 1 << 0, + /** this message originated from a message in another channel (via Channel Following) */ + IS_CROSSPOST = 1 << 1, + /** do not include any embeds when serializing this message */ + SUPPRESS_EMBEDS = 1 << 2, + /** the source message for this crosspost has been deleted (via Channel Following) */ + SOURCE_MESSAGE_DELETED = 1 << 3, + /** this message came from the urgent message system */ + URGENT = 1 << 4, +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-sticker-structure */ +export interface DiscordMessageSticker { + /** id of the sticker */ + id: string; + /** id of the pack the sticker is from */ + pack_id: string; + /** name of the sticker */ + name: string; + /** description of the sticker */ + description: string; + /** a comma-separated list of tags for the sticker */ + tags?: string; + /** sticker asset hash */ + asset: string; + /** sticker preview asset hash */ + preview_asset: string | null; + /** type of sticker format */ + format_type: DiscordMessageStickerFormatTypes; +} + +/** https://discord.com/developers/docs/resources/channel#message-object-message-sticker-format-types */ +export enum DiscordMessageStickerFormatTypes { + PNG = 1, + APNG, + LOTTIE, +} + +/** https://discord.com/developers/docs/resources/channel#reaction-object-reaction-structure */ +export interface DiscordReaction { + /** times this emoji has been used to react */ + count: number; + /** whether the current user reacted using this emoji */ + me: boolean; + /** emoji information */ + emoji: Partial; +} + +/** https://discord.com/developers/docs/resources/channel#attachment-object-attachment-structure */ +export interface DiscordAttachment { + /** attachment id */ + id: string; + /** name of file attached */ + filename: string; + /** size of file in bytes */ + size: number; + /** source url of file */ + url: string; + /** a proxied url of file */ + proxy_url: string; + /** height of file (if image) */ + height?: number | null; + /** width of file (if image) */ + width?: number | null; +} + +/** https://discord.com/developers/docs/resources/channel#channel-mention-object-channel-mention-structure */ +export interface DiscordChannelMention { + /** id of the channel */ + id: string; + /** id of the guild containing the channel */ + guild_id: string; + /** the type of channel */ + type: DiscordChannelTypes; + /** the name of the channel */ + name: string; +} + +/** https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types */ +export enum AllowedMentionTypes { + /** Controls role mentions */ + ROLES = "roles", + /** Controls user mentions */ + USERS = "users", + /** Controls `@everyone` and `@here` mentions */ + EVERYONE = "everyone", +} + +/** https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mentions-structure */ +export interface DiscordAllowedMentions { + /** An array of allowed mention types to parse from the content. */ + parse: AllowedMentionTypes[]; + /** Array of role_ids to mention (Max size of 100) */ + roles: string[]; + /** Array of user_ids to mention (Max size of 100) */ + users: string[]; + /** For replies, whether to mention the author of the message being replied to (default false) */ + replied_user: boolean; +} + +/** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ +export interface DiscordGetChannelMessagesParams { + /** get messages around this message ID */ + around?: string; + /** get messages before this message ID */ + before?: string; + /** get messages after this message ID */ + after?: string; + /** max number of messages to return (1-100) */ + limit?: number; +} + +/** https://discord.com/developers/docs/resources/channel#create-message-params */ +export interface DiscordCreateMessageParams { + /** the message contents (up to 2000 characters) */ + content?: string; + /** a nonce that can be used for optimistic message sending */ + nonce?: number | string; + /** `true` if this is a TTS message */ + tts: boolean; + /** the contents of the file being sent */ + file?: { blob: unknown; name: string }; + /** embedded rich content */ + embed?: DiscordEmbed; + /** JSON encoded body of any additional request fields. */ + payload_json?: string; + /** allowed mentions for a message */ + allowed_mentions?: DiscordAllowedMentions; + /** include to make your message a reply */ + message_reference?: DiscordMessageReference; +} + +/** https://discord.com/developers/docs/resources/channel#get-reactions-query-string-params */ +export interface DiscordGetReactionsParams { + /** get users before this user ID */ + before?: string; + /** get users after this user ID */ + after?: string; + /** max number of users to return (1-100) */ + limit?: number; +} + +/** https://discord.com/developers/docs/resources/channel#edit-message-json-params */ +export interface DiscordEditMessageParams { + /** the new message contents (up to 2000 characters) */ + content?: string | null; + /** embedded rich content */ + embed?: DiscordEmbed | null; + /** edit the flags of a message (only SUPPRESS_EMBEDS can currently be set/unset) */ + flags?: DiscordMessageFlags | null; + /** allowed mentions for the message */ + allowed_mentions?: DiscordAllowedMentions | null; +} + +/** https://discord.com/developers/docs/resources/channel#bulk-delete-messages-json-params */ +export interface DiscordBulkDeleteMessagesParams { + /** an array of message ids to delete (2-100) */ + messages: string[]; +} diff --git a/src/types/api/mod.ts b/src/types/api/mod.ts new file mode 100644 index 000000000..205d6ab70 --- /dev/null +++ b/src/types/api/mod.ts @@ -0,0 +1,22 @@ +export * from "./auditlog.ts"; +export * from "./channel.ts"; +export * from "./code.ts"; +export * from "./embed.ts"; +export * from "./emoji.ts"; +export * from "./event.ts"; +export * from "./gateway.ts"; +export * from "./guild.ts"; +export * from "./image.ts"; +export * from "./integration.ts"; +export * from "./interaction.ts"; +export * from "./invite.ts"; +export * from "./member.ts"; +export * from "./message.ts"; +export * from "./oauth2.ts"; +export * from "./permission.ts"; +export * from "./ratelimits.ts"; +export * from "./role.ts"; +export * from "./teams.ts"; +export * from "./template.ts"; +export * from "./voice.ts"; +export * from "./webhook.ts"; diff --git a/src/types/api/oauth2.ts b/src/types/api/oauth2.ts new file mode 100644 index 000000000..b60302fe9 --- /dev/null +++ b/src/types/api/oauth2.ts @@ -0,0 +1,37 @@ +import { DiscordTeam, DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/topics/oauth2#get-current-application-information */ +export interface DiscordApplication { + /** id of the app */ + id: string; + /** the name of the app */ + name: string; + /** the icon hash of the app */ + icon: string | null; + /** the description of the app */ + description: string; + /** an array of rpc origin urls, if rpx is enabled */ + rpc_origins?: string[]; + /** when false only app owner can join the app's bot to guilds */ + bot_public: boolean; + /** when true the app's bot will only join upon completion of the full oauth2 code grant flow */ + bot_require_code_grand: boolean; + /** partial user object containing info on the owner of the application */ + owner: Partial; + /** if this application is a game sold on Disccord, this field will be the summary field for the store page of its primary sku */ + summary: string; + /** the base64 enccoded key for the GameSDK'S GetTicket */ + verify_key: string; + /** if the application belongs to a team, this will be a list of the members of that team */ + team: DiscordTeam | null; + /** if this application is a game sold on Discord, this field will be the guild to which it has been linked */ + guild_id?: string; + /** if this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists */ + primary_sku_id?: string; + /** if this application is a game sold on Discord, this field will be the URL slug that links to the store page */ + slug?: string; + /** if this application is a game sold on Discord, this field wil be the hash of the image on store embeds */ + cover_image?: string; + /** the application's public flags */ + flags: number; +} diff --git a/src/types/api/permission.ts b/src/types/api/permission.ts new file mode 100644 index 000000000..fa6708c4e --- /dev/null +++ b/src/types/api/permission.ts @@ -0,0 +1,10 @@ +export interface DiscordOverwrite { + /** role or user id */ + id: string; + /** either 0 (role) or 1 (member) */ + type: number; + /** permission bit set */ + allow: string; + /** permission bit set */ + deny: string; +} diff --git a/src/types/api/ratelimits.ts b/src/types/api/ratelimits.ts new file mode 100644 index 000000000..b7fa5725d --- /dev/null +++ b/src/types/api/ratelimits.ts @@ -0,0 +1,9 @@ +/** https://discord.com/developers/docs/topics/rate-limits#exceeding-a-rate-limit */ +export interface DiscordRateLimitResponse { + /** a message saying you are being rate limited */ + message: string; + /** the number of seconds to wait before submitting another request. */ + retry_after: number; + /** a value indicating if you are being globally limited or not */ + global: boolean; +} diff --git a/src/types/api/role.ts b/src/types/api/role.ts new file mode 100644 index 000000000..02f70a0ad --- /dev/null +++ b/src/types/api/role.ts @@ -0,0 +1,31 @@ +/** https://discord.com/developers/docs/topics/permissions#role-object-role-structure */ +export interface DiscordRole { + /** role id */ + id: string; + /** role name */ + name: string; + /** number representation of hexadecimal color code */ + color: number; + /** if this role is pinned in the user listing */ + hoist: boolean; + /** position of this role */ + position: number; + /** permission bit set */ + permissions: string; + /** whether this role is managed by an integration */ + managed: boolean; + /** whether this role is mentionable */ + mentionable: boolean; + /** the tags this role has */ + tags?: DiscordRoleTags; +} + +/** https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure */ +export interface DiscordRoleTags { + /** the id of the bot this role belongs to */ + bot_id?: string; + /** the id of the integration this role belongs to */ + integration_id?: string; + /** whether this is the guild's premium subscriber role */ + premium_subscriber?: null; +} diff --git a/src/types/api/teams.ts b/src/types/api/teams.ts new file mode 100644 index 000000000..3e7624ce2 --- /dev/null +++ b/src/types/api/teams.ts @@ -0,0 +1,31 @@ +import { DiscordBaseUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/topics/teams#data-models-team-object */ +export interface DiscordTeam { + /** a hash of the image of the team's icon */ + icon: string | null; + /** the unique id of the team */ + id: string; + /** the members of the team */ + members: DiscordTeamMembers[]; + /** the user id of the current team owner */ + owner_user_id: string; +} + +/** https://discord.com/developers/docs/topics/teams#data-models-team-members-object */ +export interface DiscordTeamMembers { + /** the user's membership state on the team */ + membership_state: keyof typeof DiscordMembershipState; + /** will always be ["*"] */ + permissions: string[]; + /** the id of the parent team of which they are a member */ + team_id: string; + /** the avatar, discriminator, id, and username of the user */ + user: DiscordBaseUser; +} + +/** https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum */ +export enum DiscordMembershipState { + INVITED = 1, + ACCEPTED, +} diff --git a/src/types/api/template.ts b/src/types/api/template.ts new file mode 100644 index 000000000..20a3ba781 --- /dev/null +++ b/src/types/api/template.ts @@ -0,0 +1,51 @@ +import { DiscordGuild, DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/template#template-resource */ +export interface DiscordTemplate { + /** the template code (unique ID) */ + code: string; + /** template name */ + name: string; + /** the description for the template */ + description: string | null; + /** number of times this template has been used */ + usage_count: number; + /** the ID of teh user who created the template */ + creator_id: string; + /** the user who created the template */ + creator: DiscordUser; + /** when this template was created*/ + created_at: string; + /** when this template was last synced to the source guild */ + updated_at: string; + /** the ID of the guild this template is based on */ + source_guild_id: string; + /** the guild snapshot this template contains */ + serialized_source_guild: Partial; + /** whether the template has unsynced changes */ + is_dirty: boolean | null; +} + +/** https://discord.com/developers/docs/resources/template#create-guild-from-template */ +export interface DiscordCreateGuildFromTemplateParams { + /** name of the guild (2-100 characters) */ + name: string; + /** base64 128x128 image for the guild icon */ + icon?: string; +} + +/** https://discord.com/developers/docs/resources/template#create-guild-template */ +export interface DiscordCreateGuildTemplateParams { + /** name of the template (1-100 characters) */ + name: string; + /** description for the template (0-120 characters) */ + description?: string | null; +} + +/** https://discord.com/developers/docs/resources/template#modify-guild-template */ +export interface DiscordModifyGuildTemplateParams { + /** name of the template (1-100 characters) */ + name?: string; + /** description for the template (0-120 characters) */ + description?: string | null; +} diff --git a/src/types/api/voice.ts b/src/types/api/voice.ts new file mode 100644 index 000000000..b2d3bd7fd --- /dev/null +++ b/src/types/api/voice.ts @@ -0,0 +1,14 @@ +export interface DiscordVoiceRegion { + /** unique ID for the region */ + id: string; + /** name of the region */ + name: string; + /** true if this is a vip-only server */ + vip: boolean; + /** true for a single server that is closet to the current user's client */ + optimal: boolean; + /** whether this is a deprecated voice region (avoid switching to these) */ + deprecated: boolean; + /** whether this is a custom voice region (used for events/etc) */ + custom: boolean; +} diff --git a/src/types/api/webhook.ts b/src/types/api/webhook.ts new file mode 100644 index 000000000..bf2a9766a --- /dev/null +++ b/src/types/api/webhook.ts @@ -0,0 +1,31 @@ +import { DiscordUser } from "./mod.ts"; + +/** https://discord.com/developers/docs/resources/webhook#webhook-resource */ +export interface DiscordWebhook { + /** the id of the webhook */ + id: string; + /** the type of the webhook */ + type: DiscordWebhookTypes; + /** the guild id this webhook is for */ + guild_id?: string; + /** the channel id this webhook is for */ + channel_id: string; + /** the user this webhook was created by (not returned when getting a webhook with its token) */ + user?: DiscordUser; + /** the default name of the webhook */ + name: string | null; + /** the default avatar of the webhook */ + avatar: string | null; + /** the secure token of the webhook (returned for Incoming Webhooks) */ + token?: string; + /** the bot/OAuth2 application that created this webhook */ + application_id: string | null; +} + +/** https://discord.com/developers/docs/resources/webhook#webhook-resource */ +export enum DiscordWebhookTypes { + /** Incoming Webhook can post messages to channels with a generated token */ + INCOMING = 1, + /** Channel Follower Webhooks are internal webhooks used with Channel Following to post new messages into channels */ + CHANNEL_FOLLOWER, +} diff --git a/src/types/cdn.ts b/src/types/cdn.ts index 605617838..220aaa077 100644 --- a/src/types/cdn.ts +++ b/src/types/cdn.ts @@ -1,2 +1,6 @@ +// TODO: v11 Remove +/** @deprecated Use DiscordImageSize */ export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048; +// TODO: v11 Remove +/** @deprecated Use DiscordImageFormat */ export type ImageFormats = "jpg" | "jpeg" | "png" | "webp" | "gif"; diff --git a/src/types/errors.ts b/src/types/errors.ts index fe9582e7e..cc64e5b3c 100644 --- a/src/types/errors.ts +++ b/src/types/errors.ts @@ -1,48 +1,73 @@ export enum Errors { - MISSING_SEND_MESSAGES = "MISSING_SEND_MESSAGES", - MISSING_MANAGE_ROLES = "MISSING_MANAGE_ROLES", - MISSING_KICK_MEMBERS = "MISSING_KICK_MEMBERS", - MISSING_VIEW_CHANNEL = "MISSING_VIEW_CHANNEL", - MISSING_READ_MESSAGE_HISTORY = "MISSING_READ_MESSAGE_HISTORY", - MISSING_MANAGE_NICKNAMES = "MISSING_MANAGE_NICKNAMES", - MISSING_MUTE_MEMBERS = "MISSING_MUTE_MEMBERS", - MISSING_DEAFEN_MEMBERS = "MISSING_DEAFEN_MEMBERS", - MISSING_SEND_TTS_MESSAGE = "MISSING_SEND_TTS_MESSAGE", - MISSING_MANAGE_MESSAGES = "MISSING_MANAGE_MESSAGES", - MISSING_MANAGE_CHANNELS = "MISSING_MANAGE_CHANNELS", - MISSING_CREATE_INSTANT_INVITE = "MISSING_CREATE_INSTANT_INVITE", - MISSING_MANAGE_WEBHOOKS = "MISSING_MANAGE_WEBHOOKS", - MISSING_MANAGE_EMOJIS = "MISSING_MANAGE_EMOJIS", - MISSING_BAN_MEMBERS = "MISSING_BAN_MEMBERS", - MISSING_MANAGE_GUILD = "MISSING_MANAGE_GUILD", - MISSING_VIEW_AUDIT_LOG = "MISSING_VIEW_AUDIT_LOG", - MISSING_EMBED_LINKS = "MISSING_EMBED_LINKS", - MISSING_ADD_REACTIONS = "MISSING_ADD_REACTIONS", - DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN", + // Bot Role errors + BOTS_HIGHEST_ROLE_TOO_LOW = "BOTS_HIGHEST_ROLE_TOO_LOW", + // Channel Errors + CHANNEL_NOT_FOUND = "CHANNEL_NOT_FOUND", + CHANNEL_NOT_IN_GUILD = "CHANNEL_NOT_IN_GUILD", + CHANNEL_NOT_TEXT_BASED = "CHANNEL_NOT_TEXT_BASED", MESSAGE_MAX_LENGTH = "MESSAGE_MAX_LENGTH", - NICKNAMES_MAX_LENGTH = "NICKNAMES_MAX_LENGTH", + RULES_CHANNEL_CANNOT_BE_DELETED = "RULES_CHANNEL_CANNOT_BE_DELETED", + UPDATES_CHANNEL_CANNOT_BE_DELETED = "UPDATES_CHANNEL_CANNOT_BE_DELETED", + // Guild Errors + GUILD_NOT_DISCOVERABLE = "GUILD_NOT_DISCOVERABLE", + GUILD_NOT_FOUND = "GUILD_NOT_FOUND", + MEMBER_NOT_FOUND = "MEMBER_NOT_FOUND", + PRUNE_MAX_DAYS = "PRUNE_MAX_DAYS", + ROLE_NOT_FOUND = "ROLE_NOT_FOUND", + // Message Delete Errors + DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN", PRUNE_MIN_DAYS = "PRUNE_MIN_DAYS", - RATE_LIMIT_RETRY_MAXED = "RATE_LIMIT_RETRY_MAXED", + // Interaction Errors + INVALID_SLASH_DESCRIPTION = "INVALID_SLASH_DESCRIPTION", + INVALID_SLASH_NAME = "INVALID_SLASH_NAME", + // Webhook Errors + INVALID_WEBHOOK_NAME = "INVALID_WEBHOOK_NAME", + INVALID_WEBHOOK_OPTIONS = "INVALID_WEBHOOK_OPTIONS", + // Permission Errors + MISSING_ADD_REACTIONS = "MISSING_ADD_REACTIONS", + MISSING_ADMINISTRATOR = "MISSING_ADMINISTRATOR", + MISSING_ATTACH_FILES = "MISSING_ATTACH_FILES", + MISSING_BAN_MEMBERS = "MISSING_BAN_MEMBERS", + MISSING_CHANGE_NICKNAME = "MISSING_CHANGE_NICKNAME", + MISSING_CONNECT = "MISSING_CONNECT", + MISSING_CREATE_INSTANT_INVITE = "MISSING_CREATE_INSTANT_INVITE", + MISSING_DEAFEN_MEMBERS = "MISSING_DEAFEN_MEMBERS", + MISSING_EMBED_LINKS = "MISSING_EMBED_LINKS", MISSING_INTENT_GUILD_MEMBERS = "MISSING_INTENT_GUILD_MEMBERS", + MISSING_KICK_MEMBERS = "MISSING_KICK_MEMBERS", + MISSING_MANAGE_CHANNELS = "MISSING_MANAGE_CHANNELS", + MISSING_MANAGE_EMOJIS = "MISSING_MANAGE_EMOJIS", + MISSING_MANAGE_GUILD = "MISSING_MANAGE_GUILD", + MISSING_MANAGE_MESSAGES = "MISSING_MANAGE_MESSAGES", + MISSING_MANAGE_NICKNAMES = "MISSING_MANAGE_NICKNAMES", + MISSING_MANAGE_ROLES = "MISSING_MANAGE_ROLES", + MISSING_MANAGE_WEBHOOKS = "MISSING_MANAGE_WEBHOOKS", + MISSING_MENTION_EVERYONE = "MISSING_MENTION_EVERYONE", + MISSING_MOVE_MEMBERS = "MISSING_MOVE_MEMBERS", + MISSING_MUTE_MEMBERS = "MISSING_MUTE_MEMBERS", + MISSING_PRIORITY_SPEAKER = "MISSING_PRIORITY_SPEAKER", + MISSING_READ_MESSAGE_HISTORY = "MISSING_READ_MESSAGE_HISTORY", + MISSING_SEND_MESSAGES = "MISSING_SEND_MESSAGES", + // TODO: Remove v11 + /** @deprecated Use MISSING_SEND_TTS_MESSAGES */ + MISSING_SEND_TTS_MESSAGE = "MISSING_SEND_TTS_MESSAGE", + MISSING_SEND_TTS_MESSAGES = "MISSING_SEND_TTS_MESSAGES", + MISSING_SPEAK = "MISSING_SPEAK", + MISSING_STREAM = "MISSING_STREAM", + MISSING_USE_VAD = "MISSING_USE_VAD", + MISSING_USE_EXTERNAL_EMOJIS = "MISSING_USE_EXTERNAL_EMOJIS", + MISSING_VIEW_AUDIT_LOG = "MISSING_VIEW_AUDIT_LOG", + MISSING_VIEW_CHANNEL = "MISSING_VIEW_CHANNEL", + MISSING_VIEW_GUILD_INSIGHTS = "MISSING_VIEW_GUILD_INSIGHTS", + // User Errors + NICKNAMES_MAX_LENGTH = "NICKNAMES_MAX_LENGTH", + USERNAME_INVALID_CHARACTER = "USERNAME_INVALID_CHARACTER", + USERNAME_INVALID_USERNAME = "USERNAME_INVALID_USERNAME", + USERNAME_MAX_LENGTH = "USERNAME_MAX_LENGTH", + USERNAME_MIN_LENGTH = "USERNAME_MIN_LENGTH", + // API Errors + RATE_LIMIT_RETRY_MAXED = "RATE_LIMIT_RETRY_MAXED", REQUEST_CLIENT_ERROR = "REQUEST_CLIENT_ERROR", REQUEST_SERVER_ERROR = "REQUEST_SERVER_ERROR", REQUEST_UNKNOWN_ERROR = "REQUEST_UNKNOWN_ERROR", - BOTS_HIGHEST_ROLE_TOO_LOW = "BOTS_HIGHEST_ROLE_TOO_LOW", - CHANNEL_NOT_IN_GUILD = "CHANNEL_NOT_IN_GUILD", - INVALID_WEBHOOK_NAME = "INVALID_WEBHOOK_NAME", - INVALID_SLASH_NAME = "INVALID_SLASH_NAME", - INVALID_SLASH_DESCRIPTION = "INVALID_SLASH_DESCRIPTION", - INVALID_WEBHOOK_OPTIONS = "INVALID_WEBHOOK_OPTIONS", - CHANNEL_NOT_FOUND = "CHANNEL_NOT_FOUND", - CHANNEL_NOT_TEXT_BASED = "CHANNEL_NOT_TEXT_BASED", - USERNAME_MAX_LENGTH = "USERNAME_MAX_LENGTH", - USERNAME_MIN_LENGTH = "USERNAME_MIN_LENGTH", - USERNAME_INVALID_CHARACTER = "USERNAME_INVALID_CHARACTER", - USERNAME_INVALID_USERNAME = "USERNAME_INVALID_USERNAME", - RULES_CHANNEL_CANNOT_BE_DELETED = "RULES_CHANNEL_CANNOT_BE_DELETED", - UPDATES_CHANNEL_CANNOT_BE_DELETED = "UPDATES_CHANNEL_CANNOT_BE_DELETED", - GUILD_NOT_FOUND = "GUILD_NOT_FOUND", - PRUNE_MAX_DAYS = "PRUNE_MAX_DAYS", - GUILD_NOT_DISCOVERABLE = "GUILD_NOT_DISCOVERABLE", - MISSING_CHANGE_NICKNAME = "MISSING_CHANGE_NICKNAME", } diff --git a/src/types/guild.ts b/src/types/guild.ts index 15deb3035..74f45390d 100644 --- a/src/types/guild.ts +++ b/src/types/guild.ts @@ -176,6 +176,8 @@ export type GuildFeatures = | "ANIMATED_ICON" | "BANNER"; +// TODO: v11 Remove +/** @deprecated Use DiscordVoiceRegion */ export interface VoiceRegion { /** unique ID for the region */ id: string; diff --git a/src/types/interactions.ts b/src/types/interactions.ts index daac3f5d1..dc405be01 100644 --- a/src/types/interactions.ts +++ b/src/types/interactions.ts @@ -94,6 +94,8 @@ export interface ApplicationCommandOptionChoice { value: string | number; } +// TODO: v11 Remove +/** @deprecated Use DiscordApplicationCommandEvent */ export type ApplicationCommandEvent = ApplicationCommand & { /** id of the guild the command is in */ guild_id?: string; diff --git a/src/types/message.ts b/src/types/message.ts index e18b66db1..24f036a95 100644 --- a/src/types/message.ts +++ b/src/types/message.ts @@ -141,6 +141,8 @@ export interface Reaction { emoji: EmojiReaction; } +// TODO: v11 Remove +/** @deprecated Use DiscordMessageTypes */ export enum MessageTypes { DEFAULT, RECIPIENT_ADD, diff --git a/src/types/mod.ts b/src/types/mod.ts index c4128d9d8..13ca88bb5 100644 --- a/src/types/mod.ts +++ b/src/types/mod.ts @@ -14,3 +14,4 @@ export * from "./permission.ts"; export * from "./presence.ts"; export * from "./role.ts"; export * from "./webhook.ts"; +export * from "./api/mod.ts"; diff --git a/src/types/util.ts b/src/types/util.ts index 43af12643..2a02f1f50 100644 --- a/src/types/util.ts +++ b/src/types/util.ts @@ -6,4 +6,5 @@ export type CamelizeString = T extends string : T : T; -export type Camelize = { [K in keyof T as CamelizeString]: T[K] } +// deno-fmt-ignore +export type Camelize = { [K in keyof T as CamelizeString]: T[K] };