From 6e8f15557c58e29931f1d755ea928d9b225660d9 Mon Sep 17 00:00:00 2001 From: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> Date: Sat, 30 Sep 2023 14:58:14 -0500 Subject: [PATCH] Pr/livelove1987/3138 (#3143) * feat: Adding invite helper use transformer * fix: Fix type error * Update packages/bot/src/transformers/invite.ts Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> * fixes * fix: Fixed invite transformer * Remove < > in comment * Fix: remove useless const * fix invite * fix: ts error --------- Co-authored-by: livelove1987 Co-authored-by: livelove1987 <82705913+livelove1987@users.noreply.github.com> --- packages/bot/src/helpers.ts | 11 +++-- packages/bot/src/transformers.ts | 30 ++++++++++++- packages/bot/src/transformers/invite.ts | 44 ++++++++++++++++--- .../src/transformers/stageInviteInstance.ts | 29 ++++++++++++ packages/utils/src/typeguards.ts | 14 +++++- 5 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 packages/bot/src/transformers/stageInviteInstance.ts diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index 4d02f4fad..feec456ce 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -96,6 +96,7 @@ import type { Channel } from './transformers/channel.js' import type { Emoji } from './transformers/emoji.js' import type { Guild } from './transformers/guild.js' import type { Integration } from './transformers/integration.js' +import type { Invite } from './transformers/invite.js' import type { Member } from './transformers/member.js' import type { Message } from './transformers/message.js' import type { Role } from './transformers/role.js' @@ -363,12 +364,10 @@ export function createBotHelpers(bot: Bot): BotHelpers { ) }, getInvite: async (inviteCode, options) => { - return await bot.rest.getInvite(inviteCode, options) - // return bot.transformers.invite(bot, snakelize(await bot.rest.getInvite(inviteCode, options))) + return bot.transformers.invite(bot, snakelize(await bot.rest.getInvite(inviteCode, options))) }, getInvites: async (guildId) => { - return await bot.rest.getInvites(guildId) - // .map((res) => bot.transformers.invite(bot, snakelize(res))) + return (await bot.rest.getInvites(guildId)).map((res) => bot.transformers.invite(bot, snakelize(res))) }, getMessage: async (channelId, messageId) => { return bot.transformers.message(bot, snakelize(await bot.rest.getMessage(channelId, messageId))) @@ -787,8 +786,8 @@ export interface BotHelpers { getGuildTemplates: (guildId: BigString) => Promise getGuildWebhooks: (guildId: BigString) => Promise getIntegrations: (guildId: BigString) => Promise - getInvite: (inviteCode: string, options?: GetInvite) => Promise - getInvites: (guildId: BigString) => Promise + getInvite: (inviteCode: string, options?: GetInvite) => Promise + getInvites: (guildId: BigString) => Promise getMessage: (channelId: BigString, messageId: BigString) => Promise getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise getNitroStickerPacks: () => Promise diff --git a/packages/bot/src/transformers.ts b/packages/bot/src/transformers.ts index 197e52dbc..af713a5e1 100644 --- a/packages/bot/src/transformers.ts +++ b/packages/bot/src/transformers.ts @@ -25,6 +25,8 @@ import type { DiscordInteraction, DiscordInteractionDataOption, DiscordInviteCreate, + DiscordInviteMetadata, + DiscordInviteStageInstance, DiscordMember, DiscordMessage, DiscordPresenceUpdate, @@ -84,6 +86,7 @@ import { transformInteractionResponseToDiscordInteractionResponse } from './tran import { transformRole, type Role } from './transformers/role.js' import { transformScheduledEvent, type ScheduledEvent } from './transformers/scheduledEvent.js' import { transformStageInstance, type StageInstance } from './transformers/stageInstance.js' +import { transformInviteStageInstance, type InviteStageInstance } from './transformers/stageInviteInstance.js' import { transformSticker, transformStickerPack, type Sticker, type StickerPack } from './transformers/sticker.js' import { transformTeam, type Team } from './transformers/team.js' import { transformTemplate, type Template } from './transformers/template.js' @@ -241,6 +244,11 @@ export interface Transformers { targetApplication: boolean temporary: boolean uses: boolean + approximateMemberCount: boolean + approximatePresenceCount: boolean + guildScheduledEvent: boolean + stageInstance: boolean + expiresAt: boolean } member: { id: boolean @@ -334,6 +342,12 @@ export interface Transformers { topic: boolean guildScheduledEventId: boolean } + inviteStageInstance: { + members: boolean + participantCount: boolean + speakerCount: boolean + topic: boolean + } sticker: { id: boolean packId: boolean @@ -411,7 +425,7 @@ export interface Transformers { interaction: (bot: Bot, payload: DiscordInteraction) => Interaction interactionDataOptions: (bot: Bot, payload: DiscordInteractionDataOption) => InteractionDataOption integration: (bot: Bot, payload: DiscordIntegrationCreateUpdate) => Integration - invite: (bot: Bot, invite: DiscordInviteCreate) => Invite + invite: (bot: Bot, invite: DiscordInviteCreate | DiscordInviteMetadata) => Invite application: (bot: Bot, payload: DiscordApplication) => Application team: (bot: Bot, payload: DiscordTeam) => Team emoji: (bot: Bot, payload: DiscordEmoji) => Emoji @@ -432,6 +446,8 @@ export interface Transformers { widget: (bot: Bot, payload: DiscordGuildWidget) => GuildWidget widgetSettings: (bot: Bot, payload: DiscordGuildWidgetSettings) => GuildWidgetSettings stageInstance: (bot: Bot, payload: DiscordStageInstance) => StageInstance + inviteStageInstance: (bot: Bot, payload: DiscordInviteStageInstance & { guildId: BigString }) => InviteStageInstance + sticker: (bot: Bot, payload: DiscordSticker) => Sticker stickerPack: (bot: Bot, payload: DiscordStickerPack) => StickerPack applicationCommandOptionChoice: (bot: Bot, payload: DiscordApplicationCommandOptionChoice) => ApplicationCommandOptionChoice @@ -595,6 +611,11 @@ export function createTransformers(options: Partial): Transformers targetApplication: false, temporary: false, uses: false, + approximateMemberCount: false, + approximatePresenceCount: false, + guildScheduledEvent: false, + stageInstance: false, + expiresAt: false, }, member: { id: false, @@ -688,6 +709,12 @@ export function createTransformers(options: Partial): Transformers topic: false, guildScheduledEventId: false, }, + inviteStageInstance: { + members: false, + participantCount: false, + speakerCount: false, + topic: false, + }, sticker: { id: false, packId: false, @@ -786,6 +813,7 @@ export function createTransformers(options: Partial): Transformers widget: options.widget ?? transformWidget, widgetSettings: options.widgetSettings ?? transformWidgetSettings, stageInstance: options.stageInstance ?? transformStageInstance, + inviteStageInstance: options.inviteStageInstance ?? transformInviteStageInstance, sticker: options.sticker ?? transformSticker, stickerPack: options.stickerPack ?? transformStickerPack, gatewayBot: options.gatewayBot ?? transformGatewayBot, diff --git a/packages/bot/src/transformers/invite.ts b/packages/bot/src/transformers/invite.ts index c188db866..6ebb916aa 100644 --- a/packages/bot/src/transformers/invite.ts +++ b/packages/bot/src/transformers/invite.ts @@ -1,15 +1,15 @@ -import type { DiscordApplication, DiscordInviteCreate } from '@discordeno/types' -import type { Application, Bot, User } from '../index.js' +import type { DiscordApplication, DiscordInviteCreate, DiscordInviteMetadata } from '@discordeno/types' +import { isInviteWithMetadata, type Application, type Bot, type ScheduledEvent, type User } from '../index.js' +import type { InviteStageInstance } from './stageInviteInstance.js' // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export function transformInvite(bot: Bot, payload: DiscordInviteCreate) { +export function transformInvite(bot: Bot, payload: DiscordInviteCreate | DiscordInviteMetadata) { const props = bot.transformers.desiredProperties.invite const invite = {} as Invite + const hasMetadata = isInviteWithMetadata(payload) - if (props.channelId && payload.channel_id) invite.channelId = bot.transformers.snowflake(payload.channel_id) if (props.code && payload.code) invite.code = payload.code if (props.createdAt && payload.created_at) invite.createdAt = Date.parse(payload.created_at) - if (props.guildId && payload.guild_id) invite.guildId = bot.transformers.snowflake(payload.guild_id) if (props.inviter && payload.inviter) invite.inviter = bot.transformers.user(bot, payload.inviter) if (props.maxAge && payload.max_age) invite.maxAge = payload.max_age if (props.maxUses && payload.max_uses) invite.maxUses = payload.max_uses @@ -20,6 +20,30 @@ export function transformInvite(bot: Bot, payload: DiscordInviteCreate) { if (props.temporary && payload.temporary) invite.temporary = payload.temporary if (props.uses && payload.uses) invite.uses = payload.uses + if (hasMetadata) { + if (props.channelId && payload.channel?.id) invite.channelId = bot.transformers.snowflake(payload.channel.id) + if (props.guildId && payload.guild?.id) invite.guildId = bot.transformers.snowflake(payload.guild.id) + if (props.approximateMemberCount && payload.approximate_member_count) invite.approximateMemberCount = payload.approximate_member_count + if (props.approximatePresenceCount && payload.approximate_presence_count) invite.approximatePresenceCount = payload.approximate_presence_count + if (props.guildScheduledEvent && payload.guild_scheduled_event) { + invite.guildScheduledEvent = payload.guild_scheduled_event ? bot.transformers.scheduledEvent(bot, payload.guild_scheduled_event) : undefined + } + if (props.stageInstance && invite.guildId && payload.stage_instance) { + invite.stageInstance = payload.stage_instance + ? bot.transformers.inviteStageInstance(bot, { + ...payload.stage_instance, + guildId: invite.guildId, + }) + : undefined + } + if (props.expiresAt && payload.expires_at) { + invite.expiresAt = Date.parse(payload.expires_at) + } + } else { + if (props.channelId && payload.channel_id) invite.channelId = bot.transformers.snowflake(payload.channel_id) + if (props.guildId && payload.guild_id) invite.guildId = bot.transformers.snowflake(payload.guild_id) + } + return invite } @@ -48,4 +72,14 @@ export interface Invite { temporary: boolean /** How many times the invite has been used (always will be 0) */ uses: number + /** Approximate count of online members (only present when target_user is set) */ + approximateMemberCount: number + /** Stage instance data if there is a public Stage instance in the Stage channel this invite is for */ + stageInstance?: InviteStageInstance + /** The expiration date of this invite, returned from the GET /invites/code endpoint when with_expiration is true */ + expiresAt?: number + /** guild scheduled event data */ + guildScheduledEvent?: ScheduledEvent + /** Approximate count of online members (only present when target_user is set) */ + approximatePresenceCount?: number } diff --git a/packages/bot/src/transformers/stageInviteInstance.ts b/packages/bot/src/transformers/stageInviteInstance.ts new file mode 100644 index 000000000..262032c25 --- /dev/null +++ b/packages/bot/src/transformers/stageInviteInstance.ts @@ -0,0 +1,29 @@ +import type { BigString, DiscordInviteStageInstance, DiscordMember } from '@discordeno/types' +import type { Bot, Member } from '../index.js' + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export function transformInviteStageInstance(bot: Bot, payload: DiscordInviteStageInstance & { guildId: BigString }) { + const props = bot.transformers.desiredProperties.inviteStageInstance + const inviteStageInstance = {} as InviteStageInstance + + if (props.members && payload.members) { + inviteStageInstance.members = payload.members.map((member) => + bot.transformers.member(bot, member, payload.guildId, bot.transformers.snowflake(member.user?.id)), + ) + } + if (props.participantCount && payload.participant_count) inviteStageInstance.participantCount = payload.participant_count + if (props.speakerCount && payload.speaker_count) inviteStageInstance.participantCount = payload.participant_count + if (props.topic && payload.topic) inviteStageInstance.topic = payload.topic + return inviteStageInstance +} + +export interface InviteStageInstance { + /** The members speaking in the Stage */ + members: Array> + /** The number of users in the Stage */ + participantCount: number + /** The number of users speaking in the Stage */ + speakerCount: number + /** The topic of the Stage instance (1-120 characters) */ + topic: string +} diff --git a/packages/utils/src/typeguards.ts b/packages/utils/src/typeguards.ts index cddd3def8..d7d3fdb94 100644 --- a/packages/utils/src/typeguards.ts +++ b/packages/utils/src/typeguards.ts @@ -1,4 +1,12 @@ -import type { GetMessagesAfter, GetMessagesAround, GetMessagesBefore, GetMessagesLimit, GetMessagesOptions } from '@discordeno/types' +import type { + DiscordInviteCreate, + DiscordInviteMetadata, + GetMessagesAfter, + GetMessagesAround, + GetMessagesBefore, + GetMessagesLimit, + GetMessagesOptions, +} from '@discordeno/types' import { hasProperty } from './utils.js' export function isGetMessagesAfter(options: GetMessagesOptions): options is GetMessagesAfter { @@ -16,3 +24,7 @@ export function isGetMessagesAround(options: GetMessagesOptions): options is Get export function isGetMessagesLimit(options: GetMessagesOptions): options is GetMessagesLimit { return hasProperty(options, 'limit') } + +export function isInviteWithMetadata(options: DiscordInviteCreate | DiscordInviteMetadata): options is DiscordInviteMetadata { + return !hasProperty(options, 'channel_id') +}