From 1c2ddb2bb5b105d4d2778c418acec8b151e22551 Mon Sep 17 00:00:00 2001 From: Toastie Date: Thu, 12 Sep 2024 18:00:57 +1200 Subject: [PATCH] Added rest files --- rest/common.ts | 316 ++++++++ rest/index.ts | 4 + rest/v9/application.ts | 16 + rest/v9/auditLog.ts | 32 + rest/v9/autoModeration.ts | 84 +++ rest/v9/channel.ts | 771 ++++++++++++++++++++ rest/v9/emoji.ts | 62 ++ rest/v9/gateway.ts | 11 + rest/v9/guild.ts | 929 ++++++++++++++++++++++++ rest/v9/guildScheduledEvent.ts | 145 ++++ rest/v9/index.ts | 1248 ++++++++++++++++++++++++++++++++ rest/v9/interactions.ts | 283 ++++++++ rest/v9/invite.ts | 27 + rest/v9/oauth2.ts | 199 +++++ rest/v9/stageInstance.ts | 61 ++ rest/v9/sticker.ts | 81 +++ rest/v9/template.ts | 72 ++ rest/v9/user.ts | 131 ++++ rest/v9/voice.ts | 11 + rest/v9/webhook.ts | 276 +++++++ utils/index.ts | 4 + utils/internals.ts | 41 ++ utils/v9.ts | 177 +++++ 23 files changed, 4981 insertions(+) create mode 100644 rest/common.ts create mode 100644 rest/index.ts create mode 100644 rest/v9/application.ts create mode 100644 rest/v9/auditLog.ts create mode 100644 rest/v9/autoModeration.ts create mode 100644 rest/v9/channel.ts create mode 100644 rest/v9/emoji.ts create mode 100644 rest/v9/gateway.ts create mode 100644 rest/v9/guild.ts create mode 100644 rest/v9/guildScheduledEvent.ts create mode 100644 rest/v9/index.ts create mode 100644 rest/v9/interactions.ts create mode 100644 rest/v9/invite.ts create mode 100644 rest/v9/oauth2.ts create mode 100644 rest/v9/stageInstance.ts create mode 100644 rest/v9/sticker.ts create mode 100644 rest/v9/template.ts create mode 100644 rest/v9/user.ts create mode 100644 rest/v9/voice.ts create mode 100644 rest/v9/webhook.ts create mode 100644 utils/index.ts create mode 100644 utils/internals.ts create mode 100644 utils/v9.ts diff --git a/rest/common.ts b/rest/common.ts new file mode 100644 index 0000000..1b98f4e --- /dev/null +++ b/rest/common.ts @@ -0,0 +1,316 @@ +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes + */ +export enum RESTJSONErrorCodes { + GeneralError, + + UnknownAccount = 10001, + UnknownApplication, + UnknownChannel, + UnknownGuild, + UnknownIntegration, + UnknownInvite, + UnknownMember, + UnknownMessage, + UnknownPermissionOverwrite, + UnknownProvider, + UnknownRole, + UnknownToken, + UnknownUser, + UnknownEmoji, + UnknownWebhook, + UnknownWebhookService, + + UnknownSession = 10020, + + UnknownBan = 10026, + UnknownSKU, + UnknownStoreListing, + UnknownEntitlement, + UnknownBuild, + UnknownLobby, + UnknownBranch, + UnknownStoreDirectoryLayout, + + UnknownRedistributable = 10036, + + UnknownGiftCode = 10038, + + UnknownStream = 10049, + UnknownPremiumServerSubscribeCooldown, + + UnknownGuildTemplate = 10057, + + UnknownDiscoverableServerCategory = 10059, + UnknownSticker, + + UnknownInteraction = 10062, + UnknownApplicationCommand, + + UnknownVoiceState = 10065, + UnknownApplicationCommandPermissions, + UnknownStageInstance, + UnknownGuildMemberVerificationForm, + UnknownGuildWelcomeScreen, + UnknownGuildScheduledEvent, + UnknownGuildScheduledEventUser, + + UnknownTag = 10087, + + BotsCannotUseThisEndpoint = 20001, + OnlyBotsCanUseThisEndpoint, + + ExplicitContentCannotBeSentToTheDesiredRecipient = 20009, + + NotAuthorizedToPerformThisActionOnThisApplication = 20012, + + ActionCannotBePerformedDueToSlowmodeRateLimit = 20016, + TheMazeIsntMeantForYou, + OnlyTheOwnerOfThisAccountCanPerformThisAction, + + AnnouncementEditLimitExceeded = 20022, + + UnderMinimumAge = 20024, + + ChannelSendRateLimit = 20028, + ServerSendRateLimit, + + StageTopicServerNameServerDescriptionOrChannelNamesContainDisallowedWords = 20031, + + GuildPremiumSubscriptionLevelTooLow = 20035, + + MaximumNumberOfGuildsReached = 30001, + MaximumNumberOfFriendsReached, + MaximumNumberOfPinsReachedForTheChannel, + MaximumNumberOfRecipientsReached, + MaximumNumberOfGuildRolesReached, + + MaximumNumberOfWebhooksReached = 30007, + MaximumNumberOfEmojisReached, + + MaximumNumberOfReactionsReached = 30010, + MaximumNumberOfGroupDMsReached, + + MaximumNumberOfGuildChannelsReached = 30013, + + MaximumNumberOfAttachmentsInAMessageReached = 30015, + MaximumNumberOfInvitesReached, + + MaximumNumberOfAnimatedEmojisReached = 30018, + MaximumNumberOfServerMembersReached, + + MaximumNumberOfServerCategoriesReached = 30030, + + GuildAlreadyHasTemplate = 30031, + MaximumNumberOfApplicationCommandsReached, + MaximumThreadParticipantsReached, + MaximumDailyApplicationCommandCreatesReached, + MaximumNumberOfNonGuildMemberBansHasBeenExceeded, + + MaximumNumberOfBanFetchesHasBeenReached = 30037, + MaximumNumberOfUncompletedGuildScheduledEventsReached, + + MaximumNumberOfStickersReached = 30039, + MaximumNumberOfPruneRequestsHasBeenReached, + + MaximumNumberOfGuildWidgetSettingsUpdatesHasBeenReached = 30042, + + MaximumNumberOfEditsToMessagesOlderThanOneHourReached = 30046, + MaximumNumberOfPinnedThreadsInForumHasBeenReached, + MaximumNumberOfTagsInForumHasBeenReached, + + BitrateIsTooHighForChannelOfThisType = 30052, + + MaximumNumberOfPremiumEmojisReached = 30056, + + MaximumNumberOfWebhooksPerGuildReached = 30058, + + MaximumNumberOfChannelPermissionOverwritesReached = 30060, + TheChannelsForThisGuildAreTooLarge, + + Unauthorized = 40001, + VerifyYourAccount, + OpeningDirectMessagesTooFast, + SendMessagesHasBeenTemporarilyDisabled, + RequestEntityTooLarge, + FeatureTemporarilyDisabledServerSide, + UserBannedFromThisGuild, + + ConnectionHasBeenRevoked = 40012, + + TargetUserIsNotConnectedToVoice = 40032, + ThisMessageWasAlreadyCrossposted, + + ApplicationCommandWithThatNameAlreadyExists = 40041, + + ApplicationInteractionFailedToSend = 40043, + + CannotSendAMessageInAForumChannel = 40058, + + InteractionHasAlreadyBeenAcknowledged = 40060, + TagNamesMustBeUnique, + ServiceResourceIsBeingRateLimited, + + ThereAreNoTagsAvailableThatCanBeSetByNonModerators = 40066, + TagRequiredToCreateAForumPostInThisChannel, + + MissingAccess = 50001, + InvalidAccountType, + CannotExecuteActionOnDMChannel, + GuildWidgetDisabled, + CannotEditMessageAuthoredByAnotherUser, + CannotSendAnEmptyMessage, + CannotSendMessagesToThisUser, + CannotSendMessagesInNonTextChannel, + ChannelVerificationLevelTooHighForYouToGainAccess, + OAuth2ApplicationDoesNotHaveBot, + OAuth2ApplicationLimitReached, + InvalidOAuth2State, + MissingPermissions, + InvalidToken, + NoteWasTooLong, + ProvidedTooFewOrTooManyMessagesToDelete, + InvalidMFALevel, + + MessageCanOnlyBePinnedInTheChannelItWasSentIn = 50019, + InviteCodeInvalidOrTaken, + CannotExecuteActionOnSystemMessage, + + CannotExecuteActionOnThisChannelType = 50024, + InvalidOAuth2AccessToken, + MissingRequiredOAuth2Scope, + + InvalidWebhookToken = 50027, + InvalidRole, + + InvalidRecipients = 50033, + OneOfTheMessagesProvidedWasTooOldForBulkDelete, + InvalidFormBodyOrContentType, + InviteAcceptedToGuildWithoutTheBotBeingIn, + + InvalidActivityAction = 50039, + + InvalidAPIVersion = 50041, + + FileUploadedExceedsMaximumSize = 50045, + InvalidFileUploaded, + + CannotSelfRedeemThisGift = 50054, + InvalidGuild, + + InvalidRequestOrigin = 50067, + InvalidMessageType, + + PaymentSourceRequiredToRedeemGift = 50070, + + CannotModifyASystemWebhook = 50073, + CannotDeleteChannelRequiredForCommunityGuilds, + + CannotEditStickersWithinMessage = 50080, + InvalidStickerSent, + + InvalidActionOnArchivedThread = 50083, + InvalidThreadNotificationSettings, + ParameterEarlierThanCreation, + CommunityServerChannelsMustBeTextChannels, + + TheEntityTypeOfTheEventIsDifferentFromTheEntityYouAreTryingToStartTheEventFor = 50091, + + ServerNotAvailableInYourLocation = 50095, + + ServerNeedsMonetizationEnabledToPerformThisAction = 50097, + + ServerNeedsMoreBoostsToPerformThisAction = 50101, + + RequestBodyContainsInvalidJSON = 50109, + + OwnershipCannotBeMovedToABotUser = 50132, + + FailedToResizeAssetBelowTheMinimumSize = 50138, + + CannotMixSubscriptionAndNonSubscriptionRolesForAnEmoji = 50144, + CannotConvertBetweenPremiumEmojiAndNormalEmoji, + UploadedFileNotFound, + + YouDoNotHavePermissionToSendThisSticker = 50600, + + TwoFactorAuthenticationIsRequired = 60003, + + NoUsersWithDiscordTagExist = 80004, + + ReactionWasBlocked = 90001, + + ApplicationNotYetAvailable = 110001, + + APIResourceOverloaded = 130000, + + TheStageIsAlreadyOpen = 150006, + + CannotReplyWithoutPermissionToReadMessageHistory = 160002, + + ThreadAlreadyCreatedForMessage = 160004, + ThreadLocked, + MaximumActiveThreads, + MaximumActiveAnnouncementThreads, + + InvalidJSONForUploadedLottieFile = 170001, + UploadedLottiesCannotContainRasterizedImages, + StickerMaximumFramerateExceeded, + StickerFrameCountExceedsMaximumOf1000Frames, + LottieAnimationMaximumDimensionsExceeded, + StickerFramerateIsTooSmallOrTooLarge, + StickerAnimationDurationExceedsMaximumOf5Seconds, + + CannotUpdateAFinishedEvent = 180000, + + FailedToCreateStageNeededForStageEvent = 180002, + + MessageWasBlockedByAutomaticModeration = 200000, + TitleWasBlockedByAutomaticModeration, + + WebhooksPostedToForumChannelsMustHaveAThreadNameOrThreadId = 220001, + WebhooksPostedToForumChannelsCannotHaveBothAThreadNameAndThreadId, + WebhooksCanOnlyCreateThreadsInForumChannels, + WebhookServicesCannotBeUsedInForumChannels, + + MessageBlockedByHarmfulLinksFilter = 240000, +} + +/** + * https://discord.com/developers/docs/reference#locales + */ +export enum Locale { + Indonesian = 'id', + EnglishUS = 'en-US', + EnglishGB = 'en-GB', + Bulgarian = 'bg', + ChineseCN = 'zh-CN', + ChineseTW = 'zh-TW', + Croatian = 'hr', + Czech = 'cs', + Danish = 'da', + Dutch = 'nl', + Finnish = 'fi', + French = 'fr', + German = 'de', + Greek = 'el', + Hindi = 'hi', + Hungarian = 'hu', + Italian = 'it', + Japanese = 'ja', + Korean = 'ko', + Lithuanian = 'lt', + Norwegian = 'no', + Polish = 'pl', + PortugueseBR = 'pt-BR', + Romanian = 'ro', + Russian = 'ru', + SpanishES = 'es-ES', + Swedish = 'sv-SE', + Thai = 'th', + Turkish = 'tr', + Ukrainian = 'uk', + Vietnamese = 'vi', +} + +export type LocaleString = `${Locale}`; \ No newline at end of file diff --git a/rest/index.ts b/rest/index.ts new file mode 100644 index 0000000..d90fc16 --- /dev/null +++ b/rest/index.ts @@ -0,0 +1,4 @@ +// This file exports all the types available in the recommended API version +// Thereby, things MAY break in the future. Try sticking to imports from a specific version + +export * from './v9/index'; \ No newline at end of file diff --git a/rest/v9/application.ts b/rest/v9/application.ts new file mode 100644 index 0000000..655a78c --- /dev/null +++ b/rest/v9/application.ts @@ -0,0 +1,16 @@ +import type { APIApplicationRoleConnectionMetadata } from '../../payloads/v9/application'; + +/** + * https://discord.com/developers/docs/resources/application-role-connection-metadata#get-application-role-connection-metadata-records + */ +export type RESTGetAPIApplicationRoleConnectionMetadataResult = APIApplicationRoleConnectionMetadata[]; + +/** + * https://discord.com/developers/docs/resources/application-role-connection-metadata#update-application-role-connection-metadata-records + */ +export type RESTPutAPIApplicationRoleConnectionMetadataJSONBody = APIApplicationRoleConnectionMetadata[]; + +/** + * https://discord.com/developers/docs/resources/application-role-connection-metadata#update-application-role-connection-metadata-records + */ +export type RESTPutAPIApplicationRoleConnectionMetadataResult = APIApplicationRoleConnectionMetadata[]; \ No newline at end of file diff --git a/rest/v9/auditLog.ts b/rest/v9/auditLog.ts new file mode 100644 index 0000000..d83e013 --- /dev/null +++ b/rest/v9/auditLog.ts @@ -0,0 +1,32 @@ +import type { Snowflake } from '../../globals'; +import type { APIAuditLog, AuditLogEvent } from '../../payloads/v9/auditLog'; + +/** + * https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log + */ +export interface RESTGetAPIAuditLogQuery { + /** + * Filter the log for actions made by a user + */ + user_id?: Snowflake; + /** + * The type of audit log events + */ + action_type?: AuditLogEvent; + /** + * Filter the log before a certain entry ID + */ + before?: Snowflake; + /** + * Filter the log after a certain entry ID + */ + after?: Snowflake; + /** + * How many entiries are returned (default 50, minimum 1, maximum 100) + * + * @default 50 + */ + limit?: number; +} + +export type RESTGetAPIAuditLogResult = APIAuditLog; \ No newline at end of file diff --git a/rest/v9/autoModeration.ts b/rest/v9/autoModeration.ts new file mode 100644 index 0000000..436a146 --- /dev/null +++ b/rest/v9/autoModeration.ts @@ -0,0 +1,84 @@ +import type { Snowflake } from '../../globals'; +import type { + APIAutoModerationAction, + APIAutoModerationRule, + AutoModerationRuleEventType, + APIAutoModerationRuleTriggerMetadata, + AutoModerationRuleTriggerType, +} from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#list-auto-moderation-rules-for-guild + */ +export type RESTGetAPIAutoModerationRulesResult = APIAutoModerationRule[]; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#get-auto-moderation-rule + */ +export type RESTGetAPIAutoModerationRuleResult = APIAutoModerationRule; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#create-auto-moderation-rule + */ +export type RESTPostAPIAutoModerationRuleJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The rule name + */ + name: string; + /** + * The rule event type + */ + event_type: AutoModerationRuleEventType; + /** + * The rule trigger type + */ + trigger_type: AutoModerationRuleTriggerType; + /** + * The rule trigger metadata + * + * Can be omitted if the trigger type is {@link AutoModerationRuleTriggerType.HarmfulLink} or {@link AutoModerationRuleTriggerType.Spam} + */ + trigger_metadata?: APIAutoModerationRuleTriggerMetadata; + /** + * The actions which will execute when this rule is triggered + */ + actions: APIAutoModerationAction[]; + /** + * Whether this rule is enabled + * + * @default false + */ + enabled?: boolean; + /** + * The role ids that shouldn't be affected by this rule (Maximum of 20) + */ + exempt_roles?: Snowflake[]; + /** + * The channel ids that shouldn't be affected by this rule (Maximum of 50) + */ + exempt_channels?: Snowflake[]; +}>; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#create-auto-moderation-rule + */ +export type RESTPostAPIAutoModerationRuleResult = APIAutoModerationRule; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#modify-auto-moderation-rule + */ +export type RESTPatchAPIAutoModerationRuleJSONBody = Omit< + Partial, + 'trigger_type' +>; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#modify-auto-moderation-rule + */ +export type RESTPatchAPIAutoModerationRuleResult = APIAutoModerationRule; + +/** + * https://discord.com/developers/docs/resources/auto-moderation#delete-auto-moderation-rule + */ +export type RESTDeleteAPIAutoModerationRuleResult = never; \ No newline at end of file diff --git a/rest/v9/channel.ts b/rest/v9/channel.ts new file mode 100644 index 0000000..cc64fe2 --- /dev/null +++ b/rest/v9/channel.ts @@ -0,0 +1,771 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { + APIActionRowComponent, + APIAllowedMentions, + APIAttachment, + APIChannel, + APIEmbed, + APIExtendedInvite, + APIFollowedChannel, + APIMessage, + APIMessageActionRowComponent, + APIMessageReference, + APIThreadList, + APIThreadMember, + APIUser, + ChannelType, + InviteTargetType, + MessageFlags, + OverwriteType, + ThreadAutoArchiveDuration, + VideoQualityMode, + APIGuildForumTag, + APIGuildForumDefaultReactionEmoji, + SortOrderType, + ForumLayoutType, +} from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface, StrictPartial } from '../../utils/internals'; + +export interface APIChannelPatchOverwrite extends RESTPutAPIChannelPermissionJSONBody { + id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-channel + */ +export type RESTGetAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export type RESTPatchAPIChannelJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * 1-100 character channel name + * + * Channel types: all + */ + name?: string; + + /** + * The type of channel; only conversion between `text` and `news` + * is supported and only in guilds with the "NEWS" feature + * + * Channel types: text, news + */ + type?: ChannelType.GuildAnnouncement | ChannelType.GuildText; + /** + * The position of the channel in the left-hand listing + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + position?: number | null; + /** + * 0-1024 character channel topic (0-4096 characters for forum channels) + * + * Channel types: text, news, forum + */ + topic?: string | null; + /** + * Whether the channel is nsfw + * + * Channel types: text, voice, news, forum + */ + 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 + * + * Channel types: text, newsThread, publicThread, privateThread, forum + */ + rate_limit_per_user?: number | null; + /** + * The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers) + * + * Channel types: voice + */ + bitrate?: number | null; + /** + * The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit + * + * Channel types: voice + */ + user_limit?: number | null; + /** + * Channel or category-specific permissions + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + permission_overwrites?: APIChannelPatchOverwrite[] | null; + /** + * ID of the new parent category for a channel + * + * Channel types: text, voice, news + */ + parent_id?: Snowflake | null; + /** + * Voice region id for the voice or stage channel, automatic when set to `null` + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + rtc_region?: string | null; + /** + * The camera video quality mode of the voice channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes + */ + video_quality_mode?: VideoQualityMode | null; + /** + * Whether the thread should be archived + * + * Channel types: newsThread, publicThread, privateThread + */ + archived?: boolean; + /** + * The amount of time in minutes to wait before automatically archiving the thread + * + * Channel types: newsThread, publicThread, privateThread + */ + auto_archive_duration?: ThreadAutoArchiveDuration; + /** + * Whether the thread should be locked + * + * Channel types: newsThread, publicThread, privateThread + */ + locked?: boolean; + /** + * Default duration for newly created threads, in minutes, to automatically archive the thread after recent activity + * + * Channel types: text, news + */ + default_auto_archive_duration?: ThreadAutoArchiveDuration; + /** + * Whether non-moderators can add other non-moderators to the thread + * + * Channel types: privateThread + */ + invitable?: boolean; + /** + * The set of tags that can be used in a forum channel; limited to 20 + * + * Channel types: forum + */ + available_tags?: APIGuildForumTag[]; + /** + * The emoji to show in the add reaction button on a thread in a forum channel + * + * Channel types: forum + */ + default_reaction_emoji?: APIGuildForumDefaultReactionEmoji; + /** + * The initial `rate_limit_per_user` to set on newly created threads in a channel. + * This field is copied to the thread at creation time and does not live update + * + * Channel types: forum + */ + default_thread_rate_limit_per_user?: number | null; + /** + * The default sort order type used to order posts in a forum channel + * + * Channel types: forum + */ + default_sort_order?: SortOrderType | null; + /** + * The default layout type used to display posts in a forum channel + * + * Channel types: forum + */ + default_forum_layout?: ForumLayoutType; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export type RESTPatchAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#deleteclose-channel + */ +export type RESTDeleteAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export interface RESTGetAPIChannelMessagesQuery { + /** + * Get messages around this message ID + */ + around?: Snowflake; + /** + * Get messages before this message ID + */ + before?: Snowflake; + /** + * Get messages after this message ID + */ + after?: Snowflake; + /** + * Max number of messages to return (1-100) + * + * @default 50 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export type RESTGetAPIChannelMessagesResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-message + */ +export type RESTGetAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#message-reference-object-message-reference-structure + */ +export type APIMessageReferenceSend = StrictPartial & + Required> & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message + * + * @default true + */ + fail_if_not_exists?: boolean; + }>; + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * 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; + /** + * Embedded `rich` content (up to 6000 characters) + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embeds?: APIEmbed[]; + /** + * Embedded `rich` content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + * @deprecated Use `embeds` instead + */ + embed?: APIEmbed; + /** + * Allowed mentions for a message + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object + */ + allowed_mentions?: APIAllowedMentions; + /** + * Include to make your message a reply + * + * See https://discord.com/developers/docs/resources/channel#message-reference-object-message-reference-structure + */ + message_reference?: APIMessageReferenceSend; + /** + * The components to include with the message + * + * See https://discord.com/developers/docs/interactions/message-components#component-object + */ + components?: APIActionRowComponent[]; + /** + * IDs of up to 3 stickers in the server to send in the message + * + * See https://discord.com/developers/docs/resources/sticker#sticker-object + */ + sticker_ids?: [Snowflake] | [Snowflake, Snowflake] | [Snowflake, Snowflake, Snowflake]; + /** + * Attachment objects with filename and description + */ + attachments?: (Pick & Partial>)[]; + /** + * Message flags combined as a bitfield + */ + flags?: MessageFlags; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPostAPIChannelMessageJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#crosspost-message + */ +export type RESTPostAPIChannelMessageCrosspostResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#create-reaction + */ +export type RESTPutAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-own-reaction + */ +export type RESTDeleteAPIChannelMessageOwnReaction = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-user-reaction + */ +export type RESTDeleteAPIChannelMessageUserReactionResult = never; + +/* + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export interface RESTGetAPIChannelMessageReactionUsersQuery { + /** + * Get users after this user ID + */ + after?: Snowflake; + /** + * Max number of users to return (1-100) + * + * @default 25 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export type RESTGetAPIChannelMessageReactionUsersResult = APIUser[]; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions + */ +export type RESTDeleteAPIChannelAllMessageReactionsResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji + */ +export type RESTDeleteAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export type RESTPatchAPIChannelMessageJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The new message contents (up to 2000 characters) + */ + content?: string | null; + /** + * Embedded `rich` content (up to 6000 characters) + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embeds?: APIEmbed[] | null; + /** + * Embedded `rich` content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + * @deprecated Use `embeds` instead + */ + embed?: APIEmbed | null; + /** + * Edit the flags of a message (only `SUPPRESS_EMBEDS` can currently be set/unset) + * + * When specifying flags, ensure to include all previously set flags/bits + * in addition to ones that you are modifying + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-flags + */ + flags?: MessageFlags | null; + /** + * Allowed mentions for the message + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object + */ + allowed_mentions?: APIAllowedMentions | null; + /** + * Attached files to keep + * + * Starting with API v10, the `attachments` array must contain all attachments that should be present after edit, including **retained and new** attachments provided in the request body. + * + * See https://discord.com/developers/docs/resources/channel#attachment-object + */ + attachments?: (Pick & Partial>)[]; + /** + * The components to include with the message + * + * See https://discord.com/developers/docs/interactions/message-components#component-object + */ + components?: APIActionRowComponent[] | null; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export type RESTPatchAPIChannelMessageFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPatchAPIChannelMessageJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export type RESTPatchAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#delete-message + */ +export type RESTDeleteAPIChannelMessageResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export interface RESTPostAPIChannelMessagesBulkDeleteJSONBody { + /** + * An array of message ids to delete (2-100) + */ + messages: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export type RESTPostAPIChannelMessagesBulkDeleteResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export interface RESTPutAPIChannelPermissionJSONBody { + /** + * The bitwise value of all allowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + * + * @default "0" + */ + allow?: Permissions | null; + /** + * The bitwise value of all disallowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + * + * @default "0" + */ + deny?: Permissions | null; + /** + * `0` for a role or `1` for a member + */ + type: OverwriteType; +} + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export type RESTPutAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-invites + */ +export type RESTGetAPIChannelInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export type RESTPostAPIChannelInviteJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Duration of invite in seconds before expiry, or 0 for never + * + * @default 86400 (24 hours) + */ + max_age?: number; + /** + * Max number of uses or 0 for unlimited + * + * @default 0 + */ + max_uses?: number; + /** + * Whether this invite only grants temporary membership + * + * @default false + */ + temporary?: boolean; + /** + * If true, don't try to reuse a similar invite + * (useful for creating many unique one time use invites) + * + * @default false + */ + unique?: boolean; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ + target_type?: InviteTargetType; + /** + * The id of the user whose stream to display for this invite + * - Required if `target_type` is 1 + * - The user must be streaming in the channel + */ + target_user_id?: Snowflake; + /** + * The id of the embedded application to open for this invite + * - Required if `target_type` is 2 + * - The application must have the `EMBEDDED` flag + */ + target_application_id?: Snowflake; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export type RESTPostAPIChannelInviteResult = APIExtendedInvite; + +/** + * https://discord.com/developers/docs/resources/channel#delete-channel-permission + */ +export type RESTDeleteAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export interface RESTPostAPIChannelFollowersJSONBody { + /** + * ID of target channel + */ + webhook_channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export type RESTPostAPIChannelFollowersResult = APIFollowedChannel; + +/** + * https://discord.com/developers/docs/resources/channel#trigger-typing-indicator + */ +export type RESTPostAPIChannelTypingResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-pinned-messages + */ +export type RESTGetAPIChannelPinsResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#pin-message + */ +export type RESTPutAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#unpin-message + */ +export type RESTDeleteAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export type RESTPutAPIChannelRecipientJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Access token of a user that has granted your app the `gdm.join` scope + */ + access_token: string; + /** + * Nickname of the user being added + */ + nick?: string; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export type RESTPutAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient + */ +export type RESTDeleteAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-from-message + */ +export type RESTPostAPIChannelMessagesThreadsJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * 1-100 character thread name + */ + name: string; + /** + * The amount of time in minutes to wait before automatically archiving the thread + * + * The 3 day and 7 day archive durations require the server to be boosted. The [guild features](https://discord.com/developers/docs/resources/guild#guild-object-guild-features) will indicate if a server is able to use those settings. + */ + auto_archive_duration: ThreadAutoArchiveDuration; + /** + * Amount of seconds a user has to wait before sending another message (0-21600) + */ + rate_limit_per_user?: number; +}>; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel + */ +export type RESTPostAPIGuildForumThreadsJSONBody = RESTPostAPIChannelMessagesThreadsJSONBody & { + /** + * First message in the forum thread + */ + message: RESTPostAPIChannelMessageJSONBody; + /** + * The IDs of the set of tags that have been applied to a thread in a forum channel; limited to 5 + */ + applied_tags?: Snowflake[]; +}; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel + */ +export type RESTPostAPIGuildForumThreadsFormDataBody = RESTPostAPIChannelMessagesThreadsJSONBody & { + /** + * First message in the forum thread + */ + message: string; +}; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-from-message + */ +export type RESTPostAPIChannelMessagesThreadsResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-without-message + */ +export type RESTPostAPIChannelThreadsJSONBody = RESTPostAPIChannelMessagesThreadsJSONBody & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The type of thread to create + * + * In API v9, `type` defaults to `PRIVATE_THREAD`. + * In a future API version this will be changed to be a required field, with no default. + * + * See https://discord.com/developers/docs/resources/channel#channel-object-channel-types + * + * @default ChannelType.PrivateThread + */ + type?: ChannelType.AnnouncementThread | ChannelType.PublicThread | ChannelType.PrivateThread; + /** + * Whether non-moderators can add other non-moderators to the thread; only available when creating a private thread + */ + invitable?: boolean; + }>; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-without-message + */ +export type RESTPostAPIChannelThreadsResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#join-thread + */ +export type RESTPutAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#leave-thread + */ +export type RESTDeleteAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-thread-member + */ +export interface RESTGetAPIChannelThreadMemberQuery { + /** + * Whether to include a guild member object for the thread member + */ + with_member?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-thread-member + */ +export type RESTGetAPIChannelThreadMemberResult = APIThreadMember; + +/** + * https://discord.com/developers/docs/resources/channel#list-thread-members + */ +export interface RESTGetAPIChannelThreadMembersQuery { + /** + * Whether to include a guild member object for each thread member + */ + with_member?: boolean; + /** + * Get thread members after this user ID + */ + after?: Snowflake; + /** + * Max number of thread members to return (1-100). Defaults to 100 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#list-thread-members + */ +export type RESTGetAPIChannelThreadMembersResult = APIThreadMember[]; + +/* + * https://discord.com/developers/docs/resources/channel#list-public-archived-threads + */ +export interface RESTGetAPIChannelThreadsArchivedQuery { + /** + * Get threads before this id or ISO8601 timestamp + */ + before?: Snowflake | string; + /** + * Max number of thread to return + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#list-public-archived-threads + */ +export type RESTGetAPIChannelThreadsArchivedPublicResult = RESTGetAPIChannelUsersThreadsArchivedResult; + +/** + * https://discord.com/developers/docs/resources/channel#list-private-archived-threads + */ +export type RESTGetAPIChannelThreadsArchivedPrivateResult = RESTGetAPIChannelUsersThreadsArchivedResult; + +/** + * https://discord.com/developers/docs/resources/channel#list-active-threads + * + * @deprecated Removed in API v10, use [List Active Guild Threads](https://discord.com/developers/docs/resources/guild#list-active-guild-threads) instead. + */ +export type RESTGetAPIChannelThreadsResult = APIThreadList; + +/** + * https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads + */ +export type RESTGetAPIChannelUsersThreadsArchivedResult = APIThreadList; \ No newline at end of file diff --git a/rest/v9/emoji.ts b/rest/v9/emoji.ts new file mode 100644 index 0000000..b8f147f --- /dev/null +++ b/rest/v9/emoji.ts @@ -0,0 +1,62 @@ +import type { Snowflake } from '../../globals'; +import type { APIEmoji } from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/emoji#list-guild-emojis + */ +export type RESTGetAPIGuildEmojisResult = APIEmoji[]; + +/** + * https://discord.com/developers/docs/resources/emoji#get-guild-emoji + */ +export type RESTGetAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji-json-params + */ +export type RESTPostAPIGuildEmojiJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the emoji + */ + name: string; + /** + * The 128x128 emoji image + * + * https://discord.com/developers/docs/reference#image-data + */ + image: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[]; +}>; + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji + */ +export type RESTPostAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export type RESTPatchAPIGuildEmojiJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the emoji + */ + name?: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[] | null; +}>; + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export type RESTPatchAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#delete-guild-emoji + */ +export type RESTDeleteAPIGuildEmojiResult = never; \ No newline at end of file diff --git a/rest/v9/gateway.ts b/rest/v9/gateway.ts new file mode 100644 index 0000000..0ec6953 --- /dev/null +++ b/rest/v9/gateway.ts @@ -0,0 +1,11 @@ +import type { APIGatewayBotInfo, APIGatewayInfo } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway + */ +export type RESTGetAPIGatewayResult = APIGatewayInfo; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway-bot + */ +export type RESTGetAPIGatewayBotResult = APIGatewayBotInfo; \ No newline at end of file diff --git a/rest/v9/guild.ts b/rest/v9/guild.ts new file mode 100644 index 0000000..d8c2b09 --- /dev/null +++ b/rest/v9/guild.ts @@ -0,0 +1,929 @@ +import type { RESTPutAPIChannelPermissionJSONBody } from './channel'; +import type { Permissions, Snowflake } from '../../globals'; +import type { + APIBan, + APIChannel, + APIExtendedInvite, + APIGuild, + APIGuildIntegration, + APIGuildMember, + APIGuildMembershipScreening, + APIGuildPreview, + APIGuildWelcomeScreen, + APIGuildWidget, + APIGuildWidgetSettings, + APIRole, + APIThreadList, + APIVoiceRegion, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildFeature, + GuildMFALevel, + GuildSystemChannelFlags, + GuildVerificationLevel, + GuildWidgetStyle, + APIDMChannel, + APIGroupDMChannel, + APIChannelType, +} from '../../payloads/v9/index'; +import type { + AddUndefinedToPossiblyUndefinedPropertiesOfInterface, + DistributiveOmit, + DistributivePick, + Nullable, + StrictPartial, + StrictRequired, +} from '../../utils/internals'; + +export interface APIGuildCreateOverwrite extends RESTPutAPIChannelPermissionJSONBody { + id: number | string; +} + +export type APIGuildChannelResolvable = Exclude; +export type APIGuildCreatePartialChannel = StrictPartial< + DistributivePick< + APIGuildChannelResolvable, + | 'type' + | 'topic' + | 'nsfw' + | 'bitrate' + | 'user_limit' + | 'rate_limit_per_user' + | 'default_auto_archive_duration' + | 'position' + | 'rtc_region' + | 'video_quality_mode' + | 'flags' + | 'default_reaction_emoji' + | 'available_tags' + | 'default_sort_order' + | 'default_forum_layout' + > +> & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + name: string; + id?: number | string; + parent_id?: number | string | null; + permission_overwrites?: APIGuildCreateOverwrite[]; + }>; + +export interface APIGuildCreateRole extends RESTPostAPIGuildRoleJSONBody { + id: number | string; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export type RESTPostAPIGuildsJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter; + /** + * New guild roles + * + * **When using this parameter, the first member of the array is used to change properties of the guild's @everyone role. + * If you are trying to bootstrap a guild with additional roles, keep this in mind.** + * + * *When using this parameter, the required `id` field within each role object is an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions + * in a channel when also passing in channels with the channels array.* + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles?: APIGuildCreateRole[]; + /** + * New guild's channels + * + * **When using the channels parameter, the `position` field is ignored, and none of the default channels are created.** + * + * *When using the channels parameter, the `id` field within each channel object may be set to an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to create `GUILD_CATEGORY` channels + * by setting the `parent_id` field on any children to the category's id field. + * Category channels must be listed before any children.* + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channels?: APIGuildCreatePartialChannel[]; + /** + * ID for afk channel + */ + afk_channel_id?: number | Snowflake | null; + /** + * afk timeout in seconds, can be set to: `60`, `300`, `900`, `1800`, `3600` + */ + afk_timeout?: 60 | 300 | 900 | 1800 | 3600; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id?: number | Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; + /** + * Whether the boosts progress bar should be enabled. + */ + premium_progress_bar_enabled?: boolean; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export type RESTPostAPIGuildsResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-mfa-level + */ +export interface RESTPostAPIGuildsMFAJSONBody { + /** + * MFA level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-mfa-level + */ + level: GuildMFALevel; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-mfa-level + */ +export type RESTPostAPIGuildsMFAResult = RESTPostAPIGuildsMFAJSONBody; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export interface RESTGetAPIGuildQuery { + /** + * When `true`, will return approximate member and presence counts for the guild + * + * @default false + */ + with_counts?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export type RESTGetAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-preview + */ +export type RESTGetAPIGuildPreviewResult = APIGuildPreview; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export type RESTPatchAPIGuildJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * New name for the guild (2-100 characters) + */ + name?: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string | null; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel | null; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications | null; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter | null; + /** + * ID for afk channel + */ + afk_channel_id?: Snowflake | null; + /** + * afk timeout in seconds, can be set to: `60`, `300`, `900`, `1800`, `3600` + */ + afk_timeout?: 60 | 300 | 900 | 1800 | 3600; + /** + * base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the guild has `ANIMATED_ICON` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string | null; + /** + * User id to transfer guild ownership to (must be owner) + */ + owner_id?: Snowflake; + /** + * base64 16:9 png/jpeg image for the guild splash (when the guild has `INVITE_SPLASH` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + splash?: string | null; + /** + * base64 png/jpeg image for the guild discovery splash (when the guild has `DISCOVERABLE` feature) + */ + discovery_splash?: string | null; + /** + * base64 16:9 png/jpeg image for the guild banner (when the server has the `BANNER` feature; can be animated gif when the server has the `ANIMATED_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?: Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; + /** + * The id of the channel where Community guilds display rules and/or guidelines + */ + rules_channel_id?: Snowflake | null; + /** + * The id of the channel where admins and moderators of Community guilds receive notices from Discord + */ + public_updates_channel_id?: Snowflake | null; + /** + * The preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" + * + * @default "en-US" (if the value is set to `null`) + */ + preferred_locale?: string | null; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features?: GuildFeature[]; + /** + * The description for the guild + */ + description?: string | null; + /** + * Whether the boosts progress bar should be enabled. + */ + premium_progress_bar_enabled?: boolean; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export type RESTPatchAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild + */ +export type RESTDeleteAPIGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-channels + */ +export type RESTGetAPIGuildChannelsResult = APIChannel[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelJSONBody = DistributiveOmit; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsJSONBody = Array< + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Channel id + */ + id: Snowflake; + /** + * Sorting position of the channel + */ + position: number; + /** + * Sync channel overwrites with the new parent, when moving to a new `parent_id` + */ + lock_permissions?: boolean; + /** + * The new parent id of this channel + */ + parent_id?: Snowflake | null; + }> +>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#list-active-guild-threads + */ +export type RESTGetAPIGuildThreadsResult = Omit; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-member + */ +export type RESTGetAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export interface RESTGetAPIGuildMembersQuery { + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; + /** + * The highest user id in the previous page + * + * @default 0 + */ + after?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export type RESTGetAPIGuildMembersResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#search-guild-members + */ +export interface RESTGetAPIGuildMembersSearchQuery { + /** + * Query string to match username(s) and nickname(s) against + */ + query: string; + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; +} + +export type RESTGetAPIGuildMembersSearchResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export type RESTPutAPIGuildMemberJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * 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 `MANAGE_NICKNAMES` permission + */ + nick?: string; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[]; + /** + * 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; +}>; + +export type RESTPutAPIGuildMemberResult = APIGuildMember | never; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-member + */ +export type RESTPatchAPIGuildMemberJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Value to set users nickname to + * + * Requires `MANAGE_NICKNAMES` permission + */ + nick?: string | null; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[] | null; + /** + * Whether the user is muted in voice channels. Will throw a 400 if the user is not in a voice channel + * + * Requires `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 `DEAFEN_MEMBERS` permission + */ + deaf?: boolean | null; + /** + * ID of channel to move user to (if they are connected to voice) + * + * Requires `MOVE_MEMBERS` permission + */ + channel_id?: Snowflake | null; + /** + * Timestamp of when the time out will be removed; until then, they cannot interact with the guild + */ + communication_disabled_until?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export type RESTPatchAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + * + * @deprecated Use [Modify Current Member](https://discord.com/developers/docs/resources/guild#modify-current-member) instead. + */ +export type RESTPatchAPICurrentGuildMemberNicknameJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Value to set users nickname to + * + * Requires `CHANGE_NICKNAME` permission + */ + nick?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-member + */ +export type RESTPatchAPICurrentGuildMemberJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Value to set users nickname to + * + * Requires `CHANGE_NICKNAME` permission + */ + nick?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + * + * @deprecated Use [Modify Current Member](https://discord.com/developers/docs/resources/guild#modify-current-member) instead. + */ +export type RESTPatchAPICurrentGuildMemberNicknameResult = + StrictRequired; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member-role + */ +export type RESTPutAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member-role + */ +export type RESTDeleteAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member + */ +export type RESTDeleteAPIGuildMemberResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-bans + */ +export type RESTGetAPIGuildBansResult = APIBan[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-bans + */ +export interface RESTGetAPIGuildBansQuery { + /** + * Consider only users before given user id + */ + before?: Snowflake; + /** + * Consider only users after given user id + */ + after?: Snowflake; + /** + * Number of users to return (1-1000) + * + * @default 1000 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-ban + */ +export type RESTGetAPIGuildBanResult = APIBan; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export type RESTPutAPIGuildBanJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Number of days to delete messages for (0-7) + * + * @deprecated use `delete_message_seconds` instead + */ + delete_message_days?: number; + /** + * Number of seconds to delete messages for, between 0 and 604800 (7 days) + */ + delete_message_seconds?: number; + /** + * Reason for the ban + * + * @deprecated Removed in API v10, use the `X-Audit-Log-Reason` header instead. + */ + reason?: string; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export type RESTPutAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-ban + */ +export type RESTDeleteAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-roles + */ +export type RESTGetAPIGuildRolesResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export type RESTPostAPIGuildRoleJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the role + * + * @default "new role" + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + * + * @default "default role permissions in guild" + */ + permissions?: Permissions | null; + /** + * RGB color value + * + * @default 0 + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + * + * @default false + */ + hoist?: boolean | null; + /** + * The role's icon image (if the guild has the `ROLE_ICONS` feature) + */ + icon?: string | null; + /** + * The role's unicode emoji as a standard emoji (if the guild has the `ROLE_ICONS` feature) + */ + unicode_emoji?: string | null; + /** + * Whether the role should be mentionable + * + * @default false + */ + mentionable?: boolean | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export type RESTPostAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsJSONBody = Array< + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Role id + */ + id: Snowflake; + /** + * Sorting position of the role + */ + position?: number; + }> +>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export type RESTPatchAPIGuildRoleJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the role + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + */ + permissions?: Permissions | null; + /** + * RGB color value + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + */ + hoist?: boolean | null; + /** + * The role's icon image (if the guild has the `ROLE_ICONS` feature) + */ + icon?: string | null; + /** + * The role's unicode emoji as a standard emoji (if the guild has the `ROLE_ICONS` feature) + */ + unicode_emoji?: string | null; + /** + * Whether the role should be mentionable + */ + mentionable?: boolean | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export type RESTPatchAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-role + */ +export type RESTDeleteAPIGuildRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountQuery { + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Role(s) to include + * + * While this is typed as a string, it represents an array of + * role IDs delimited by commas + * + * See https://discord.com/developers/docs/resources/guild#get-guild-prune-count-query-string-params + */ + include_roles?: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountResult { + pruned: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export type RESTPostAPIGuildPruneJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Whether `pruned is returned, discouraged for large guilds + * + * @default true + */ + compute_prune_count?: boolean; + /** + * Role(s) to include + */ + include_roles?: Snowflake[]; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export interface RESTPostAPIGuildPruneResult { + pruned: number | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-voice-regions + */ +export type RESTGetAPIGuildVoiceRegionsResult = APIVoiceRegion[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-invites + */ +export type RESTGetAPIGuildInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-integrations + */ +export type RESTGetAPIGuildIntegrationsResult = APIGuildIntegration[]; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-integration + */ +export type RESTDeleteAPIGuildIntegrationResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-settings + */ +export type RESTGetAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsJSONBody = StrictPartial; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget + */ +export type RESTGetAPIGuildWidgetJSONResult = APIGuildWidget; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-vanity-url + */ +export interface RESTGetAPIGuildVanityUrlResult { + code: string | null; + uses: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-image + */ +export interface RESTGetAPIGuildWidgetImageQuery { + /** + * Style of the widget image returned + * + * @default "shield" + */ + style?: GuildWidgetStyle; +} + +/** + * Note: while the return type is `ArrayBuffer`, the expected result is + * a buffer of sorts (depends if in browser or on node.js/deno). + */ +export type RESTGetAPIGuildWidgetImageResult = ArrayBuffer; + +export type RESTGetAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +export type RESTPatchAPIGuildMemberVerificationJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Whether Membership Screening is enabled + */ + enabled?: boolean; + /** + * Array of field objects serialized in a string + */ + form_fields?: string; + /** + * The server description to show in the screening form + */ + description?: string | null; +}>; + +export type RESTPatchAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state + */ +export type RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The id of the channel the user is currently in + */ + channel_id?: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; + /** + * Sets the user's request to speak + */ + request_to_speak_timestamp?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state + */ +export type RESTPatchAPIGuildVoiceStateCurrentMemberResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#modify-user-voice-state + */ +export type RESTPatchAPIGuildVoiceStateUserJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The id of the channel the user is currently in + */ + channel_id: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-user-voice-state + */ +export type RESTPatchAPIGuildVoiceStateUserResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen + */ +export type RESTGetAPIGuildWelcomeScreenResult = APIGuildWelcomeScreen; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen + */ +export type RESTPatchAPIGuildWelcomeScreenJSONBody = Nullable> & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Whether the welcome screen is enabled + */ + enabled?: boolean | null; + }>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen + */ +export type RESTPatchAPIGuildWelcomeScreenResult = APIGuildWelcomeScreen; \ No newline at end of file diff --git a/rest/v9/guildScheduledEvent.ts b/rest/v9/guildScheduledEvent.ts new file mode 100644 index 0000000..b229ec8 --- /dev/null +++ b/rest/v9/guildScheduledEvent.ts @@ -0,0 +1,145 @@ +import type { Snowflake } from '../../globals'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface, StrictPartial } from '../../utils/internals'; +import type { + APIGuildScheduledEvent, + GuildScheduledEventEntityType, + GuildScheduledEventPrivacyLevel, + APIGuildScheduledEventEntityMetadata, + GuildScheduledEventStatus, + APIGuildScheduledEventUser, +} from '../../v9'; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild + */ +export interface RESTGetAPIGuildScheduledEventsQuery { + /** + * Whether to include number of users subscribed to each event + */ + with_user_count?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild + */ +export type RESTGetAPIGuildScheduledEventsResult = APIGuildScheduledEvent[]; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event + */ +export type RESTPostAPIGuildScheduledEventJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The stage channel id of the guild event + */ + channel_id?: Snowflake; + /** + * The name of the guild event + */ + name: string; + /** + * The privacy level of the guild event + */ + privacy_level: GuildScheduledEventPrivacyLevel; + /** + * The time to schedule the guild event at + */ + scheduled_start_time: string; + /** + * The time when the scheduled event is scheduled to end + */ + scheduled_end_time?: string; + /** + * The description of the guild event + */ + description?: string; + /** + * The scheduled entity type of the guild event + */ + entity_type?: GuildScheduledEventEntityType; + /** + * The entity metadata of the scheduled event + */ + entity_metadata?: APIGuildScheduledEventEntityMetadata; + /** + * The cover image of the scheduled event + */ + image?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event + */ +export type RESTPostAPIGuildScheduledEventResult = APIGuildScheduledEvent; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event + */ +export interface RESTGetAPIGuildScheduledEventQuery { + /** + * Whether to include number of users subscribed to this event + */ + with_user_count?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event + */ +export type RESTGetAPIGuildScheduledEventResult = APIGuildScheduledEvent; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event + */ +export type RESTPatchAPIGuildScheduledEventJSONBody = StrictPartial & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The status of the scheduled event + */ + status?: GuildScheduledEventStatus; + /** + * The entity metadata of the scheduled event + */ + entity_metadata?: APIGuildScheduledEventEntityMetadata | null; + /** + * The description of the guild event + */ + description?: string | null; + }>; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event + */ +export type RESTPatchAPIGuildScheduledEventResult = APIGuildScheduledEvent; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#delete-guild-scheduled-event + */ +export type RESTDeleteAPIGuildScheduledEventResult = never; + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users + */ +export interface RESTGetAPIGuildScheduledEventUsersQuery { + /** + * Number of users to receive from the event + * + * @default 100 + */ + limit?: number; + /** + * Whether to include guild member data if it exists + */ + with_member?: boolean; + /** + * Consider only users before given user id + */ + before?: Snowflake; + /** + * Consider only users after given user id + */ + after?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users + */ +export type RESTGetAPIGuildScheduledEventUsersResult = APIGuildScheduledEventUser[]; \ No newline at end of file diff --git a/rest/v9/index.ts b/rest/v9/index.ts new file mode 100644 index 0000000..fb8c267 --- /dev/null +++ b/rest/v9/index.ts @@ -0,0 +1,1248 @@ +import type { Snowflake } from '../../globals'; + +export * from '../common'; +export * from './application'; +export * from './auditLog'; +export * from './autoModeration'; +export * from './channel'; +export * from './emoji'; +export * from './gateway'; +export * from './guild'; +export * from './guildScheduledEvent'; +export * from './interactions'; +export * from './invite'; +export * from './oauth2'; +export * from './stageInstance'; +export * from './sticker'; +export * from './template'; +export * from './user'; +export * from './voice'; +export * from './webhook'; + +export const APIVersion = '9'; + +export const Routes = { + /** + * Route for: + * - GET `/applications/{application.id}/role-connections/metadata` + * - PUT `/applications/{application.id}/role-connections/metadata` + */ + applicationRoleConnectionMetadata(applicationId: Snowflake) { + return `/applications/${applicationId}/role-connections/metadata` as const; + }, + /** + * Route for: + * - GET `/guilds/{guild.id}/auto-moderation/rules` + * - POST `/guilds/{guild.id}/auto-moderation/rules` + */ + guildAutoModerationRules(guildId: Snowflake) { + return `/guilds/${guildId}/auto-moderation/rules` as const; + }, + + /** + * Routes for: + * - GET `/guilds/{guild.id}/auto-moderation/rules/{rule.id}` + * - PATCH `/guilds/{guild.id}/auto-moderation/rules/{rule.id}` + * - DELETE `/guilds/{guild.id}/auto-moderation/rules/{rule.id}` + */ + guildAutoModerationRule(guildId: Snowflake, ruleId: Snowflake) { + return `/guilds/${guildId}/auto-moderation/rules/${ruleId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/audit-logs` + */ + guildAuditLog(guildId: Snowflake) { + return `/guilds/${guildId}/audit-logs` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}` + * - PATCH `/channels/{channel.id}` + * - DELETE `/channels/{channel.id}` + */ + channel(channelId: Snowflake) { + return `/channels/${channelId}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages` + * - POST `/channels/{channel.id}/messages` + */ + channelMessages(channelId: Snowflake) { + return `/channels/${channelId}/messages` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}` + * - PATCH `/channels/{channel.id}/messages/{message.id}` + * - DELETE `/channels/{channel.id}/messages/{message.id}` + */ + channelMessage(channelId: Snowflake, messageId: Snowflake) { + return `/channels/${channelId}/messages/${messageId}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/{message.id}/crosspost` + */ + channelMessageCrosspost(channelId: Snowflake, messageId: Snowflake) { + return `/channels/${channelId}/messages/${messageId}/crosspost` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageOwnReaction(channelId: Snowflake, messageId: Snowflake, emoji: string) { + return `/channels/${channelId}/messages/${messageId}/reactions/${emoji}/@me` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{user.id}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageUserReaction(channelId: Snowflake, messageId: Snowflake, emoji: string, userId: Snowflake) { + return `/channels/${channelId}/messages/${messageId}/reactions/${emoji}/${userId}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageReaction(channelId: Snowflake, messageId: Snowflake, emoji: string) { + return `/channels/${channelId}/messages/${messageId}/reactions/${emoji}` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions` + */ + channelMessageAllReactions(channelId: Snowflake, messageId: Snowflake) { + return `/channels/${channelId}/messages/${messageId}/reactions` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/bulk-delete` + */ + channelBulkDelete(channelId: Snowflake) { + return `/channels/${channelId}/messages/bulk-delete` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/permissions/{overwrite.id}` + * - DELETE `/channels/{channel.id}/permissions/{overwrite.id}` + */ + channelPermission(channelId: Snowflake, overwriteId: Snowflake) { + return `/channels/${channelId}/permissions/${overwriteId}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/invites` + * - POST `/channels/{channel.id}/invites` + */ + channelInvites(channelId: Snowflake) { + return `/channels/${channelId}/invites` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/followers` + */ + channelFollowers(channelId: Snowflake) { + return `/channels/${channelId}/followers` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/typing` + */ + channelTyping(channelId: Snowflake) { + return `/channels/${channelId}/typing` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/pins` + */ + channelPins(channelId: Snowflake) { + return `/channels/${channelId}/pins` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/pins/{message.id}` + * - DELETE `/channels/{channel.id}/pins/{message.id}` + */ + channelPin(channelId: Snowflake, messageId: Snowflake) { + return `/channels/${channelId}/pins/${messageId}` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/recipients/{user.id}` + * - DELETE `/channels/{channel.id}/recipients/{user.id}` + */ + channelRecipient(channelId: Snowflake, userId: Snowflake) { + return `/channels/${channelId}/recipients/${userId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis` + * - POST `/guilds/{guild.id}/emojis` + */ + guildEmojis(guildId: Snowflake) { + return `/guilds/${guildId}/emojis` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis/{emoji.id}` + * - PATCH `/guilds/{guild.id}/emojis/{emoji.id}` + * - DELETE `/guilds/{guild.id}/emojis/{emoji.id}` + */ + guildEmoji(guildId: Snowflake, emojiId: Snowflake) { + return `/guilds/${guildId}/emojis/${emojiId}` as const; + }, + + /** + * Route for: + * - POST `/guilds` + */ + guilds() { + return '/guilds' as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}` + * - PATCH `/guilds/{guild.id}` + * - DELETE `/guilds/{guild.id}` + */ + guild(guildId: Snowflake) { + return `/guilds/${guildId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/preview` + */ + guildPreview(guildId: Snowflake) { + return `/guilds/${guildId}/preview` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/channels` + * - POST `/guilds/{guild.id}/channels` + * - PATCH `/guilds/{guild.id}/channels` + */ + guildChannels(guildId: Snowflake) { + return `/guilds/${guildId}/channels` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/{user.id}` + * - PUT `/guilds/{guild.id}/members/{user.id}` + * - PATCH `/guilds/{guild.id}/members/@me` + * - PATCH `/guilds/{guild.id}/members/{user.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}` + */ + guildMember(guildId: Snowflake, userId: Snowflake | '@me' = '@me') { + return `/guilds/${guildId}/members/${userId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members` + */ + guildMembers(guildId: Snowflake) { + return `/guilds/${guildId}/members` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/search` + */ + guildMembersSearch(guildId: Snowflake) { + return `/guilds/${guildId}/members/search` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/members/@me/nick` + * @deprecated Use {@link Routes.guildMember} instead. + */ + guildCurrentMemberNickname(guildId: Snowflake) { + return `/guilds/${guildId}/members/@me/nick` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + */ + guildMemberRole(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake) { + return `/guilds/${guildId}/members/${memberId}/roles/${roleId}` as const; + }, + + /** + * Route for: + * - POST `/guilds/{guild.id}/mfa` + */ + guildMFA(guildId: Snowflake) { + return `/guilds/${guildId}/mfa` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans` + */ + guildBans(guildId: Snowflake) { + return `/guilds/${guildId}/bans` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans/{user.id}` + * - PUT `/guilds/{guild.id}/bans/{user.id}` + * - DELETE `/guilds/{guild.id}/bans/{user.id}` + */ + guildBan(guildId: Snowflake, userId: Snowflake) { + return `/guilds/${guildId}/bans/${userId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/roles` + * - POST `/guilds/{guild.id}/roles` + * - PATCH `/guilds/{guild.id}/roles` + */ + guildRoles(guildId: Snowflake) { + return `/guilds/${guildId}/roles` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/roles/{role.id}` + */ + guildRole(guildId: Snowflake, roleId: Snowflake) { + return `/guilds/${guildId}/roles/${roleId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/prune` + * - POST `/guilds/{guild.id}/prune` + */ + guildPrune(guildId: Snowflake) { + return `/guilds/${guildId}/prune` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/regions` + */ + guildVoiceRegions(guildId: Snowflake) { + return `/guilds/${guildId}/regions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/invites` + */ + guildInvites(guildId: Snowflake) { + return `/guilds/${guildId}/invites` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/integrations` + */ + guildIntegrations(guildId: Snowflake) { + return `/guilds/${guildId}/integrations` as const; + }, + + /** + * Route for: + * - DELETE `/guilds/{guild.id}/integrations/{integration.id}` + */ + guildIntegration(guildId: Snowflake, integrationId: Snowflake) { + return `/guilds/${guildId}/integrations/${integrationId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget` + * - PATCH `/guilds/{guild.id}/widget` + */ + guildWidgetSettings(guildId: Snowflake) { + return `/guilds/${guildId}/widget` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.json` + */ + guildWidgetJSON(guildId: Snowflake) { + return `/guilds/${guildId}/widget.json` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/vanity-url` + */ + guildVanityUrl(guildId: Snowflake) { + return `/guilds/${guildId}/vanity-url` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.png` + */ + guildWidgetImage(guildId: Snowflake) { + return `/guilds/${guildId}/widget.png` as const; + }, + + /** + * Route for: + * - GET `/invites/{invite.code}` + * - DELETE `/invites/{invite.code}` + */ + invite(code: string) { + return `/invites/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/templates/{template.code}` + * - POST `/guilds/templates/{template.code}` + */ + template(code: string) { + return `/guilds/templates/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/templates` + * - POST `/guilds/{guild.id}/templates` + */ + guildTemplates(guildId: Snowflake) { + return `/guilds/${guildId}/templates` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/templates/{template.code}` + * - PATCH `/guilds/{guild.id}/templates/{template.code}` + * - DELETE `/guilds/{guild.id}/templates/{template.code}` + */ + guildTemplate(guildId: Snowflake, code: string) { + return `/guilds/${guildId}/templates/${code}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/threads` + * - POST `/channels/{channel.id}/messages/{message.id}/threads` + */ + threads(parentId: Snowflake, messageId?: Snowflake) { + const parts = ['', 'channels', parentId]; + + if (messageId) parts.push('messages', messageId); + + parts.push('threads'); + + return parts.join('/') as `/channels/${Snowflake}/threads` | `/channels/${Snowflake}/messages/${Snowflake}/threads`; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/threads/active` + */ + guildActiveThreads(guildId: Snowflake) { + return `/guilds/${guildId}/threads/active` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/threads/active` + * (deprecated, removed in API v10, use [List Active Guild Threads](https://discord.com/developers/docs/resources/guild#list-active-threads) instead.) + * - GET `/channels/{channel.id}/threads/archived/public` + * - GET `/channels/{channel.id}/threads/archived/private` + */ + channelThreads(channelId: Snowflake, archived?: 'public' | 'private') { + const parts = ['', 'channels', channelId, 'threads']; + + if (archived) parts.push('archived', archived); + else parts.push('active'); + + return parts.join('/') as + | `/channels/${Snowflake}/threads/active` + | `/channels/${Snowflake}/threads/archived/${'public' | 'private'}`; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/users/@me/threads/archived/prviate` + */ + channelJoinedArchivedThreads(channelId: Snowflake) { + return `/channels/${channelId}/users/@me/threads/archived/private` as const; + }, + + /** + * Route for: + * - GET `/channels/{thread.id}/thread-members` + * - GET `/channels/{thread.id}/thread-members/{user.id}` + * - PUT `/channels/{thread.id}/thread-members/@me` + * - PUT `/channels/{thread.id}/thread-members/{user.id}` + * - DELETE `/channels/{thread.id}/thread-members/@me` + * - DELETE `/channels/{thread.id}/thread-members/{user.id}` + */ + threadMembers(threadId: Snowflake, userId?: Snowflake | '@me') { + const parts = ['', 'channels', threadId, 'thread-members']; + + if (userId) parts.push(userId); + + return parts.join('/') as + | `/channels/${Snowflake}/thread-members` + | `/channels/${Snowflake}/thread-members/${Snowflake | '@me'}`; + }, + + /** + * Route for: + * - GET `/users/@me` + * - GET `/users/{user.id}` + * - PATCH `/users/@me` + * + * @param [userId='@me'] The user ID, defaulted to `@me` + */ + user(userId: Snowflake | '@me' = '@me') { + return `/users/${userId}` as const; + }, + + /** + * Route for: + * - GET `/users/@me/applications/{application.id}/role-connection` + * - PUT `/users/@me/applications/{application.id}/role-connection` + */ + userApplicationRoleConnection(applicationId: Snowflake) { + return `/users/@me/applications/${applicationId}/role-connection` as const; + }, + + /** + * Route for: + * - GET `/users/@me/guilds` + */ + userGuilds() { + return `/users/@me/guilds` as const; + }, + + /** + * Route for: + * - GET `/users/@me/guilds/{guild.id}/member` + */ + userGuildMember(guildId: Snowflake) { + return `/users/@me/guilds/${guildId}/member` as const; + }, + + /** + * Route for: + * - DELETE `/users/@me/guilds/{guild.id}` + */ + userGuild(guildId: Snowflake) { + return `/users/@me/guilds/${guildId}` as const; + }, + + /** + * Route for: + * - POST `/users/@me/channels` + */ + userChannels() { + return `/users/@me/channels` as const; + }, + + /** + * Route for: + * - GET `/users/@me/connections` + */ + userConnections() { + return `/users/@me/connections` as const; + }, + + /** + * Route for: + * - GET `/voice/regions` + */ + voiceRegions() { + return `/voice/regions` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/webhooks` + * - POST `/channels/{channel.id}/webhooks` + */ + channelWebhooks(channelId: Snowflake) { + return `/channels/${channelId}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/webhooks` + */ + guildWebhooks(guildId: Snowflake) { + return `/guilds/${guildId}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}` + * - GET `/webhooks/{webhook.id}/{webhook.token}` + * - PATCH `/webhooks/{webhook.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}` + * - DELETE `/webhooks/{webhook.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}` + * - POST `/webhooks/{webhook.id}/{webhook.token}` + * + * - POST `/webhooks/{application.id}/{interaction.token}` + */ + webhook(webhookId: Snowflake, webhookToken?: string) { + const parts = ['', 'webhooks', webhookId]; + + if (webhookToken) parts.push(webhookToken); + + return parts.join('/') as `/webhooks/${Snowflake}` | `/webhooks/${Snowflake}/${string}`; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/@original` + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * - DELETE `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * + * @param [messageId='@original'] The message ID to change, defaulted to `@original` + */ + webhookMessage(webhookId: Snowflake, webhookToken: string, messageId: Snowflake | '@original' = '@original') { + return `/webhooks/${webhookId}/${webhookToken}/messages/${messageId}` as const; + }, + + /** + * Route for: + * - POST `/webhooks/{webhook.id}/{webhook.token}/github` + * - POST `/webhooks/{webhook.id}/{webhook.token}/slack` + */ + webhookPlatform(webhookId: Snowflake, webhookToken: string, platform: 'github' | 'slack') { + return `/webhooks/${webhookId}/${webhookToken}/${platform}` as const; + }, + + /** + * Route for: + * - GET `/gateway` + */ + gateway() { + return `/gateway` as const; + }, + + /** + * Route for: + * - GET `/gateway/bot` + */ + gatewayBot() { + return `/gateway/bot` as const; + }, + + /** + * Route for: + * - GET `/oauth2/applications/@me` + */ + oauth2CurrentApplication() { + return `/oauth2/applications/@me` as const; + }, + + /** + * Route for: + * - GET `/oauth2/@me` + */ + oauth2CurrentAuthorization() { + return `/oauth2/@me` as const; + }, + + /** + * Route for: + * - GET `/oauth2/authorize` + */ + oauth2Authorization() { + return `/oauth2/authorize` as const; + }, + + /** + * Route for: + * - POST `/oauth2/token` + */ + oauth2TokenExchange() { + return `/oauth2/token` as const; + }, + + /** + * Route for: + * - POST `/oauth2/token/revoke` + */ + oauth2TokenRevocation() { + return `/oauth2/token/revoke` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands` + * - PUT `/applications/{application.id}/commands` + * - POST `/applications/{application.id}/commands` + */ + applicationCommands(applicationId: Snowflake) { + return `/applications/${applicationId}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/commands/{command.id}` + */ + applicationCommand(applicationId: Snowflake, commandId: Snowflake) { + return `/applications/${applicationId}/commands/${commandId}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands` + * - POST `/applications/{application.id}/guilds/{guild.id}/commands` + */ + applicationGuildCommands(applicationId: Snowflake, guildId: Snowflake) { + return `/applications/${applicationId}/guilds/${guildId}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + */ + applicationGuildCommand(applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake) { + return `/applications/${applicationId}/guilds/${guildId}/commands/${commandId}` as const; + }, + + /** + * Route for: + * - POST `/interactions/{interaction.id}/{interaction.token}/callback` + */ + interactionCallback(interactionId: Snowflake, interactionToken: string) { + return `/interactions/${interactionId}/${interactionToken}/callback` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/member-verification` + * - PATCH `/guilds/{guild.id}/member-verification` + */ + guildMemberVerification(guildId: Snowflake) { + return `/guilds/${guildId}/member-verification` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/voice-states/@me` + * - PATCH `/guilds/{guild.id}/voice-states/{user.id}` + */ + guildVoiceState(guildId: Snowflake, userId: Snowflake | '@me' = '@me') { + return `/guilds/${guildId}/voice-states/${userId}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + */ + guildApplicationCommandsPermissions(applicationId: Snowflake, guildId: Snowflake) { + return `/applications/${applicationId}/guilds/${guildId}/commands/permissions` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + */ + applicationCommandPermissions(applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake) { + return `/applications/${applicationId}/guilds/${guildId}/commands/${commandId}/permissions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/welcome-screen` + * - PATCH `/guilds/{guild.id}/welcome-screen` + */ + guildWelcomeScreen(guildId: Snowflake) { + return `/guilds/${guildId}/welcome-screen` as const; + }, + + /** + * Route for: + * - POST `/stage-instances` + */ + stageInstances() { + return `/stage-instances` as const; + }, + + /** + * Route for: + * - GET `/stage-instances/{channel.id}` + * - PATCH `/stage-instances/{channel.id}` + * - DELETE `/stage-instances/{channel.id}` + */ + stageInstance(channelId: Snowflake) { + return `/stage-instances/${channelId}` as const; + }, + + /** + * Route for: + * - GET `/stickers/{sticker.id}` + */ + sticker(stickerId: Snowflake) { + return `/stickers/${stickerId}` as const; + }, + + /** + * Route for: + * - GET `/sticker-packs` + */ + nitroStickerPacks() { + return '/sticker-packs' as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/stickers` + * - POST `/guilds/{guild.id}/stickers` + */ + guildStickers(guildId: Snowflake) { + return `/guilds/${guildId}/stickers` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/stickers/{sticker.id}` + * - PATCH `/guilds/{guild.id}/stickers/{sticker.id}` + * - DELETE `/guilds/{guild.id}/stickers/{sticker.id}` + */ + guildSticker(guildId: Snowflake, stickerId: Snowflake) { + return `/guilds/${guildId}/stickers/${stickerId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/scheduled-events` + * - POST `/guilds/{guild.id}/scheduled-events` + */ + guildScheduledEvents(guildId: Snowflake) { + return `/guilds/${guildId}/scheduled-events` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/scheduled-events/{guildScheduledEvent.id}` + * - PATCH `/guilds/{guild.id}/scheduled-events/{guildScheduledEvent.id}` + * - DELETE `/guilds/{guild.id}/scheduled-events/{guildScheduledEvent.id}` + */ + guildScheduledEvent(guildId: Snowflake, guildScheduledEventId: Snowflake) { + return `/guilds/${guildId}/scheduled-events/${guildScheduledEventId}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/scheduled-events/{guildScheduledEvent.id}/users` + */ + guildScheduledEventUsers(guildId: Snowflake, guildScheduledEventId: Snowflake) { + return `/guilds/${guildId}/scheduled-events/${guildScheduledEventId}/users` as const; + }, + + /* ---------- Auth routes -------------------- */ + login() { + return '/auth/login' as const; + }, + + logout() { + return '/auth/logout' as const; + }, + + register() { + return '/auth/register' as const; + }, + + reset() { + return '/auth/reset' as const; + }, + + locationMetadata() { + return '/auth/location-metadata' as const; + }, + + generateRegistrationTokens() { + return '/auth/generate-registration-tokens' as const; + }, + + forgot() { + return '/auth/forgot' as const; + }, + + emailVerify() { + return '/auth/verify' as const; + }, + + emailVerifyResend() { + return '/auth/verify/resend' as const; + }, + + viewBackupCodesChallenge() { + return '/auth/verify/view-backup-codes-challenge' as const; + }, + + mfaTotp() { + return '/auth/mfa/totp' as const; + }, + + mfaWebauthn() { + return '/auth/mfa/webauthn' as const; + }, + + /* ---------- Polices routes -------------------- */ + stats() { + return '/policies/stats' as const; + }, + + instance() { + return '/policies/instance' as const; + }, + + instanceDomains() { + return '/policies/instance/domains' as const; + }, + + instanceLimits() { + return '/policies/instance/limits' as const; + }, +}; + +export const StickerPackApplicationId = '710982414301790216'; + +export const CDNRoutes = { + /** + * Route for: + * - GET `/emojis/{emoji.id}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + emoji(emojiId: Snowflake, format: EmojiFormat) { + return `/emojis/${emojiId}.${format}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/icons/{guild.id}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + guildIcon(guildId: Snowflake, guildIcon: string, format: GuildIconFormat) { + return `/icons/${guildId}/${guildIcon}.${format}` as const; + }, + + /** + * Route for: + * - GET `/splashes/{guild.id}/{guild.splash}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + guildSplash(guildId: Snowflake, guildSplash: string, format: GuildSplashFormat) { + return `/splashes/${guildId}/${guildSplash}.${format}` as const; + }, + + /** + * Route for: + * - GET `/discovery-splashes/{guild.id}/{guild.discovery_splash}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + guildDiscoverySplash(guildId: Snowflake, guildDiscoverySplash: string, format: GuildDiscoverySplashFormat) { + return `/discovery-splashes/${guildId}/${guildDiscoverySplash}.${format}` as const; + }, + + /** + * Route for: + * - GET `/banners/{guild.id}/{guild.banner}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + guildBanner(guildId: Snowflake, guildBanner: string, format: GuildBannerFormat) { + return `/banners/${guildId}/${guildBanner}.${format}` as const; + }, + + /** + * Route for: + * - GET `/banners/{user.id}/{user.banner}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + userBanner(userId: Snowflake, userBanner: string, format: UserBannerFormat) { + return `/banners/${userId}/${userBanner}.${format}` as const; + }, + + /** + * Route for: + * - GET `/embed/avatars/{user.discriminator % 5}.png` + * + * The `userDiscriminator` parameter should be the user discriminator modulo 5 (e.g. 1337 % 5 = 2) + * + * This route supports the extension: PNG + */ + defaultUserAvatar(userDiscriminator: DefaultUserAvatarAssets) { + return `/embed/avatars/${userDiscriminator}.png` as const; + }, + + /** + * Route for: + * - GET `/avatars/{user.id}/{user.avatar}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + userAvatar(userId: Snowflake, userAvatar: string, format: UserAvatarFormat) { + return `/avatars/${userId}/${userAvatar}.${format}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/users/{user.id}/{guild_member.avatar}.{png|jpeg|webp|gif}` + * + * As this route supports GIFs, the hash will begin with `a_` if it is available in GIF format + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + guildMemberAvatar(guildId: Snowflake, userId: Snowflake, memberAvatar: string, format: GuildMemberAvatarFormat) { + return `/guilds/${guildId}/users/${userId}/avatars/${memberAvatar}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-icons/{application.id}/{application.icon}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + applicationIcon(applicationId: Snowflake, applicationIcon: string, format: ApplicationIconFormat) { + return `/app-icons/${applicationId}/${applicationIcon}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-icons/{application.id}/{application.cover_image}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + applicationCover(applicationId: Snowflake, applicationCoverImage: string, format: ApplicationCoverFormat) { + return `/app-icons/${applicationId}/${applicationCoverImage}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-assets/{application.id}/{application.asset_id}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + applicationAsset(applicationId: Snowflake, applicationAssetId: string, format: ApplicationAssetFormat) { + return `/app-assets/${applicationId}/${applicationAssetId}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-assets/{application.id}/achievements/{achievement.id}/icons/{achievement.icon}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + achievementIcon( + applicationId: Snowflake, + achievementId: Snowflake, + achievementIconHash: string, + format: AchievementIconFormat, + ) { + return `/app-assets/${applicationId}/achievements/${achievementId}/icons/${achievementIconHash}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-assets/710982414301790216/store/{sticker_pack.banner.asset_id}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + stickerPackBanner(stickerPackBannerAssetId: Snowflake, format: StickerPackBannerFormat) { + return `/app-assets/${StickerPackApplicationId}/store/${stickerPackBannerAssetId}.${format}` as const; + }, + + /** + * Route for: + * - GET `/app-assets/${application.id}/store/${asset.id}.{png|jpeg|webp}}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + storePageAsset(applicationId: Snowflake, assetId: string) { + return `/app-assets/${applicationId}/store/${assetId}.png` as const; + }, + + /** + * Route for: + * - GET `team-icons/{team.id}/{team.icon}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + teamIcon(teamId: Snowflake, teamIcon: string, format: TeamIconFormat) { + return `/team-icons/${teamId}/${teamIcon}.${format}` as const; + }, + + /** + * Route for: + * - GET `/stickers/{sticker.id}.{png|json}` + * + * This route supports the extensions: PNG, Lottie, GIF + */ + sticker(stickerId: Snowflake, format: StickerFormat) { + return `/stickers/${stickerId}.${format}` as const; + }, + + /** + * Route for: + * - GET `/role-icons/{role.id}/{role.icon}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + roleIcon(roleId: Snowflake, roleIcon: string, format: RoleIconFormat) { + return `/role-icons/${roleId}/${roleIcon}.${format}` as const; + }, + + /** + * Route for: + * - GET `/guild-events/{guild_scheduled_event.id}/{guild_scheduled_event.image}.{png|jpeg|webp}` + * + * This route supports the extensions: PNG, JPEG, WebP + */ + guildScheduledEventCover( + guildScheduledEventId: Snowflake, + guildScheduledEventCoverImage: string, + format: GuildScheduledEventCoverFormat, + ) { + return `/guild-events/${guildScheduledEventId}/${guildScheduledEventCoverImage}.${format}` as const; + }, + + /** + * Route for: + * - GET `/guilds/${guild.id}/users/${user.id}/banners/${guild_member.banner}.{png|jpeg|webp|gif}` + * + * This route supports the extensions: PNG, JPEG, WebP, GIF + */ + guildMemberBanner(guildId: Snowflake, userId: Snowflake, guildMemberBanner: string, format: GuildMemberBannerFormat) { + return `/guilds/${guildId}/users/${userId}/banners/${guildMemberBanner}.${format}` as const; + }, +}; + +export type DefaultUserAvatarAssets = 0 | 1 | 2 | 3 | 4 | 5; + +export type EmojiFormat = Exclude; +export type GuildIconFormat = Exclude; +export type GuildSplashFormat = Exclude; +export type GuildDiscoverySplashFormat = Exclude; +export type GuildBannerFormat = Exclude; +export type UserBannerFormat = Exclude; +export type DefaultUserAvatar = Extract; +export type UserAvatarFormat = Exclude; +export type GuildMemberAvatarFormat = Exclude; +export type ApplicationIconFormat = Exclude; +export type ApplicationCoverFormat = Exclude; +export type ApplicationAssetFormat = Exclude; +export type AchievementIconFormat = Exclude; +export type StickerPackBannerFormat = Exclude; +export type TeamIconFormat = Exclude; +export type StickerFormat = Extract; +export type RoleIconFormat = Exclude; +export type GuildScheduledEventCoverFormat = Exclude; +export type GuildMemberBannerFormat = Exclude; + +export enum ImageFormat { + JPEG = 'jpeg', + PNG = 'png', + WebP = 'webp', + GIF = 'gif', + Lottie = 'json', +} + +export interface CDNQuery { + /** + * The returned image can have the size changed by using this query parameter + * + * Image size can be any power of two between 16 and 4096 + */ + size?: number; +} + +export const RouteBases = { + api: `https://discord.com/api/v${APIVersion}`, + cdn: 'https://cdn.discordapp.com', + invite: 'https://discord.gg', + template: 'https://discord.new', + gift: 'https://discord.gift', + scheduledEvent: 'https://discord.com/events', +} as const; + +// Freeze bases object +Object.freeze(RouteBases); + +export const OAuth2Routes = { + authorizationURL: `${RouteBases.api}${Routes.oauth2Authorization()}`, + tokenURL: `${RouteBases.api}${Routes.oauth2TokenExchange()}`, + /** + * See https://tools.ietf.org/html/rfc7009 + */ + tokenRevocationURL: `${RouteBases.api}${Routes.oauth2TokenRevocation()}`, +} as const; + +// Freeze OAuth2 route object +Object.freeze(OAuth2Routes); \ No newline at end of file diff --git a/rest/v9/interactions.ts b/rest/v9/interactions.ts new file mode 100644 index 0000000..fddaefb --- /dev/null +++ b/rest/v9/interactions.ts @@ -0,0 +1,283 @@ +import type { + RESTDeleteAPIWebhookWithTokenMessageResult, + RESTGetAPIWebhookWithTokenMessageResult, + RESTPatchAPIWebhookWithTokenMessageFormDataBody, + RESTPatchAPIWebhookWithTokenMessageJSONBody, + RESTPatchAPIWebhookWithTokenMessageResult, + RESTPostAPIWebhookWithTokenWaitResult, +} from './webhook'; +import type { + APIApplicationCommand, + APIApplicationCommandPermission, + APIGuildApplicationCommandPermissions, + APIInteractionResponse, + APIInteractionResponseCallbackData, + ApplicationCommandType, +} from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface, StrictPartial } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands + */ +export interface RESTGetAPIApplicationCommandsQuery { + /** + * Whether to include full localization dictionaries (name_localizations and description_localizations) + * in the returned objects, instead of the name_localized and description_localized fields. + * + * @default false + */ + with_localizations?: boolean; +} + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands + */ +export type RESTGetAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-global-application-command + */ +export type RESTGetAPIApplicationCommandResult = APIApplicationCommand; + +type RESTPostAPIBaseApplicationCommandsJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface< + Omit< + APIApplicationCommand, + | 'id' + | 'application_id' + | 'description' + | 'type' + | 'version' + | 'guild_id' + | 'name_localized' + | 'description_localized' + | 'default_member_permissions' + > & + Partial> +>; + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-global-application-command + */ +export type RESTPostAPIChatInputApplicationCommandsJSONBody = RESTPostAPIBaseApplicationCommandsJSONBody & + AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + type?: ApplicationCommandType.ChatInput; + description: string; + }>; + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-global-application-command + */ +export interface RESTPostAPIContextMenuApplicationCommandsJSONBody extends RESTPostAPIBaseApplicationCommandsJSONBody { + type: ApplicationCommandType.User | ApplicationCommandType.Message; +} + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsJSONBody = + | RESTPostAPIChatInputApplicationCommandsJSONBody + | RESTPostAPIContextMenuApplicationCommandsJSONBody; + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandJSONBody = StrictPartial; + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands + */ +export type RESTGetAPIApplicationGuildCommandsQuery = RESTGetAPIApplicationCommandsQuery; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands + */ +export type RESTGetAPIApplicationGuildCommandsResult = Omit[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands + */ +export type RESTGetAPIApplicationGuildCommandResult = Omit; + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsJSONBody = + | Omit + | Omit; + +/** + * https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsResult = Omit; + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandJSONBody = StrictPartial< + | Omit + | Omit +>; + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandResult = Omit; + +/** + * https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-guild-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsJSONBody = ( + | (Omit & + Pick, 'id'>) + | (Omit & + Pick, 'id'>) +)[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-guild-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsResult = Omit[]; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackJSONBody = APIInteractionResponse; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPostAPIInteractionCallbackJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response + */ +export type RESTGetAPIInteractionOriginalResponseResult = RESTGetAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response + */ +export type RESTPatchAPIInteractionOriginalResponseJSONBody = RESTPatchAPIWebhookWithTokenMessageJSONBody; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response + */ +export type RESTPatchAPIInteractionOriginalResponseFormDataBody = RESTPatchAPIWebhookWithTokenMessageFormDataBody; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response + */ +export type RESTPatchAPIInteractionOriginalResponseResult = RESTPatchAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response + */ +export type RESTDeleteAPIInteractionOriginalResponseResult = RESTDeleteAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#create-followup-message + */ +export type RESTPostAPIInteractionFollowupJSONBody = APIInteractionResponseCallbackData; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#create-followup-message + */ +export type RESTPostAPIInteractionFollowupFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPostAPIInteractionFollowupJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#create-followup-message + */ +export type RESTPostAPIInteractionFollowupResult = RESTPostAPIWebhookWithTokenWaitResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#get-followup-message + */ +export type RESTGetAPIInteractionFollowupResult = RESTGetAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message + */ +export type RESTPatchAPIInteractionFollowupJSONBody = RESTPatchAPIWebhookWithTokenMessageJSONBody; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message + */ +export type RESTPatchAPIInteractionFollowupFormDataBody = RESTPatchAPIWebhookWithTokenMessageFormDataBody; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message + */ +export type RESTPatchAPIInteractionFollowupResult = RESTPatchAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#delete-followup-message + */ +export type RESTDeleteAPIInteractionFollowupResult = RESTDeleteAPIWebhookWithTokenMessageResult; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-guild-application-command-permissions + */ +export type RESTGetAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions + */ +export type RESTGetAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions + */ +export interface RESTPutAPIApplicationCommandPermissionsJSONBody { + permissions: APIApplicationCommandPermission[]; +} + +/** + * https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions + */ +export type RESTPutAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/application-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsJSONBody = Pick< + APIGuildApplicationCommandPermissions, + 'id' | 'permissions' +>[]; + +/** + * https://discord.com/developers/docs/interactions/application-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; \ No newline at end of file diff --git a/rest/v9/invite.ts b/rest/v9/invite.ts new file mode 100644 index 0000000..0c93999 --- /dev/null +++ b/rest/v9/invite.ts @@ -0,0 +1,27 @@ +import type { Snowflake } from '../../globals'; +import type { APIInvite } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/invite#get-invite + */ +export interface RESTGetAPIInviteQuery { + /** + * Whether the invite should contain approximate member counts + */ + with_counts?: boolean; + /** + * Whether the invite should contain the expiration date + */ + with_expiration?: boolean; + /** + * The guild scheduled event to include with the invite + */ + guild_scheduled_event_id?: Snowflake; +} + +export type RESTGetAPIInviteResult = APIInvite; + +/** + * https://discord.com/developers/docs/resources/invite#delete-invite + */ +export type RESTDeleteAPIInviteResult = APIInvite; \ No newline at end of file diff --git a/rest/v9/oauth2.ts b/rest/v9/oauth2.ts new file mode 100644 index 0000000..78e622b --- /dev/null +++ b/rest/v9/oauth2.ts @@ -0,0 +1,199 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { APIApplication, APIGuild, APIUser, APIWebhook, OAuth2Scopes } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-bot-application-information + */ +export type RESTGetAPIOAuth2CurrentApplicationResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-authorization-information + */ +export interface RESTGetAPIOAuth2CurrentAuthorizationResult { + /** + * the current application + */ + application: Partial; + /** + * the scopes the user has authorized the application for + */ + scopes: OAuth2Scopes[]; + /** + * when the access token expires + */ + expires: string; + /** + * the user who has authorized, if the user has authorized with the `identify` scope + */ + user?: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant + */ +export interface RESTOAuth2AuthorizationQuery { + response_type: 'code'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTOAuth2AuthorizationQueryResult { + code: string; + state?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTPostOAuth2AccessTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'authorization_code'; + code: string; + redirect_uri?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response + */ +export interface RESTPostOAuth2AccessTokenResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-refresh-token-exchange-example + */ +export interface RESTPostOAuth2RefreshTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'refresh_token'; + refresh_token: string; +} + +export type RESTPostOAuth2RefreshTokenResult = RESTPostOAuth2AccessTokenResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant + */ +export interface RESTOAuth2ImplicitAuthorizationQuery { + response_type: 'token'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant-redirect-url-example + */ +export type RESTOAuth2ImplicitAuthorizationURLFragmentResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#client-credentials-grant + */ +export interface RESTPostOAuth2ClientCredentialsURLEncodedData { + grant_type: 'client_credentials'; + scope: string; +} + +export type RESTPostOAuth2ClientCredentialsResult = RESTOAuth2ImplicitAuthorizationURLFragmentResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow-bot-auth-parameters + */ +export interface RESTOAuth2BotAuthorizationQuery { + /** + * Your app's client id + */ + client_id: Snowflake; + /** + * Needs to include bot for the bot flow + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The permissions you're requesting + * + * See https://discord.com/developers/docs/topics/permissions + */ + permissions?: Permissions; + /** + * Pre-fills the dropdown picker with a guild for the user + */ + guild_id?: Snowflake; + /** + * `true` or `false`—disallows the user from changing the guild dropdown + */ + disable_guild_select?: boolean; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization + */ +export interface RESTOAuth2AdvancedBotAuthorizationQuery { + client_id: Snowflake; + /** + * This assumes you include the `bot` scope alongside others (like `identify` for example) + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The required permissions bitfield, stringified + */ + permissions?: Permissions; + guild_id?: Snowflake; + disable_guild_select?: boolean; + response_type: string; + redirect_uri?: string; +} + +export interface RESTOAuth2AdvancedBotAuthorizationQueryResult { + code: string; + state?: string; + guild_id: Snowflake; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization-extended-bot-authorization-access-token-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + guild: APIGuild; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#webhooks-webhook-token-response-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + webhook: APIWebhook; +} + +export type RESTPostOAuth2AccessTokenWithBotAndGuildsAndWebhookIncomingScopeResult = + RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult & RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult; \ No newline at end of file diff --git a/rest/v9/stageInstance.ts b/rest/v9/stageInstance.ts new file mode 100644 index 0000000..174c036 --- /dev/null +++ b/rest/v9/stageInstance.ts @@ -0,0 +1,61 @@ +import type { Snowflake } from '../../globals'; +import type { APIStageInstance, StageInstancePrivacyLevel } from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/stage-instance#create-stage-instance + */ +export interface RESTPostAPIStageInstanceJSONBody { + /** + * The id of the stage channel + */ + channel_id: Snowflake; + /** + * The topic of the stage instance (1-120 characters) + */ + topic: string; + /** + * The privacy level of the stage instance + * + * @default GuildOnly + */ + privacy_level?: StageInstancePrivacyLevel; + /** + * Notify @everyone that a stage instance has started + */ + send_start_notification?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/stage-instance#create-stage-instance + */ +export type RESTPostAPIStageInstanceResult = APIStageInstance; + +/** + * https://discord.com/developers/docs/resources/stage-instance#get-stage-instance + */ +export type RESTGetAPIStageInstanceResult = APIStageInstance; + +/** + * https://discord.com/developers/docs/resources/stage-instance#modify-stage-instance + */ +export type RESTPatchAPIStageInstanceJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The topic of the stage instance (1-120 characters) + */ + topic?: string; + /** + * The privacy level of the stage instance + */ + privacy_level?: StageInstancePrivacyLevel; +}>; + +/** + * https://discord.com/developers/docs/resources/stage-instance#modify-stage-instance + */ +export type RESTPatchAPIStageInstanceResult = APIStageInstance; + +/** + * https://discord.com/developers/docs/resources/stage-instance#delete-stage-instance + */ +export type RESTDeleteAPIStageInstanceResult = never; \ No newline at end of file diff --git a/rest/v9/sticker.ts b/rest/v9/sticker.ts new file mode 100644 index 0000000..3af2714 --- /dev/null +++ b/rest/v9/sticker.ts @@ -0,0 +1,81 @@ +import type { APISticker, APIStickerPack } from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/sticker#get-sticker + */ +export type RESTGetAPIStickerResult = APISticker; + +/** + * https://discord.com/developers/docs/resources/sticker#list-nitro-sticker-packs + */ +export interface RESTGetNitroStickerPacksResult { + sticker_packs: APIStickerPack[]; +} + +/** + * https://discord.com/developers/docs/resources/sticker#list-guild-stickers + */ +export type RESTGetAPIGuildStickersResult = APISticker[]; + +/** + * https://discord.com/developers/docs/resources/sticker#get-guild-sticker + */ +export type RESTGetAPIGuildStickerResult = APISticker; + +/** + * https://discord.com/developers/docs/resources/sticker#create-guild-sticker + */ +export interface RESTPostAPIGuildStickerFormDataBody { + /** + * Name of the sticker (2-30 characters) + */ + name: string; + /** + * Description of the sticker (empty or 2-100 characters) + */ + description: string; + /** + * The Discord name of a unicode emoji representing the sticker's expression (2-200 characters) + */ + tags: string; + /** + * The sticker file to upload, must be a PNG, APNG, GIF, or Lottie JSON file, max 512 KB + * + * Uploaded stickers are constrained to 5 seconds in length for animated stickers, and 320 x 320 pixels. + */ + file: unknown; +} + +/** + * https://discord.com/developers/docs/resources/sticker#create-guild-sticker + */ +export type RESTPostAPIGuildStickerResult = APISticker; + +/** + * https://discord.com/developers/docs/resources/sticker#modify-guild-sticker + */ +export type RESTPatchAPIGuildStickerJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the sticker (2-30 characters) + */ + name?: string; + /** + * Description of the sticker (2-100 characters) + */ + description?: string | null; + /** + * The Discord name of a unicode emoji representing the sticker's expression (2-200 characters) + */ + tags?: string; +}>; + +/** + * https://discord.com/developers/docs/resources/sticker#modify-guild-sticker + */ +export type RESTPatchAPIGuildStickerResult = APISticker; + +/** + * https://discord.com/developers/docs/resources/sticker#delete-guild-sticker + */ +export type RESTDeleteAPIGuildStickerResult = never; \ No newline at end of file diff --git a/rest/v9/template.ts b/rest/v9/template.ts new file mode 100644 index 0000000..6b51c16 --- /dev/null +++ b/rest/v9/template.ts @@ -0,0 +1,72 @@ +import type { APIGuild, APITemplate } from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface, StrictPartial } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/guild-template#get-guild-template + */ +export type RESTGetAPITemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/guild-template#create-guild-from-guild-template + */ +export type RESTPostAPITemplateCreateGuildJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; +}>; + +/** + * https://discord.com/developers/docs/resources/guild-template#create-guild-from-guild-template + */ +export type RESTPostAPITemplateCreateGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild-template#get-guild-templates + */ +export type RESTGetAPIGuildTemplatesResult = APITemplate[]; + +/** + * https://discord.com/developers/docs/resources/guild-template#create-guild-template + */ +export type RESTPostAPIGuildTemplatesJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * 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/guild-template#create-guild-template + */ +export type RESTPostAPIGuildTemplatesResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/guild-template#sync-guild-template + */ +export type RESTPutAPIGuildTemplateSyncResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/guild-template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateJSONBody = StrictPartial; + +/** + * https://discord.com/developers/docs/resources/guild-template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/guild-template#delete-guild-template + */ +export type RESTDeleteAPIGuildTemplateResult = APITemplate; \ No newline at end of file diff --git a/rest/v9/user.ts b/rest/v9/user.ts new file mode 100644 index 0000000..996bef0 --- /dev/null +++ b/rest/v9/user.ts @@ -0,0 +1,131 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { + APIChannel, + APIConnection, + APIGuildMember, + APIUser, + APIApplicationRoleConnection, + GuildFeature, +} from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface } from '../../utils/internals'; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user + */ +export type RESTGetAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-user + */ +export type RESTGetAPIUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guild-member + */ +export type RESTGetCurrentUserGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export type RESTPatchAPICurrentUserJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * User's username, if changed may cause the user's discriminator to be randomized + */ + username?: string; + /** + * If passed, modifies the user's avatar + */ + avatar?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export type RESTPatchAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export interface RESTGetAPICurrentUserGuildsQuery { + /** + * Get guilds before this guild ID + */ + before?: Snowflake; + /** + * Get guilds after this guild ID + */ + after?: Snowflake; + /** + * Max number of guilds to return (1-200) + * + * @default 200 + */ + limit?: number; +} + +export interface RESTAPIPartialCurrentUserGuild { + id: Snowflake; + name: string; + icon: string | null; + owner: boolean; + features: GuildFeature[]; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export type RESTGetAPICurrentUserGuildsResult = RESTAPIPartialCurrentUserGuild[]; + +/** + * https://discord.com/developers/docs/resources/user#leave-guild + */ +export type RESTDeleteAPICurrentUserGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export interface RESTPostAPICurrentUserCreateDMChannelJSONBody { + /** + * The recipient to open a DM channel with + */ + recipient_id: string; +} + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export type RESTPostAPICurrentUserCreateDMChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/user#get-user-connections + */ +export type RESTGetAPICurrentUserConnectionsResult = APIConnection[]; + +/** + * https://discord.com/developers/docs/resources/user#get-user-application-role-connection + */ +export type RESTGetAPICurrentUserApplicationRoleConnectionResult = APIApplicationRoleConnection; + +/** + * https://discord.com/developers/docs/resources/user#update-user-application-role-connection + */ +export interface RESTPutAPICurrentUserApplicationRoleConnectionJSONBody { + /** + * The vanity name of the platform a bot has connected (max 50 characters) + */ + platform_name?: string; + /** + * The username on the platform a bot has connected (max 100 characters) + */ + platform_username?: string; + /** + * Object mapping application role connection metadata keys to their `string`-ified value (max 100 characters) for the user on the platform a bot has connected + */ + metadata?: Record; +} + +/** + * https://discord.com/developers/docs/resources/user#update-user-application-role-connection + */ +export type RESTPutAPICurrentUserApplicationRoleConnectionResult = APIApplicationRoleConnection; \ No newline at end of file diff --git a/rest/v9/voice.ts b/rest/v9/voice.ts new file mode 100644 index 0000000..dc7f2f9 --- /dev/null +++ b/rest/v9/voice.ts @@ -0,0 +1,11 @@ +import type { APIVoiceRegion } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/voice#list-voice-regions + */ +export type RESTGetAPIVoiceRegionsResult = APIVoiceRegion[]; + +/** + * @deprecated This was exported with the wrong name, use `RESTGetAPIVoiceRegionsResult` instead + */ +export type GetAPIVoiceRegionsResult = RESTGetAPIVoiceRegionsResult; \ No newline at end of file diff --git a/rest/v9/webhook.ts b/rest/v9/webhook.ts new file mode 100644 index 0000000..c7c1b9c --- /dev/null +++ b/rest/v9/webhook.ts @@ -0,0 +1,276 @@ +import type { Snowflake } from '../../globals'; +import type { + APIAllowedMentions, + APIActionRowComponent, + APIEmbed, + APIMessage, + APIWebhook, + APIAttachment, + MessageFlags, + APIMessageActionRowComponent, +} from '../../payloads/v9/index'; +import type { AddUndefinedToPossiblyUndefinedPropertiesOfInterface, Nullable } from '../../utils/internals'; +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export type RESTPostAPIChannelWebhookJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * Name of the webhook (1-80 characters) + */ + name: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; +}>; + +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export type RESTPostAPIChannelWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-channel-webhooks + */ +export type RESTGetAPIChannelWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-guild-webhooks + */ +export type RESTGetAPIGuildWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook + */ +export type RESTGetAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-with-token + */ +export type RESTGetAPIWebhookWithTokenResult = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export type RESTPatchAPIWebhookJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The default name of the webhook + */ + name?: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; + /** + * The new channel id this webhook should be moved to + */ + channel_id?: Snowflake; +}>; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export type RESTPatchAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenJSONBody = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenResult = RESTGetAPIWebhookWithTokenResult; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook + */ +export type RESTDeleteAPIWebhookResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token + */ +export type RESTDeleteAPIWebhookWithTokenResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface<{ + /** + * The message contents (up to 2000 characters) + */ + content?: string; + /** + * Override the default username of the webhook + */ + username?: string; + /** + * Override the default avatar of the webhook + */ + avatar_url?: string; + /** + * `true` if this is a TTS message + */ + tts?: boolean; + /** + * Embedded `rich` content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embeds?: APIEmbed[]; + /** + * Allowed mentions for the message + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object + */ + allowed_mentions?: APIAllowedMentions; + /** + * The components to include with the message + * + * Requires an application-owned webhook + * + * See https://discord.com/developers/docs/interactions/message-components#component-object + */ + components?: APIActionRowComponent[]; + /** + * Attachment objects with filename and description + */ + attachments?: (Pick & Partial>)[]; + /** + * Message flags combined as a bitfield + */ + flags?: MessageFlags; + /** + * Name of thread to create + * + * Available only if the webhook is in a forum channel and a thread is not specified in {@link RESTPostAPIWebhookWithTokenQuery.thread_id} query parameter + */ + thread_name?: string; +}>; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPostAPIWebhookWithTokenJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export interface RESTPostAPIWebhookWithTokenQuery { + /** + * Waits for server confirmation of message send before response, and returns the created message body + * (defaults to `false`; when `false` a message that is not saved does not return an error) + * + * @default false + */ + wait?: boolean; + /** + * Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived. + * + * Available only if the {@link RESTPostAPIWebhookWithTokenJSONBody.thread_name} JSON body property is not specified + */ + thread_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenSlackResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenGitHubResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-message + */ +export type RESTGetAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageJSONBody = AddUndefinedToPossiblyUndefinedPropertiesOfInterface< + Nullable> & { + /** + * Attached files to keep + * + * Starting with API v10, the `attachments` array must contain all attachments that should be present after edit, including **retained and new** attachments provided in the request body. + * + * See https://discord.com/developers/docs/resources/channel#attachment-object + */ + attachments?: (Pick & Partial>)[]; + } +>; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageFormDataBody = + | ({ + /** + * JSON stringified message body + */ + payload_json?: string; + } & Record<`files[${bigint}]`, unknown>) + | (RESTPatchAPIWebhookWithTokenMessageJSONBody & Record<`files[${bigint}]`, unknown>); + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-message + */ +export type RESTDeleteAPIWebhookWithTokenMessageResult = never; \ No newline at end of file diff --git a/utils/index.ts b/utils/index.ts new file mode 100644 index 0000000..73f9e61 --- /dev/null +++ b/utils/index.ts @@ -0,0 +1,4 @@ +// This file exports all the utility functions available in the recommended API / Gateway version +// Thereby, things MAY break in the future. Try sticking to imports from a specific version + +export * from './v9'; \ No newline at end of file diff --git a/utils/internals.ts b/utils/internals.ts new file mode 100644 index 0000000..638b7ce --- /dev/null +++ b/utils/internals.ts @@ -0,0 +1,41 @@ +export type Nullable = { + [P in keyof T]: T[P] | null; +}; + +/** + * Allows support for TS 4.5's `exactOptionalPropertyTypes` option by ensuring a property present and undefined is valid + * (since JSON.stringify ignores undefined properties) + */ +export type AddUndefinedToPossiblyUndefinedPropertiesOfInterface = { + [K in keyof Base]: Base[K] extends Exclude + ? AddUndefinedToPossiblyUndefinedPropertiesOfInterface + : AddUndefinedToPossiblyUndefinedPropertiesOfInterface | undefined; +}; + +export type StrictPartial = AddUndefinedToPossiblyUndefinedPropertiesOfInterface>; + +export type StrictRequired = Required<{ [K in keyof Base]: Exclude }>; + +export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; + +type Keys = keyof T; +type DistributiveKeys = T extends unknown ? Keys : never; +/** + * Allows picking of keys from unions that are disjoint + */ +export type DistributivePick> = T extends unknown + ? keyof Pick_ extends never + ? never + : { [P in keyof Pick_]: Pick_[P] } + : never; + +type Pick_ = Pick>; + +/** + * Allows omitting of keys from unions that are disjoint + */ +export type DistributiveOmit> = T extends unknown + ? { [P in keyof Omit_]: Omit_[P] } + : never; + +type Omit_ = Omit>; \ No newline at end of file diff --git a/utils/v9.ts b/utils/v9.ts new file mode 100644 index 0000000..8bf5272 --- /dev/null +++ b/utils/v9.ts @@ -0,0 +1,177 @@ +import { + APIApplicationCommandDMInteraction, + APIApplicationCommandGuildInteraction, + APIApplicationCommandInteraction, + APIButtonComponent, + APIButtonComponentWithCustomId, + APIButtonComponentWithURL, + APIChatInputApplicationCommandInteraction, + APIContextMenuInteraction, + APIDMInteraction, + APIGuildInteraction, + APIInteraction, + APIMessageComponentButtonInteraction, + APIMessageComponentDMInteraction, + APIMessageComponentGuildInteraction, + APIMessageComponentInteraction, + APIMessageComponentSelectMenuInteraction, + ApplicationCommandType, + ButtonStyle, + ComponentType, + InteractionType, +} from '../payloads/v9/index'; + +// Interactions + +/** + * A type-guard check for DM interactions + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction was received in a DM channel + */ +export function isDMInteraction(interaction: APIInteraction): interaction is APIDMInteraction { + return Reflect.has(interaction, 'user'); +} + +/** + * A type-guard check for guild interactions + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction was received in a guild + */ +export function isGuildInteraction(interaction: APIInteraction): interaction is APIGuildInteraction { + return Reflect.has(interaction, 'guild_id'); +} + +// ApplicationCommandInteractions + +/** + * A type-guard check for DM application command interactions + * @param interaction The application command interaction to check against + * @returns A boolean that indicates if the application command interaction was received in a DM channel + */ +export function isApplicationCommandDMInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandDMInteraction { + return isDMInteraction(interaction); +} + +/** + * A type-guard check for guild application command interactions + * @param interaction The interaction to check against + * @returns A boolean that indicates if the application command interaction was received in a guild + */ +export function isApplicationCommandGuildInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandGuildInteraction { + return isGuildInteraction(interaction); +} + +// MessageComponentInteractions + +/** + * A type-guard check for DM message component interactions + * @param interaction The message component interaction to check against + * @returns A boolean that indicates if the message component interaction was received in a DM channel + */ +export function isMessageComponentDMInteraction( + interaction: APIMessageComponentInteraction, +): interaction is APIMessageComponentDMInteraction { + return isDMInteraction(interaction); +} + +/** + * A type-guard check for guild message component interactions + * @param interaction The interaction to check against + * @returns A boolean that indicates if the message component interaction was received in a guild + */ +export function isMessageComponentGuildInteraction( + interaction: APIMessageComponentInteraction, +): interaction is APIMessageComponentGuildInteraction { + return isGuildInteraction(interaction); +} + +// Buttons + +/** + * A type-guard check for buttons that have a `url` attached to them. + * @param component The button to check against + * @returns A boolean that indicates if the button has a `url` attached to it + */ +export function isLinkButton(component: APIButtonComponent): component is APIButtonComponentWithURL { + return component.style === ButtonStyle.Link; +} + +/** + * A type-guard check for buttons that have a `custom_id` attached to them. + * @param button The button to check against + * @returns A boolean that indicates if the button has a `custom_id` attached to it + */ +export function isInteractionButton(component: APIButtonComponent): component is APIButtonComponentWithCustomId { + return component.style !== ButtonStyle.Link; +} + +// Message Components + +/** + * A type-guard check for message component interactions + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction is a message component + */ +export function isMessageComponentInteraction( + interaction: APIInteraction, +): interaction is APIMessageComponentInteraction { + return interaction.type === InteractionType.MessageComponent; +} + +/** + * A type-guard check for button message component interactions + * @param interaction The message component interaction to check against + * @returns A boolean that indicates if the message component is a button + */ +export function isMessageComponentButtonInteraction( + interaction: APIMessageComponentInteraction, +): interaction is APIMessageComponentButtonInteraction { + return interaction.data.component_type === ComponentType.Button; +} + +/** + * A type-guard check for select menu message component interactions + * @param interaction The message component interaction to check against + * @returns A boolean that indicates if the message component is a select menu + */ +export function isMessageComponentSelectMenuInteraction( + interaction: APIMessageComponentInteraction, +): interaction is APIMessageComponentSelectMenuInteraction { + return [ + ComponentType.StringSelect, + ComponentType.UserSelect, + ComponentType.RoleSelect, + ComponentType.MentionableSelect, + ComponentType.ChannelSelect, + ].includes(interaction.data.component_type); +} + +// Application Commands + +/** + * A type-guard check for chat input application commands. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction is a chat input application command + */ +export function isChatInputApplicationCommandInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIChatInputApplicationCommandInteraction { + return interaction.data.type === ApplicationCommandType.ChatInput; +} + +/** + * A type-guard check for context menu application commands. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction is a context menu application command + */ +export function isContextMenuApplicationCommandInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIContextMenuInteraction { + return ( + interaction.data.type === ApplicationCommandType.Message || interaction.data.type === ApplicationCommandType.User + ); +} \ No newline at end of file