From 9eb9591473902a7608aed9c1927690c4445a6fb9 Mon Sep 17 00:00:00 2001 From: Rodry <38259440+ImRodry@users.noreply.github.com> Date: Sun, 3 Oct 2021 13:59:52 +0100 Subject: [PATCH] fix: don't patch set data with undefined (#6694) --- src/structures/AnonymousGuild.js | 63 ++++--- src/structures/ApplicationCommand.js | 62 ++++--- src/structures/BaseGuildEmoji.js | 8 +- src/structures/BaseGuildVoiceChannel.js | 36 ++-- src/structures/ClientApplication.js | 68 ++++--- src/structures/ClientUser.js | 2 +- src/structures/DMChannel.js | 26 +-- src/structures/Guild.js | 218 +++++++++++++---------- src/structures/GuildBan.js | 12 +- src/structures/GuildPreview.js | 98 +++++----- src/structures/GuildTemplate.js | 138 ++++++++------ src/structures/Integration.js | 24 +-- src/structures/IntegrationApplication.js | 126 ++++++++----- src/structures/Invite.js | 202 +++++++++++++-------- src/structures/InviteStageInstance.js | 36 ++-- src/structures/Message.js | 6 +- src/structures/MessageAttachment.js | 78 ++++---- src/structures/MessageReaction.js | 5 +- src/structures/PermissionOverwrites.js | 36 ++-- src/structures/Presence.js | 48 +++-- src/structures/Role.js | 85 +++++---- src/structures/StageInstance.js | 70 +++++--- src/structures/Sticker.js | 136 ++++++++------ src/structures/Team.js | 41 +++-- src/structures/TeamMember.js | 36 ++-- src/structures/ThreadChannel.js | 12 +- src/structures/ThreadMember.js | 14 +- src/structures/Typing.js | 12 +- src/structures/User.js | 16 +- src/structures/VoiceState.js | 150 ++++++++++------ src/structures/Webhook.js | 104 ++++++----- src/structures/Widget.js | 36 ++-- src/structures/interfaces/Application.js | 46 +++-- 33 files changed, 1233 insertions(+), 817 deletions(-) diff --git a/src/structures/AnonymousGuild.js b/src/structures/AnonymousGuild.js index e146a577f1a2..4f723661a23b 100644 --- a/src/structures/AnonymousGuild.js +++ b/src/structures/AnonymousGuild.js @@ -15,36 +15,47 @@ class AnonymousGuild extends BaseGuild { } _patch(data) { - this.features = data.features; - /** - * The hash of the guild invite splash image - * @type {?string} - */ - this.splash = data.splash; + if ('features' in data) this.features = data.features; - /** - * The hash of the guild banner - * @type {?string} - */ - this.banner = data.banner; + if ('splash' in data) { + /** + * The hash of the guild invite splash image + * @type {?string} + */ + this.splash = data.splash; + } + + if ('banner' in data) { + /** + * The hash of the guild banner + * @type {?string} + */ + this.banner = data.banner; + } - /** - * The description of the guild, if any - * @type {?string} - */ - this.description = data.description; + if ('description' in data) { + /** + * The description of the guild, if any + * @type {?string} + */ + this.description = data.description; + } - /** - * The verification level of the guild - * @type {VerificationLevel} - */ - this.verificationLevel = VerificationLevels[data.verification_level]; + if ('verification_level' in data) { + /** + * The verification level of the guild + * @type {VerificationLevel} + */ + this.verificationLevel = VerificationLevels[data.verification_level]; + } - /** - * The vanity invite code of the guild, if any - * @type {?string} - */ - this.vanityURLCode = data.vanity_url_code; + if ('vanity_url_code' in data) { + /** + * The vanity invite code of the guild, if any + * @type {?string} + */ + this.vanityURLCode = data.vanity_url_code; + } if ('nsfw_level' in data) { /** diff --git a/src/structures/ApplicationCommand.js b/src/structures/ApplicationCommand.js index 58d0f8c48e67..b6c99a443587 100644 --- a/src/structures/ApplicationCommand.js +++ b/src/structures/ApplicationCommand.js @@ -54,35 +54,47 @@ class ApplicationCommand extends Base { } _patch(data) { - /** - * The name of this command - * @type {string} - */ - this.name = data.name; + if ('name' in data) { + /** + * The name of this command + * @type {string} + */ + this.name = data.name; + } - /** - * The description of this command - * @type {string} - */ - this.description = data.description; + if ('description' in data) { + /** + * The description of this command + * @type {string} + */ + this.description = data.description; + } - /** - * The options of this command - * @type {ApplicationCommandOption[]} - */ - this.options = data.options?.map(o => this.constructor.transformOption(o, true)) ?? []; + if ('options' in data) { + /** + * The options of this command + * @type {ApplicationCommandOption[]} + */ + this.options = data.options.map(o => this.constructor.transformOption(o, true)); + } else { + this.options ??= []; + } - /** - * Whether the command is enabled by default when the app is added to a guild - * @type {boolean} - */ - this.defaultPermission = data.default_permission; + if ('default_permission' in data) { + /** + * Whether the command is enabled by default when the app is added to a guild + * @type {boolean} + */ + this.defaultPermission = data.default_permission; + } - /** - * Autoincrementing version identifier updated during substantial record changes - * @type {Snowflake} - */ - this.version = data.version; + if ('version' in data) { + /** + * Autoincrementing version identifier updated during substantial record changes + * @type {Snowflake} + */ + this.version = data.version; + } } /** diff --git a/src/structures/BaseGuildEmoji.js b/src/structures/BaseGuildEmoji.js index f7245f62af5f..41dc792c2850 100644 --- a/src/structures/BaseGuildEmoji.js +++ b/src/structures/BaseGuildEmoji.js @@ -25,9 +25,9 @@ class BaseGuildEmoji extends Emoji { } _patch(data) { - if (data.name) this.name = data.name; + if ('name' in data) this.name = data.name; - if (typeof data.require_colons !== 'undefined') { + if ('require_colons' in data) { /** * Whether or not this emoji requires colons surrounding it * @type {?boolean} @@ -35,7 +35,7 @@ class BaseGuildEmoji extends Emoji { this.requiresColons = data.require_colons; } - if (typeof data.managed !== 'undefined') { + if ('managed' in data) { /** * Whether this emoji is managed by an external service * @type {?boolean} @@ -43,7 +43,7 @@ class BaseGuildEmoji extends Emoji { this.managed = data.managed; } - if (typeof data.available !== 'undefined') { + if ('available' in data) { /** * Whether this emoji is available * @type {?boolean} diff --git a/src/structures/BaseGuildVoiceChannel.js b/src/structures/BaseGuildVoiceChannel.js index d678fd2b0830..b3ef2f8b8127 100644 --- a/src/structures/BaseGuildVoiceChannel.js +++ b/src/structures/BaseGuildVoiceChannel.js @@ -12,23 +12,29 @@ class BaseGuildVoiceChannel extends GuildChannel { _patch(data) { super._patch(data); - /** - * The RTC region for this voice-based channel. This region is automatically selected if `null`. - * @type {?string} - */ - this.rtcRegion = data.rtc_region; + if ('rtc_region' in data) { + /** + * The RTC region for this voice-based channel. This region is automatically selected if `null`. + * @type {?string} + */ + this.rtcRegion = data.rtc_region; + } - /** - * The bitrate of this voice-based channel - * @type {number} - */ - this.bitrate = data.bitrate; + if ('bitrate' in data) { + /** + * The bitrate of this voice-based channel + * @type {number} + */ + this.bitrate = data.bitrate; + } - /** - * The maximum amount of users allowed in this channel. - * @type {number} - */ - this.userLimit = data.user_limit; + if ('user_limit' in data) { + /** + * The maximum amount of users allowed in this channel. + * @type {number} + */ + this.userLimit = data.user_limit; + } } /** diff --git a/src/structures/ClientApplication.js b/src/structures/ClientApplication.js index 4eb95a6c41bb..6ad83464b9a6 100644 --- a/src/structures/ClientApplication.js +++ b/src/structures/ClientApplication.js @@ -23,35 +23,53 @@ class ClientApplication extends Application { _patch(data) { super._patch(data); - /** - * The flags this application has - * @type {ApplicationFlags} - */ - this.flags = 'flags' in data ? new ApplicationFlags(data.flags).freeze() : this.flags; + if ('flags' in data) { + /** + * The flags this application has + * @type {ApplicationFlags} + */ + this.flags = new ApplicationFlags(data.flags).freeze(); + } - /** - * The hash of the application's cover image - * @type {?string} - */ - this.cover = data.cover_image ?? this.cover ?? null; + if ('cover_image' in data) { + /** + * The hash of the application's cover image + * @type {?string} + */ + this.cover = data.cover_image; + } else { + this.cover ??= null; + } - /** - * The application's RPC origins, if enabled - * @type {string[]} - */ - this.rpcOrigins = data.rpc_origins ?? this.rpcOrigins ?? []; + if ('rpc_origins' in data) { + /** + * The application's RPC origins, if enabled + * @type {string[]} + */ + this.rpcOrigins = data.rpc_origins; + } else { + this.rpcOrigins ??= []; + } - /** - * If this application's bot requires a code grant when using the OAuth2 flow - * @type {?boolean} - */ - this.botRequireCodeGrant = data.bot_require_code_grant ?? this.botRequireCodeGrant ?? null; + if ('bot_require_code_grant' in data) { + /** + * If this application's bot requires a code grant when using the OAuth2 flow + * @type {?boolean} + */ + this.botRequireCodeGrant = data.bot_require_code_grant; + } else { + this.botRequireCodeGrant ??= null; + } - /** - * If this application's bot is public - * @type {?boolean} - */ - this.botPublic = data.bot_public ?? this.botPublic ?? null; + if ('bot_public' in data) { + /** + * If this application's bot is public + * @type {?boolean} + */ + this.botPublic = data.bot_public; + } else { + this.botPublic ??= null; + } /** * The owner of this OAuth application diff --git a/src/structures/ClientUser.js b/src/structures/ClientUser.js index 6b3c80c7b0b7..9136752f0b3f 100644 --- a/src/structures/ClientUser.js +++ b/src/structures/ClientUser.js @@ -29,7 +29,7 @@ class ClientUser extends User { this.mfaEnabled ??= null; } - if (data.token) this.client.token = data.token; + if ('token' in data) this.client.token = data.token; } /** diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index 7ebc159bade0..52704c052cb6 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -38,17 +38,23 @@ class DMChannel extends Channel { this.recipient = this.client.users._add(data.recipients[0]); } - /** - * The channel's last message id, if one was sent - * @type {?Snowflake} - */ - this.lastMessageId = data.last_message_id; + if ('last_message_id' in data) { + /** + * The channel's last message id, if one was sent + * @type {?Snowflake} + */ + this.lastMessageId = data.last_message_id; + } - /** - * The timestamp when the last pinned message was pinned, if there was one - * @type {?number} - */ - this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; + if ('last_pin_timestamp' in data) { + /** + * The timestamp when the last pinned message was pinned, if there was one + * @type {?number} + */ + this.lastPinTimestamp = new Date(data.last_pin_timestamp).getTime(); + } else { + this.lastPinTimestamp ??= null; + } } /** diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 8379b88c6a78..5fb14ba0702d 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -140,27 +140,33 @@ class Guild extends AnonymousGuild { _patch(data) { super._patch(data); this.id = data.id; - this.name = data.name; - this.icon = data.icon; - this.available = !data.unavailable; + if ('name' in data) this.name = data.name; + if ('icon' in data) this.icon = data.icon; + if ('unavailable' in data) this.available = !data.unavailable; - /** - * The hash of the guild discovery splash image - * @type {?string} - */ - this.discoverySplash = data.discovery_splash; + if ('discovery_splash' in data) { + /** + * The hash of the guild discovery splash image + * @type {?string} + */ + this.discoverySplash = data.discovery_splash; + } - /** - * The full amount of members in this guild - * @type {number} - */ - this.memberCount = data.member_count ?? this.memberCount; + if ('member_count' in data) { + /** + * The full amount of members in this guild + * @type {number} + */ + this.memberCount = data.member_count; + } - /** - * Whether the guild is "large" (has more than large_threshold members, 50 by default) - * @type {boolean} - */ - this.large = Boolean(data.large ?? this.large); + if ('large' in data) { + /** + * Whether the guild is "large" (has more than {@link WebsocketOptions large_threshold} members, 50 by default) + * @type {boolean} + */ + this.large = Boolean(data.large); + } /** * An array of enabled guild features, here are the possible values: @@ -189,37 +195,47 @@ class Guild extends AnonymousGuild { * @see {@link https://discord.com/developers/docs/resources/guild#guild-object-guild-features} */ - /** - * The id of the application that created this guild (if applicable) - * @type {?Snowflake} - */ - this.applicationId = data.application_id; + if ('application_id' in data) { + /** + * The id of the application that created this guild (if applicable) + * @type {?Snowflake} + */ + this.applicationId = data.application_id; + } - /** - * The time in seconds before a user is counted as "away from keyboard" - * @type {?number} - */ - this.afkTimeout = data.afk_timeout; + if ('afk_timeout' in data) { + /** + * The time in seconds before a user is counted as "away from keyboard" + * @type {?number} + */ + this.afkTimeout = data.afk_timeout; + } - /** - * The id of the voice channel where AFK members are moved - * @type {?Snowflake} - */ - this.afkChannelId = data.afk_channel_id; + if ('afk_channel_id' in data) { + /** + * The id of the voice channel where AFK members are moved + * @type {?Snowflake} + */ + this.afkChannelId = data.afk_channel_id; + } - /** - * The system channel's id - * @type {?Snowflake} - */ - this.systemChannelId = data.system_channel_id; + if ('system_channel_id' in data) { + /** + * The system channel's id + * @type {?Snowflake} + */ + this.systemChannelId = data.system_channel_id; + } - /** - * The premium tier of this guild - * @type {PremiumTier} - */ - this.premiumTier = PremiumTiers[data.premium_tier]; + if ('premium_tier' in data) { + /** + * The premium tier of this guild + * @type {PremiumTier} + */ + this.premiumTier = PremiumTiers[data.premium_tier]; + } - if (typeof data.premium_subscription_count !== 'undefined') { + if ('premium_subscription_count' in data) { /** * The total number of boosts for this server * @type {?number} @@ -227,7 +243,7 @@ class Guild extends AnonymousGuild { this.premiumSubscriptionCount = data.premium_subscription_count; } - if (typeof data.widget_enabled !== 'undefined') { + if ('widget_enabled' in data) { /** * Whether widget images are enabled on this guild * @type {?boolean} @@ -235,7 +251,7 @@ class Guild extends AnonymousGuild { this.widgetEnabled = data.widget_enabled; } - if (typeof data.widget_channel_id !== 'undefined') { + if ('widget_channel_id' in data) { /** * The widget channel's id, if enabled * @type {?string} @@ -243,37 +259,47 @@ class Guild extends AnonymousGuild { this.widgetChannelId = data.widget_channel_id; } - /** - * The explicit content filter level of the guild - * @type {ExplicitContentFilterLevel} - */ - this.explicitContentFilter = ExplicitContentFilterLevels[data.explicit_content_filter]; + if ('explicit_content_filter' in data) { + /** + * The explicit content filter level of the guild + * @type {ExplicitContentFilterLevel} + */ + this.explicitContentFilter = ExplicitContentFilterLevels[data.explicit_content_filter]; + } - /** - * The required MFA level for this guild - * @type {MFALevel} - */ - this.mfaLevel = MFALevels[data.mfa_level]; + if ('mfa_level' in data) { + /** + * The required MFA level for this guild + * @type {MFALevel} + */ + this.mfaLevel = MFALevels[data.mfa_level]; + } - /** - * The timestamp the client user joined the guild at - * @type {number} - */ - this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp; + if ('joined_at' in data) { + /** + * The timestamp the client user joined the guild at + * @type {number} + */ + this.joinedTimestamp = new Date(data.joined_at).getTime(); + } - /** - * The default message notification level of the guild - * @type {DefaultMessageNotificationLevel} - */ - this.defaultMessageNotifications = DefaultMessageNotificationLevels[data.default_message_notifications]; + if ('default_message_notifications' in data) { + /** + * The default message notification level of the guild + * @type {DefaultMessageNotificationLevel} + */ + this.defaultMessageNotifications = DefaultMessageNotificationLevels[data.default_message_notifications]; + } - /** - * The value set for the guild's system channel flags - * @type {Readonly} - */ - this.systemChannelFlags = new SystemChannelFlags(data.system_channel_flags).freeze(); + if ('system_channel_flags' in data) { + /** + * The value set for the guild's system channel flags + * @type {Readonly} + */ + this.systemChannelFlags = new SystemChannelFlags(data.system_channel_flags).freeze(); + } - if (typeof data.max_members !== 'undefined') { + if ('max_members' in data) { /** * The maximum amount of members the guild can have * @type {?number} @@ -283,7 +309,7 @@ class Guild extends AnonymousGuild { this.maximumMembers ??= null; } - if (typeof data.max_presences !== 'undefined') { + if ('max_presences' in data) { /** * The maximum amount of presences the guild can have * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter @@ -294,7 +320,7 @@ class Guild extends AnonymousGuild { this.maximumPresences ??= null; } - if (typeof data.approximate_member_count !== 'undefined') { + if ('approximate_member_count' in data) { /** * The approximate amount of members the guild has * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter @@ -305,7 +331,7 @@ class Guild extends AnonymousGuild { this.approximateMemberCount ??= null; } - if (typeof data.approximate_presence_count !== 'undefined') { + if ('approximate_presence_count' in data) { /** * The approximate amount of presences the guild has * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter @@ -321,26 +347,32 @@ class Guild extends AnonymousGuild { * You will need to fetch this parameter using {@link Guild#fetchVanityData} if you want to receive it * @type {?number} */ - this.vanityURLUses = null; + this.vanityURLUses ??= null; - /** - * The rules channel's id for the guild - * @type {?Snowflake} - */ - this.rulesChannelId = data.rules_channel_id; + if ('rules_channel_id' in data) { + /** + * The rules channel's id for the guild + * @type {?Snowflake} + */ + this.rulesChannelId = data.rules_channel_id; + } - /** - * The community updates channel's id for the guild - * @type {?Snowflake} - */ - this.publicUpdatesChannelId = data.public_updates_channel_id; + if ('public_updates_channel_id' in data) { + /** + * The community updates channel's id for the guild + * @type {?Snowflake} + */ + this.publicUpdatesChannelId = data.public_updates_channel_id; + } - /** - * The preferred locale of the guild, defaults to `en-US` - * @type {string} - * @see {@link https://discord.com/developers/docs/dispatch/field-values#predefined-field-values-accepted-locales} - */ - this.preferredLocale = data.preferred_locale; + if ('preferred_locale' in data) { + /** + * The preferred locale of the guild, defaults to `en-US` + * @type {string} + * @see {@link https://discord.com/developers/docs/dispatch/field-values#predefined-field-values-accepted-locales} + */ + this.preferredLocale = data.preferred_locale; + } if (data.channels) { this.channels.cache.clear(); @@ -365,7 +397,7 @@ class Guild extends AnonymousGuild { for (const guildUser of data.members) this.members._add(guildUser); } - if (data.owner_id) { + if ('owner_id' in data) { /** * The user id of this guild's owner * @type {Snowflake} diff --git a/src/structures/GuildBan.js b/src/structures/GuildBan.js index d3cdc6e2509b..1157c25b73e2 100644 --- a/src/structures/GuildBan.js +++ b/src/structures/GuildBan.js @@ -25,11 +25,13 @@ class GuildBan extends Base { } _patch(data) { - /** - * The user this ban applies to - * @type {User} - */ - this.user = this.client.users._add(data.user, true); + if ('user' in data) { + /** + * The user this ban applies to + * @type {User} + */ + this.user = this.client.users._add(data.user, true); + } if ('reason' in data) { /** diff --git a/src/structures/GuildPreview.js b/src/structures/GuildPreview.js index 239476fe4896..bbe5ae03bcd0 100644 --- a/src/structures/GuildPreview.js +++ b/src/structures/GuildPreview.js @@ -30,53 +30,71 @@ class GuildPreview extends Base { */ this.id = data.id; - /** - * The name of this guild - * @type {string} - */ - this.name = data.name; + if ('name' in data) { + /** + * The name of this guild + * @type {string} + */ + this.name = data.name; + } - /** - * The icon of this guild - * @type {?string} - */ - this.icon = data.icon; + if ('icon' in data) { + /** + * The icon of this guild + * @type {?string} + */ + this.icon = data.icon; + } - /** - * The splash icon of this guild - * @type {?string} - */ - this.splash = data.splash; + if ('splash' in data) { + /** + * The splash icon of this guild + * @type {?string} + */ + this.splash = data.splash; + } - /** - * The discovery splash icon of this guild - * @type {?string} - */ - this.discoverySplash = data.discovery_splash; + if ('discovery_splash' in data) { + /** + * The discovery splash icon of this guild + * @type {?string} + */ + this.discoverySplash = data.discovery_splash; + } - /** - * An array of enabled guild features - * @type {Features[]} - */ - this.features = data.features; + if ('features' in data) { + /** + * An array of enabled guild features + * @type {Features[]} + */ + this.features = data.features; + } - /** - * The approximate count of members in this guild - * @type {number} - */ - this.approximateMemberCount = data.approximate_member_count; + if ('approximate_member_count' in data) { + /** + * The approximate count of members in this guild + * @type {number} + */ + this.approximateMemberCount = data.approximate_member_count; + } - /** - * The approximate count of online members in this guild - * @type {number} - */ - this.approximatePresenceCount = data.approximate_presence_count; + if ('approximate_presence_count' in data) { + /** + * The approximate count of online members in this guild + * @type {number} + */ + this.approximatePresenceCount = data.approximate_presence_count; + } - /** - * The description for this guild - * @type {?string} - */ - this.description = data.description ?? null; + if ('description' in data) { + /** + * The description for this guild + * @type {?string} + */ + this.description = data.description; + } else { + this.description ??= null; + } if (!this.emojis) { /** diff --git a/src/structures/GuildTemplate.js b/src/structures/GuildTemplate.js index 953a7cf9d9c0..a52d87a219ff 100644 --- a/src/structures/GuildTemplate.js +++ b/src/structures/GuildTemplate.js @@ -25,65 +25,85 @@ class GuildTemplate extends Base { * @private */ _patch(data) { - /** - * The unique code of this template - * @type {string} - */ - this.code = data.code; - - /** - * The name of this template - * @type {string} - */ - this.name = data.name; - - /** - * The description of this template - * @type {?string} - */ - this.description = data.description; - - /** - * The amount of times this template has been used - * @type {number} - */ - this.usageCount = data.usage_count; - - /** - * The id of the user that created this template - * @type {Snowflake} - */ - this.creatorId = data.creator_id; - - /** - * The user that created this template - * @type {User} - */ - this.creator = this.client.users._add(data.creator); - - /** - * The time of when this template was created at - * @type {Date} - */ - this.createdAt = new Date(data.created_at); - - /** - * The time of when this template was last synced to the guild - * @type {Date} - */ - this.updatedAt = new Date(data.updated_at); - - /** - * The id of the guild that this template belongs to - * @type {Snowflake} - */ - this.guildId = data.source_guild_id; - - /** - * The data of the guild that this template would create - * @type {APIGuild} - */ - this.serializedGuild = data.serialized_source_guild; + if ('code' in data) { + /** + * The unique code of this template + * @type {string} + */ + this.code = data.code; + } + + if ('name' in data) { + /** + * The name of this template + * @type {string} + */ + this.name = data.name; + } + + if ('description' in data) { + /** + * The description of this template + * @type {?string} + */ + this.description = data.description; + } + + if ('usage_count' in data) { + /** + * The amount of times this template has been used + * @type {number} + */ + this.usageCount = data.usage_count; + } + + if ('creator_id' in data) { + /** + * The id of the user that created this template + * @type {Snowflake} + */ + this.creatorId = data.creator_id; + } + + if ('creator' in data) { + /** + * The user that created this template + * @type {User} + */ + this.creator = this.client.users._add(data.creator); + } + + if ('created_at' in data) { + /** + * The time of when this template was created at + * @type {Date} + */ + this.createdAt = new Date(data.created_at); + } + + if ('updated_at' in data) { + /** + * The time of when this template was last synced to the guild + * @type {Date} + */ + this.updatedAt = new Date(data.updated_at); + } + + if ('source_guild_id' in data) { + /** + * The id of the guild that this template belongs to + * @type {Snowflake} + */ + this.guildId = data.source_guild_id; + } + + if ('serialized_source_guild' in data) { + /** + * The data of the guild that this template would create + * @type {APIGuild} + */ + this.serializedGuild = data.serialized_source_guild; + } /** * Whether this template has unsynced changes diff --git a/src/structures/Integration.js b/src/structures/Integration.js index 674b7b8fb212..525f75aab4aa 100644 --- a/src/structures/Integration.js +++ b/src/structures/Integration.js @@ -125,17 +125,21 @@ class Integration extends Base { } _patch(data) { - /** - * The behavior of expiring subscribers - * @type {?number} - */ - this.expireBehavior = data.expire_behavior; + if ('expire_behavior' in data) { + /** + * The behavior of expiring subscribers + * @type {?number} + */ + this.expireBehavior = data.expire_behavior; + } - /** - * The grace period before expiring subscribers - * @type {?number} - */ - this.expireGracePeriod = data.expire_grace_period; + if ('expire_grace_period' in data) { + /** + * The grace period before expiring subscribers + * @type {?number} + */ + this.expireGracePeriod = data.expire_grace_period; + } if ('application' in data) { if (this.application) { diff --git a/src/structures/IntegrationApplication.js b/src/structures/IntegrationApplication.js index d9a6d394680f..25e6a7d70b9b 100644 --- a/src/structures/IntegrationApplication.js +++ b/src/structures/IntegrationApplication.js @@ -10,53 +10,85 @@ class IntegrationApplication extends Application { _patch(data) { super._patch(data); - /** - * The bot user for this application - * @type {?User} - */ - this.bot = data.bot ? this.client.users._add(data.bot) : this.bot ?? null; - - /** - * The url of the application's terms of service - * @type {?string} - */ - this.termsOfServiceURL = data.terms_of_service_url ?? this.termsOfServiceURL ?? null; - - /** - * The url of the application's privacy policy - * @type {?string} - */ - this.privacyPolicyURL = data.privacy_policy_url ?? this.privacyPolicyURL ?? null; - - /** - * The Array of RPC origin urls - * @type {string[]} - */ - this.rpcOrigins = data.rpc_origins ?? this.rpcOrigins ?? []; - - /** - * The application's summary - * @type {?string} - */ - this.summary = data.summary ?? this.summary ?? null; - - /** - * Whether the application can be default hooked by the client - * @type {?boolean} - */ - this.hook = data.hook ?? this.hook ?? null; - - /** - * The hash of the application's cover image - * @type {?string} - */ - this.cover = data.cover_image ?? this.cover ?? null; - - /** - * The hex-encoded key for verification in interactions and the GameSDK's GetTicket - * @type {?string} - */ - this.verifyKey = data.verify_key ?? this.verifyKey ?? null; + if ('bot' in data) { + /** + * The bot user for this application + * @type {?User} + */ + this.bot = this.client.users._add(data.bot); + } else { + this.bot ??= null; + } + + if ('terms_of_service_url' in data) { + /** + * The url of the application's terms of service + * @type {?string} + */ + this.termsOfServiceURL = data.terms_of_service_url; + } else { + this.termsOfServiceURL ??= null; + } + + if ('privacy_policy_url' in data) { + /** + * The url of the application's privacy policy + * @type {?string} + */ + this.privacyPolicyURL = data.privacy_policy_url; + } else { + this.privacyPolicyURL ??= null; + } + + if ('rpc_origins' in data) { + /** + * The Array of RPC origin urls + * @type {string[]} + */ + this.rpcOrigins = data.rpc_origins; + } else { + this.rpcOrigins ??= []; + } + + if ('summary' in data) { + /** + * The application's summary + * @type {?string} + */ + this.summary = data.summary; + } else { + this.summary ??= null; + } + + if ('hook' in data) { + /** + * Whether the application can be default hooked by the client + * @type {?boolean} + */ + this.hook = data.hook; + } else { + this.hook ??= null; + } + + if ('cover_image' in data) { + /** + * The hash of the application's cover image + * @type {?string} + */ + this.cover = data.cover_image; + } else { + this.cover ??= null; + } + + if ('verify_key' in data) { + /** + * The hex-encoded key for verification in interactions and the GameSDK's GetTicket + * @type {?string} + */ + this.verifyKey = data.verify_key; + } else { + this.verifyKey ??= null; + } } } diff --git a/src/structures/Invite.js b/src/structures/Invite.js index b9b3f42a8a0c..e0d08f4eeafe 100644 --- a/src/structures/Invite.js +++ b/src/structures/Invite.js @@ -24,72 +24,108 @@ class Invite extends Base { * The guild the invite is for including welcome screen data if present * @type {?(Guild|InviteGuild)} */ - this.guild = null; + this.guild ??= null; if (data.guild) { this.guild = this.client.guilds.resolve(data.guild.id) ?? new InviteGuild(this.client, data.guild); } - /** - * The code for this invite - * @type {string} - */ - this.code = data.code; + if ('code' in data) { + /** + * The code for this invite + * @type {string} + */ + this.code = data.code; + } - /** - * The approximate number of online members of the guild this invite is for - * @type {?number} - */ - this.presenceCount = data.approximate_presence_count ?? null; + if ('approximate_presence_count' in data) { + /** + * The approximate number of online members of the guild this invite is for + * @type {?number} + */ + this.presenceCount = data.approximate_presence_count; + } else { + this.presenceCount ??= null; + } - /** - * The approximate total number of members of the guild this invite is for - * @type {?number} - */ - this.memberCount = data.approximate_member_count ?? null; + if ('approximate_member_count' in data) { + /** + * The approximate total number of members of the guild this invite is for + * @type {?number} + */ + this.memberCount = data.approximate_member_count; + } else { + this.memberCount ??= null; + } - /** - * Whether or not this invite is temporary - * @type {?boolean} - */ - this.temporary = data.temporary ?? null; + if ('temporary' in data) { + /** + * Whether or not this invite only grants temporary membership + * @type {?boolean} + */ + this.temporary = data.temporary ?? null; + } else { + this.temporary ??= null; + } - /** - * The maximum age of the invite, in seconds, 0 if never expires - * @type {?number} - */ - this.maxAge = data.max_age ?? null; + if ('max_age' in data) { + /** + * The maximum age of the invite, in seconds, 0 if never expires + * @type {?number} + */ + this.maxAge = data.max_age; + } else { + this.maxAge ??= null; + } - /** - * How many times this invite has been used - * @type {?number} - */ - this.uses = data.uses ?? null; + if ('uses' in data) { + /** + * How many times this invite has been used + * @type {?number} + */ + this.uses = data.uses; + } else { + this.uses ??= null; + } - /** - * The maximum uses of this invite - * @type {?number} - */ - this.maxUses = data.max_uses ?? null; + if ('max_uses' in data) { + /** + * The maximum uses of this invite + * @type {?number} + */ + this.maxUses = data.max_uses; + } else { + this.maxUses ??= null; + } - /** - * The user who created this invite - * @type {?User} - */ - this.inviter = data.inviter ? this.client.users._add(data.inviter) : null; + if ('inviter' in data) { + /** + * The user who created this invite + * @type {?User} + */ + this.inviter = this.client.users._add(data.inviter); + } else { + this.inviter ??= null; + } - /** - * The user whose stream to display for this voice channel stream invite - * @type {?User} - */ - this.targetUser = data.target_user ? this.client.users._add(data.target_user) : null; + if ('target_user' in data) { + /** + * The user whose stream to display for this voice channel stream invite + * @type {?User} + */ + this.targetUser = this.client.users._add(data.target_user); + } else { + this.targetUser ??= null; + } - /** - * The embedded application to open for this voice channel embedded application invite - * @type {?IntegrationApplication} - */ - this.targetApplication = data.target_application - ? new IntegrationApplication(this.client, data.target_application) - : null; + if ('target_application' in data) { + /** + * The embedded application to open for this voice channel embedded application invite + * @type {?IntegrationApplication} + */ + this.targetApplication = new IntegrationApplication(this.client, data.target_application); + } else { + this.targetApplication ??= null; + } /** * The type of the invite target: @@ -99,34 +135,46 @@ class Invite extends Base { * @see {@link https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types} */ - /** - * The target type - * @type {?TargetType} - */ - this.targetType = data.target_type ?? null; + if ('target_type' in data) { + /** + * The target type + * @type {?TargetType} + */ + this.targetType = data.target_type; + } else { + this.targetType ??= null; + } - /** - * The channel the invite is for - * @type {Channel} - */ - this.channel = this.client.channels._add(data.channel, this.guild, { cache: false }); + if ('channel' in data) { + /** + * The channel the invite is for + * @type {Channel} + */ + this.channel = this.client.channels._add(data.channel, this.guild, { cache: false }); + } - /** - * The timestamp the invite was created at - * @type {?number} - */ - this.createdTimestamp = 'created_at' in data ? new Date(data.created_at).getTime() : null; + if ('created_at' in data) { + /** + * The timestamp the invite was created at + * @type {?number} + */ + this.createdTimestamp = new Date(data.created_at).getTime(); + } else { + this.createdTimestamp ??= null; + } - this._expiresTimestamp = 'expires_at' in data ? new Date(data.expires_at).getTime() : null; + if ('expires_at' in data) this._expiresTimestamp = new Date(data.expires_at).getTime(); + else this._expiresTimestamp ??= null; - /** - * The stage instance data if there is a public {@link StageInstance} in the stage channel this invite is for - * @type {?InviteStageInstance} - */ - this.stageInstance = - 'stage_instance' in data - ? new InviteStageInstance(this.client, data.stage_instance, this.channel.id, this.guild.id) - : null; + if ('stage_instance' in data) { + /** + * The stage instance data if there is a public {@link StageInstance} in the stage channel this invite is for + * @type {?InviteStageInstance} + */ + this.stageInstance = new InviteStageInstance(this.client, data.stage_instance, this.channel.id, this.guild.id); + } else { + this.stageInstance ??= null; + } } /** diff --git a/src/structures/InviteStageInstance.js b/src/structures/InviteStageInstance.js index 6356ba28bf80..73db63ace504 100644 --- a/src/structures/InviteStageInstance.js +++ b/src/structures/InviteStageInstance.js @@ -33,23 +33,29 @@ class InviteStageInstance extends Base { } _patch(data) { - /** - * The topic of the stage instance - * @type {string} - */ - this.topic = data.topic; + if ('topic' in data) { + /** + * The topic of the stage instance + * @type {string} + */ + this.topic = data.topic; + } - /** - * The number of users in the stage channel - * @type {number} - */ - this.participantCount = data.participant_count; + if ('participant_count' in data) { + /** + * The number of users in the stage channel + * @type {number} + */ + this.participantCount = data.participant_count; + } - /** - * The number of users speaking in the stage channel - * @type {number} - */ - this.speakerCount = data.speaker_count; + if ('speaker_count' in data) { + /** + * The number of users speaking in the stage channel + * @type {number} + */ + this.speakerCount = data.speaker_count; + } this.members.clear(); for (const rawMember of data.members) { diff --git a/src/structures/Message.js b/src/structures/Message.js index 80e312b3fb7c..0112f645ba4c 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -71,9 +71,9 @@ class Message extends Base { * @type {?boolean} */ this.system = SystemMessageTypes.includes(this.type); - } else if (typeof this.type !== 'string') { - this.system = null; - this.type = null; + } else { + this.system ??= null; + this.type ??= null; } if ('content' in data) { diff --git a/src/structures/MessageAttachment.js b/src/structures/MessageAttachment.js index 513c136d98d5..15cef63c5d9e 100644 --- a/src/structures/MessageAttachment.js +++ b/src/structures/MessageAttachment.js @@ -68,41 +68,59 @@ class MessageAttachment { */ this.id = data.id; - /** - * The size of this attachment in bytes - * @type {number} - */ - this.size = data.size; + if ('size' in data) { + /** + * The size of this attachment in bytes + * @type {number} + */ + this.size = data.size; + } - /** - * The URL to this attachment - * @type {string} - */ - this.url = data.url; + if ('url' in data) { + /** + * The URL to this attachment + * @type {string} + */ + this.url = data.url; + } - /** - * The Proxy URL to this attachment - * @type {string} - */ - this.proxyURL = data.proxy_url; + if ('proxy_url' in data) { + /** + * The Proxy URL to this attachment + * @type {string} + */ + this.proxyURL = data.proxy_url; + } - /** - * The height of this attachment (if an image or video) - * @type {?number} - */ - this.height = data.height ?? null; + if ('height' in data) { + /** + * The height of this attachment (if an image or video) + * @type {?number} + */ + this.height = data.height; + } else { + this.height ??= null; + } - /** - * The width of this attachment (if an image or video) - * @type {?number} - */ - this.width = data.width ?? null; + if ('width' in data) { + /** + * The width of this attachment (if an image or video) + * @type {?number} + */ + this.width = data.width; + } else { + this.width ??= null; + } - /** - * This media type of this attachment - * @type {?string} - */ - this.contentType = data.content_type ?? null; + if ('content_type' in data) { + /** + * This media type of this attachment + * @type {?string} + */ + this.contentType = data.content_type; + } else { + this.contentType ??= null; + } /** * Whether this attachment is ephemeral diff --git a/src/structures/MessageReaction.js b/src/structures/MessageReaction.js index a2feb37d8b45..799f3051d475 100644 --- a/src/structures/MessageReaction.js +++ b/src/structures/MessageReaction.js @@ -47,13 +47,12 @@ class MessageReaction { } _patch(data) { - // eslint-disable-next-line eqeqeq - if (this.count == undefined) { + if ('count' in data) { /** * The number of people that have given the same reaction * @type {?number} */ - this.count = data.count; + this.count ??= data.count; } } diff --git a/src/structures/PermissionOverwrites.js b/src/structures/PermissionOverwrites.js index edb00db40ca0..f9351a8e6007 100644 --- a/src/structures/PermissionOverwrites.js +++ b/src/structures/PermissionOverwrites.js @@ -32,23 +32,29 @@ class PermissionOverwrites extends Base { */ this.id = data.id; - /** - * The type of this overwrite - * @type {OverwriteType} - */ - this.type = typeof data.type === 'number' ? OverwriteTypes[data.type] : data.type; + if ('type' in data) { + /** + * The type of this overwrite + * @type {OverwriteType} + */ + this.type = typeof data.type === 'number' ? OverwriteTypes[data.type] : data.type; + } - /** - * The permissions that are denied for the user or role. - * @type {Readonly} - */ - this.deny = new Permissions(BigInt(data.deny)).freeze(); + if ('deny' in data) { + /** + * The permissions that are denied for the user or role. + * @type {Readonly} + */ + this.deny = new Permissions(BigInt(data.deny)).freeze(); + } - /** - * The permissions that are allowed for the user or role. - * @type {Readonly} - */ - this.allow = new Permissions(BigInt(data.allow)).freeze(); + if ('allow' in data) { + /** + * The permissions that are allowed for the user or role. + * @type {Readonly} + */ + this.allow = new Permissions(BigInt(data.allow)).freeze(); + } } /** diff --git a/src/structures/Presence.js b/src/structures/Presence.js index 47a549636ace..bad6f8a1a1b1 100644 --- a/src/structures/Presence.js +++ b/src/structures/Presence.js @@ -76,26 +76,38 @@ class Presence extends Base { } _patch(data) { - /** - * The status of this presence - * @type {PresenceStatus} - */ - this.status = data.status ?? this.status ?? 'offline'; + if ('status' in data) { + /** + * The status of this presence + * @type {PresenceStatus} + */ + this.status = data.status; + } else { + this.status ??= 'offline'; + } - /** - * The activities of this presence - * @type {Activity[]} - */ - this.activities = data.activities?.map(activity => new Activity(this, activity)) ?? []; + if ('activities' in data) { + /** + * The activities of this presence + * @type {Activity[]} + */ + this.activities = data.activities.map(activity => new Activity(this, activity)); + } else { + this.activities ??= []; + } - /** - * The devices this presence is on - * @type {?Object} - * @property {?ClientPresenceStatus} web The current presence in the web application - * @property {?ClientPresenceStatus} mobile The current presence in the mobile application - * @property {?ClientPresenceStatus} desktop The current presence in the desktop application - */ - this.clientStatus = data.client_status ?? null; + if ('client_status' in data) { + /** + * The devices this presence is on + * @type {?Object} + * @property {?ClientPresenceStatus} web The current presence in the web application + * @property {?ClientPresenceStatus} mobile The current presence in the mobile application + * @property {?ClientPresenceStatus} desktop The current presence in the desktop application + */ + this.clientStatus = data.client_status; + } else { + this.clientStatus ??= null; + } return this; } diff --git a/src/structures/Role.js b/src/structures/Role.js index d5faa92b9db2..9e7bd9be122c 100644 --- a/src/structures/Role.js +++ b/src/structures/Role.js @@ -34,48 +34,61 @@ class Role extends Base { * @type {Snowflake} */ this.id = data.id; + if ('name' in data) { + /** + * The name of the role + * @type {string} + */ + this.name = data.name; + } - /** - * The name of the role - * @type {string} - */ - this.name = data.name; - - /** - * The base 10 color of the role - * @type {number} - */ - this.color = data.color; + if ('color' in data) { + /** + * The base 10 color of the role + * @type {number} + */ + this.color = data.color; + } - /** - * If true, users that are part of this role will appear in a separate category in the users list - * @type {boolean} - */ - this.hoist = data.hoist; + if ('hoist' in data) { + /** + * If true, users that are part of this role will appear in a separate category in the users list + * @type {boolean} + */ + this.hoist = data.hoist; + } - /** - * The raw position of the role from the API - * @type {number} - */ - this.rawPosition = data.position; + if ('position' in data) { + /** + * The raw position of the role from the API + * @type {number} + */ + this.rawPosition = data.position; + } - /** - * The permissions of the role - * @type {Readonly} - */ - this.permissions = new Permissions(BigInt(data.permissions)).freeze(); + if ('permissions' in data) { + /** + * The permissions of the role + * @type {Readonly} + */ + this.permissions = new Permissions(BigInt(data.permissions)).freeze(); + } - /** - * Whether or not the role is managed by an external service - * @type {boolean} - */ - this.managed = data.managed; + if ('managed' in data) { + /** + * Whether or not the role is managed by an external service + * @type {boolean} + */ + this.managed = data.managed; + } - /** - * Whether or not the role can be mentioned by anyone - * @type {boolean} - */ - this.mentionable = data.mentionable; + if ('mentionable' in data) { + /** + * Whether or not the role can be mentioned by anyone + * @type {boolean} + */ + this.mentionable = data.mentionable; + } /** * Whether the role has been deleted diff --git a/src/structures/StageInstance.js b/src/structures/StageInstance.js index 460ec6a830e5..e2e89b8c09fd 100644 --- a/src/structures/StageInstance.js +++ b/src/structures/StageInstance.js @@ -28,35 +28,47 @@ class StageInstance extends Base { } _patch(data) { - /** - * The id of the guild associated with the stage channel - * @type {Snowflake} - */ - this.guildId = data.guild_id; - - /** - * The id of the channel associated with the stage channel - * @type {Snowflake} - */ - this.channelId = data.channel_id; - - /** - * The topic of the stage instance - * @type {string} - */ - this.topic = data.topic; - - /** - * The privacy level of the stage instance - * @type {PrivacyLevel} - */ - this.privacyLevel = PrivacyLevels[data.privacy_level]; - - /** - * Whether or not stage discovery is disabled - * @type {?boolean} - */ - this.discoverableDisabled = data.discoverable_disabled ?? null; + if ('guild_id' in data) { + /** + * The id of the guild associated with the stage channel + * @type {Snowflake} + */ + this.guildId = data.guild_id; + } + + if ('channel_id' in data) { + /** + * The id of the channel associated with the stage channel + * @type {Snowflake} + */ + this.channelId = data.channel_id; + } + + if ('topic' in data) { + /** + * The topic of the stage instance + * @type {string} + */ + this.topic = data.topic; + } + + if ('privacy_level' in data) { + /** + * The privacy level of the stage instance + * @type {PrivacyLevel} + */ + this.privacyLevel = PrivacyLevels[data.privacy_level]; + } + + if ('discoverable_disabled' in data) { + /** + * Whether or not stage discovery is disabled + * @type {?boolean} + */ + this.discoverableDisabled = data.discoverable_disabled; + } else { + this.discoverableDisabled ??= null; + } } /** diff --git a/src/structures/Sticker.js b/src/structures/Sticker.js index fa9ccc116661..54e5e9d42ef3 100644 --- a/src/structures/Sticker.js +++ b/src/structures/Sticker.js @@ -26,65 +26,101 @@ class Sticker extends Base { */ this.id = sticker.id; - /** - * The description of the sticker - * @type {?string} - */ - this.description = sticker.description ?? null; + if ('description' in sticker) { + /** + * The description of the sticker + * @type {?string} + */ + this.description = sticker.description; + } else { + this.description ??= null; + } - /** - * The type of the sticker - * @type {?StickerType} - */ - this.type = StickerTypes[sticker.type] ?? null; + if ('type' in sticker) { + /** + * The type of the sticker + * @type {?StickerType} + */ + this.type = StickerTypes[sticker.type]; + } else { + this.type ??= null; + } - /** - * The format of the sticker - * @type {StickerFormatType} - */ - this.format = StickerFormatTypes[sticker.format_type]; + if ('format_type' in sticker) { + /** + * The format of the sticker + * @type {StickerFormatType} + */ + this.format = StickerFormatTypes[sticker.format_type]; + } - /** - * The name of the sticker - * @type {string} - */ - this.name = sticker.name; + if ('name' in sticker) { + /** + * The name of the sticker + * @type {string} + */ + this.name = sticker.name; + } - /** - * The id of the pack the sticker is from, for standard stickers - * @type {?Snowflake} - */ - this.packId = sticker.pack_id ?? null; + if ('pack_id' in sticker) { + /** + * The id of the pack the sticker is from, for standard stickers + * @type {?Snowflake} + */ + this.packId = sticker.pack_id; + } else { + this.packId ??= null; + } - /** - * An array of tags for the sticker - * @type {?string[]} - */ - this.tags = sticker.tags?.split(', ') ?? null; + if ('tags' in sticker) { + /** + * An array of tags for the sticker + * @type {?string[]} + */ + this.tags = sticker.tags.split(', '); + } else { + this.tags ??= null; + } - /** - * Whether or not the guild sticker is available - * @type {?boolean} - */ - this.available = sticker.available ?? null; + if ('available' in sticker) { + /** + * Whether or not the guild sticker is available + * @type {?boolean} + */ + this.available = sticker.available; + } else { + this.available ??= null; + } - /** - * The id of the guild that owns this sticker - * @type {?Snowflake} - */ - this.guildId = sticker.guild_id ?? null; + if ('guild_id' in sticker) { + /** + * The id of the guild that owns this sticker + * @type {?Snowflake} + */ + this.guildId = sticker.guild_id; + } else { + this.guildId ??= null; + } - /** - * The user that uploaded the guild sticker - * @type {?User} - */ - this.user = sticker.user ? this.client.users._add(sticker.user) : null; + if ('user' in sticker) { + /** + * The user that uploaded the guild sticker + * @type {?User} + */ + this.user = this.client.users._add(sticker.user); + } else { + this.user ??= null; + } - /** - * The standard sticker's sort order within its pack - * @type {?number} - */ - this.sortValue = sticker.sort_value ?? null; + if ('sort_value' in sticker) { + /** + * The standard sticker's sort order within its pack + * @type {?number} + */ + this.sortValue = sticker.sort_value; + } else { + this.sortValue ??= null; + } } /** diff --git a/src/structures/Team.js b/src/structures/Team.js index 63a28b0a7d45..380e60696be3 100644 --- a/src/structures/Team.js +++ b/src/structures/Team.js @@ -22,24 +22,33 @@ class Team extends Base { */ this.id = data.id; - /** - * The name of the Team - * @type {string} - */ - this.name = data.name; - - /** - * The Team's icon hash - * @type {?string} - */ - this.icon = data.icon ?? null; + if ('name' in data) { + /** + * The name of the Team + * @type {string} + */ + this.name = data.name; + } - /** - * The Team's owner id - * @type {?Snowflake} - */ - this.ownerId = data.owner_user_id ?? null; + if ('icon' in data) { + /** + * The Team's icon hash + * @type {?string} + */ + this.icon = data.icon; + } else { + this.icon ??= null; + } + if ('owner_user_id' in data) { + /** + * The Team's owner id + * @type {?Snowflake} + */ + this.ownerId = data.owner_user_id; + } else { + this.ownerId ??= null; + } /** * The Team's members * @type {Collection} diff --git a/src/structures/TeamMember.js b/src/structures/TeamMember.js index 146c291c1c66..9bd5993aadba 100644 --- a/src/structures/TeamMember.js +++ b/src/structures/TeamMember.js @@ -21,23 +21,29 @@ class TeamMember extends Base { } _patch(data) { - /** - * The permissions this Team Member has with regard to the team - * @type {string[]} - */ - this.permissions = data.permissions; + if ('permissions' in data) { + /** + * The permissions this Team Member has with regard to the team + * @type {string[]} + */ + this.permissions = data.permissions; + } - /** - * The permissions this Team Member has with regard to the team - * @type {MembershipState} - */ - this.membershipState = MembershipStates[data.membership_state]; + if ('membership_state' in data) { + /** + * The permissions this Team Member has with regard to the team + * @type {MembershipState} + */ + this.membershipState = MembershipStates[data.membership_state]; + } - /** - * The user for this Team Member - * @type {User} - */ - this.user = this.client.users._add(data.user); + if ('user' in data) { + /** + * The user for this Team Member + * @type {User} + */ + this.user = this.client.users._add(data.user); + } } /** diff --git a/src/structures/ThreadChannel.js b/src/structures/ThreadChannel.js index 420a4163d54d..e2f45886f967 100644 --- a/src/structures/ThreadChannel.js +++ b/src/structures/ThreadChannel.js @@ -51,11 +51,13 @@ class ThreadChannel extends Channel { _patch(data, partial = false) { super._patch(data); - /** - * The name of the thread - * @type {string} - */ - this.name = data.name; + if ('name' in data) { + /** + * The name of the thread + * @type {string} + */ + this.name = data.name; + } if ('guild_id' in data) { this.guildId = data.guild_id; diff --git a/src/structures/ThreadMember.js b/src/structures/ThreadMember.js index 147f603f76c6..252de831efd0 100644 --- a/src/structures/ThreadMember.js +++ b/src/structures/ThreadMember.js @@ -37,13 +37,15 @@ class ThreadMember extends Base { } _patch(data) { - this.joinedTimestamp = new Date(data.join_timestamp).getTime(); + if ('join_timestamp' in data) this.joinedTimestamp = new Date(data.join_timestamp).getTime(); - /** - * The flags for this thread member - * @type {ThreadMemberFlags} - */ - this.flags = new ThreadMemberFlags(data.flags).freeze(); + if ('flags' in data) { + /** + * The flags for this thread member + * @type {ThreadMemberFlags} + */ + this.flags = new ThreadMemberFlags(data.flags).freeze(); + } } /** diff --git a/src/structures/Typing.js b/src/structures/Typing.js index 9b3d8968191d..96599e18902e 100644 --- a/src/structures/Typing.js +++ b/src/structures/Typing.js @@ -31,11 +31,13 @@ class Typing extends Base { } _patch(data) { - /** - * The UNIX timestamp in milliseconds the user started typing at - * @type {number} - */ - this.startedTimestamp = data.timestamp * 1_000; + if ('timestamp' in data) { + /** + * The UNIX timestamp in milliseconds the user started typing at + * @type {number} + */ + this.startedTimestamp = data.timestamp * 1_000; + } } /** diff --git a/src/structures/User.js b/src/structures/User.js index b1dca83f8104..ec652cef1d69 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -41,8 +41,8 @@ class User extends Base { * @type {?string} */ this.username = data.username; - } else if (typeof this.username !== 'string') { - this.username = null; + } else { + this.username ??= null; } if ('bot' in data) { @@ -61,8 +61,8 @@ class User extends Base { * @type {?string} */ this.discriminator = data.discriminator; - } else if (typeof this.discriminator !== 'string') { - this.discriminator = null; + } else { + this.discriminator ??= null; } if ('avatar' in data) { @@ -71,8 +71,8 @@ class User extends Base { * @type {?string} */ this.avatar = data.avatar; - } else if (typeof this.avatar !== 'string') { - this.avatar = null; + } else { + this.avatar ??= null; } if ('banner' in data) { @@ -82,8 +82,8 @@ class User extends Base { * @type {?string} */ this.banner = data.banner; - } else if (typeof this.banner !== 'string') { - this.banner = null; + } else { + this.banner ??= null; } if ('accent_color' in data) { diff --git a/src/structures/VoiceState.js b/src/structures/VoiceState.js index f26ae6f06a98..39b799590c94 100644 --- a/src/structures/VoiceState.js +++ b/src/structures/VoiceState.js @@ -27,58 +27,104 @@ class VoiceState extends Base { } _patch(data) { - /** - * Whether this member is deafened server-wide - * @type {?boolean} - */ - this.serverDeaf = data.deaf ?? null; - /** - * Whether this member is muted server-wide - * @type {?boolean} - */ - this.serverMute = data.mute ?? null; - /** - * Whether this member is self-deafened - * @type {?boolean} - */ - this.selfDeaf = data.self_deaf ?? null; - /** - * Whether this member is self-muted - * @type {?boolean} - */ - this.selfMute = data.self_mute ?? null; - /** - * Whether this member's camera is enabled - * @type {?boolean} - */ - this.selfVideo = data.self_video ?? null; - /** - * The session id for this member's connection - * @type {?string} - */ - this.sessionId = data.session_id ?? null; - /** - * Whether this member is streaming using "Screen Share" - * @type {boolean} - */ - this.streaming = data.self_stream ?? false; - /** - * The {@link VoiceChannel} or {@link StageChannel} id the member is in - * @type {?Snowflake} - */ - this.channelId = data.channel_id ?? null; - /** - * Whether this member is suppressed from speaking. This property is specific to stage channels only. - * @type {boolean} - */ - this.suppress = data.suppress; - /** - * The time at which the member requested to speak. This property is specific to stage channels only. - * @type {?number} - */ - this.requestToSpeakTimestamp = data.request_to_speak_timestamp - ? new Date(data.request_to_speak_timestamp).getTime() - : null; + if ('deaf' in data) { + /** + * Whether this member is deafened server-wide + * @type {?boolean} + */ + this.serverDeaf = data.deaf; + } else { + this.serverDeaf ??= null; + } + + if ('mute' in data) { + /** + * Whether this member is muted server-wide + * @type {?boolean} + */ + this.serverMute = data.mute; + } else { + this.serverMute ??= null; + } + + if ('self_deaf' in data) { + /** + * Whether this member is self-deafened + * @type {?boolean} + */ + this.selfDeaf = data.self_deaf; + } else { + this.selfDeaf ??= null; + } + + if ('self_mute' in data) { + /** + * Whether this member is self-muted + * @type {?boolean} + */ + this.selfMute = data.self_mute; + } else { + this.selfMute ??= null; + } + + if ('self_video' in data) { + /** + * Whether this member's camera is enabled + * @type {?boolean} + */ + this.selfVideo = data.self_video; + } else { + this.selfVideo ??= null; + } + + if ('session_id' in data) { + /** + * The session id for this member's connection + * @type {?string} + */ + this.sessionId = data.session_id; + } else { + this.sessionId ??= null; + } + + if ('self_streaming' in data) { + /** + * Whether this member is streaming using "Screen Share" + * @type {boolean} + */ + this.streaming = data.self_stream ?? false; + } else { + this.streaming ??= null; + } + + if ('channel_id' in data) { + /** + * The {@link VoiceChannel} or {@link StageChannel} id the member is in + * @type {?Snowflake} + */ + this.channelId = data.channel_id; + } else { + this.channelId ??= null; + } + + if ('suppress' in data) { + /** + * Whether this member is suppressed from speaking. This property is specific to stage channels only. + * @type {boolean} + */ + this.suppress = data.suppress; + } + + if ('request_to_speak_timestamp' in data) { + /** + * The time at which the member requested to speak. This property is specific to stage channels only. + * @type {?number} + */ + this.requestToSpeakTimestamp = new Date(data.request_to_speak_timestamp).getTime(); + } else { + this.requestToSpeakTimestamp ??= null; + } + return this; } diff --git a/src/structures/Webhook.js b/src/structures/Webhook.js index 31db5249a3f5..da65af8f9b6e 100644 --- a/src/structures/Webhook.js +++ b/src/structures/Webhook.js @@ -22,11 +22,13 @@ class Webhook { } _patch(data) { - /** - * The name of the webhook - * @type {string} - */ - this.name = data.name; + if ('name' in data) { + /** + * The name of the webhook + * @type {string} + */ + this.name = data.name; + } /** * The token for the webhook, unavailable for follower webhooks and webhooks owned by another application. @@ -35,11 +37,13 @@ class Webhook { */ Object.defineProperty(this, 'token', { value: data.token ?? null, writable: true, configurable: true }); - /** - * The avatar for the webhook - * @type {?string} - */ - this.avatar = data.avatar; + if ('avatar' in data) { + /** + * The avatar for the webhook + * @type {?string} + */ + this.avatar = data.avatar; + } /** * The webhook's id @@ -47,43 +51,59 @@ class Webhook { */ this.id = data.id; - /** - * The type of the webhook - * @type {WebhookType} - */ - this.type = WebhookTypes[data.type]; + if ('type' in data) { + /** + * The type of the webhook + * @type {WebhookType} + */ + this.type = WebhookTypes[data.type]; + } - /** - * The guild the webhook belongs to - * @type {Snowflake} - */ - this.guildId = data.guild_id; + if ('guild_id' in data) { + /** + * The guild the webhook belongs to + * @type {Snowflake} + */ + this.guildId = data.guild_id; + } - /** - * The channel the webhook belongs to - * @type {Snowflake} - */ - this.channelId = data.channel_id; + if ('channel_id' in data) { + /** + * The channel the webhook belongs to + * @type {Snowflake} + */ + this.channelId = data.channel_id; + } - /** - * The owner of the webhook - * @type {?(User|APIUser)} - */ - this.owner = data.user ? this.client.users?._add(data.user) ?? data.user : null; + if ('user' in data) { + /** + * The owner of the webhook + * @type {?(User|APIUser)} + */ + this.owner = this.client.users?._add(data.user) ?? data.user; + } else { + this.owner ??= null; + } - /** - * The source guild of the webhook - * @type {?(Guild|APIGuild)} - */ - this.sourceGuild = data.source_guild - ? this.client.guilds?._add(data.source_guild, false) ?? data.source_guild - : null; + if ('source_guild' in data) { + /** + * The source guild of the webhook + * @type {?(Guild|APIGuild)} + */ + this.sourceGuild = this.client.guilds?._add(data.source_guild, false) ?? data.source_guild; + } else { + this.sourceGuild ??= null; + } - /** - * The source channel of the webhook - * @type {?(Channel|APIChannel)} - */ - this.sourceChannel = this.client.channels?.resolve(data.source_channel?.id) ?? data.source_channel ?? null; + if ('source_channel' in data) { + /** + * The source channel of the webhook + * @type {?(Channel|APIChannel)} + */ + this.sourceChannel = this.client.channels?.resolve(data.source_channel?.id) ?? data.source_channel; + } else { + this.sourceChannel ??= null; + } } /** diff --git a/src/structures/Widget.js b/src/structures/Widget.js index 773ea821a0c8..cf6f6b5a4477 100644 --- a/src/structures/Widget.js +++ b/src/structures/Widget.js @@ -37,17 +37,21 @@ class Widget extends Base { */ this.id = data.id; - /** - * The name of the guild. - * @type {string} - */ - this.name = data.name; + if ('name' in data) { + /** + * The name of the guild. + * @type {string} + */ + this.name = data.name; + } - /** - * The invite of the guild. - * @type {?string} - */ - this.instantInvite = data.instant_invite; + if ('instant_invite' in data) { + /** + * The invite of the guild. + * @type {?string} + */ + this.instantInvite = data.instant_invite; + } /** * The list of channels in the guild. @@ -68,11 +72,13 @@ class Widget extends Base { this.members.set(member.id, new WidgetMember(this.client, member)); } - /** - * The number of the members online. - * @type {number} - */ - this.presenceCount = data.presence_count; + if ('presence_count' in data) { + /** + * The number of the members online. + * @type {number} + */ + this.presenceCount = data.presence_count; + } } /** diff --git a/src/structures/interfaces/Application.js b/src/structures/interfaces/Application.js index 29a1d5b5f5f3..3cfa051dfff3 100644 --- a/src/structures/interfaces/Application.js +++ b/src/structures/interfaces/Application.js @@ -23,23 +23,35 @@ class Application extends Base { */ this.id = data.id; - /** - * The name of the application - * @type {?string} - */ - this.name = data.name ?? this.name ?? null; - - /** - * The application's description - * @type {?string} - */ - this.description = data.description ?? this.description ?? null; - - /** - * The application's icon hash - * @type {?string} - */ - this.icon = data.icon ?? this.icon ?? null; + if ('name' in data) { + /** + * The name of the application + * @type {?string} + */ + this.name = data.name; + } else { + this.name ??= null; + } + + if ('description' in data) { + /** + * The application's description + * @type {?string} + */ + this.description = data.description; + } else { + this.description ??= null; + } + + if ('icon' in data) { + /** + * The application's icon hash + * @type {?string} + */ + this.icon = data.icon; + } else { + this.icon ??= null; + } } /**