From 7b258faa52ded7c7c0fd1b280c8b6c758e475132 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:48:19 -0400 Subject: [PATCH 01/14] feat(types): type some more stores Co-Authored-By: prism <69634294+imjustprism@users.noreply.github.com> --- packages/discord-types/enums/activity.ts | 26 +- packages/discord-types/enums/application.ts | 43 + packages/discord-types/enums/channel.ts | 146 +++- packages/discord-types/enums/commands.ts | 35 +- packages/discord-types/enums/guild.ts | 103 +++ packages/discord-types/enums/index.ts | 5 + packages/discord-types/enums/messages.ts | 115 +++ packages/discord-types/enums/misc.ts | 67 +- packages/discord-types/enums/quests.ts | 390 +++++++++ packages/discord-types/enums/settings.ts | 42 + packages/discord-types/enums/user.ts | 41 +- packages/discord-types/enums/voice.ts | 50 ++ .../discord-types/src/common/Activity.d.ts | 14 +- .../discord-types/src/common/Application.d.ts | 61 +- .../discord-types/src/common/Channel.d.ts | 378 +++++++-- packages/discord-types/src/common/Guild.d.ts | 45 +- .../discord-types/src/common/GuildMember.d.ts | 32 +- packages/discord-types/src/common/Role.d.ts | 20 +- packages/discord-types/src/common/User.d.ts | 103 ++- .../src/common/messages/Embed.d.ts | 87 ++- .../src/common/messages/Message.d.ts | 169 +++- .../src/common/messages/Sticker.d.ts | 2 +- packages/discord-types/src/components.d.ts | 38 +- packages/discord-types/src/flux.d.ts | 37 + packages/discord-types/src/fluxEvents.d.ts | 2 +- packages/discord-types/src/menu.d.ts | 9 +- .../src/stores/AccessibilityStore.d.ts | 3 +- .../stores/ApplicationCommandIndexStore.d.ts | 443 +++++++++++ .../src/stores/ApplicationStore.d.ts | 4 +- .../src/stores/ChannelRTCStore.d.ts | 12 +- .../src/stores/ChannelStore.d.ts | 94 ++- .../src/stores/EditMessageStore.d.ts | 253 ++++++ .../src/stores/ExperimentStore.d.ts | 101 +++ .../src/stores/FriendsStore.d.ts | 4 +- .../src/stores/GuildScheduledEventStore.d.ts | 4 +- .../discord-types/src/stores/InviteStore.d.ts | 22 +- .../src/stores/MediaEngineStore.d.ts | 2 +- .../src/stores/OverridePremiumTypeStore.d.ts | 11 +- .../src/stores/PendingReplyStore.d.ts | 7 + .../discord-types/src/stores/QuestStore.d.ts | 738 ++++++++++++++++++ .../src/stores/RTCConnectionStore.d.ts | 3 +- .../src/stores/RelationshipStore.d.ts | 7 +- .../src/stores/RunningGameStore.d.ts | 4 +- .../src/stores/SpotifyStore.d.ts | 17 +- .../src/stores/StickersStore.d.ts | 42 +- .../src/stores/UserAffinitiesStore.d.ts | 33 + .../src/stores/UserGuildSettingsStore.d.ts | 35 +- .../src/stores/UserProfileStore.d.ts | 8 +- .../src/stores/UserSettingsProtoStore.d.ts | 11 +- .../src/stores/VoiceStateStore.d.ts | 4 + packages/discord-types/src/stores/index.d.ts | 5 + packages/discord-types/src/utils.d.ts | 151 +++- src/plugins/implicitRelationships/index.ts | 5 +- src/webpack/common/stores.ts | 10 + 54 files changed, 3755 insertions(+), 338 deletions(-) create mode 100644 packages/discord-types/enums/application.ts create mode 100644 packages/discord-types/enums/guild.ts create mode 100644 packages/discord-types/enums/quests.ts create mode 100644 packages/discord-types/enums/settings.ts create mode 100644 packages/discord-types/enums/voice.ts create mode 100644 packages/discord-types/src/stores/ApplicationCommandIndexStore.d.ts create mode 100644 packages/discord-types/src/stores/EditMessageStore.d.ts create mode 100644 packages/discord-types/src/stores/ExperimentStore.d.ts create mode 100644 packages/discord-types/src/stores/QuestStore.d.ts create mode 100644 packages/discord-types/src/stores/UserAffinitiesStore.d.ts diff --git a/packages/discord-types/enums/activity.ts b/packages/discord-types/enums/activity.ts index 513a65dee2..90a7e85aec 100644 --- a/packages/discord-types/enums/activity.ts +++ b/packages/discord-types/enums/activity.ts @@ -20,7 +20,8 @@ export const enum ActivityFlags { PARTY_PRIVACY_FRIENDS = 1 << 6, PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7, EMBEDDED = 1 << 8, - CONTEXTLESS = 1 << 9 + CONTEXTLESS = 1 << 9, + SUPPORTS_GATEWAY_ACTIVITY_ACTION_JOIN = 1 << 10, } export const enum ActivityStatusDisplayType { @@ -28,3 +29,26 @@ export const enum ActivityStatusDisplayType { STATE = 1, DETAILS = 2 } + +export const enum OrientationLockState { + UNLOCKED = 1, + PORTRAIT = 2, + LANDSCAPE = 3, +} + +export const enum ActivityGameMode { + PLAY = 0, + SPECTATE = 1, +} + +export const enum ActivityLayout { + FOCUSED = 0, + PIP = 1, + GRID = 2, +} + +export const enum ActivityLabelType { + NONE = 0, + NEW = 1, + UPDATED = 2, +} diff --git a/packages/discord-types/enums/application.ts b/packages/discord-types/enums/application.ts new file mode 100644 index 0000000000..b032a2a8ff --- /dev/null +++ b/packages/discord-types/enums/application.ts @@ -0,0 +1,43 @@ +export const enum ApplicationType { + DEPRECATED_GAME = 1, + TICKETED_EVENTS = 3, + GUILD_ROLE_SUBSCRIPTIONS = 4, + GAME = 5, + NON_GAME_DETECTABLE = 6, +} + +export const enum LinkedGameType { + LINKED = 1, + OFFICIAL = 2, + NVIDIA = 3, +} + +export const enum CarouselItemType { + IMG = 1, + YOUTUBE_VIDEO = 2, + VIDEO = 3, +} + +export const enum ApplicationFlags { + EMBEDDED_RELEASED = 2, + EMBEDDED_IAP = 8, + APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 64, + GAME_PROFILE_DISABLED = 128, + CONTEXTLESS_ACTIVITY = 512, + SOCIAL_LAYER_INTEGRATION_LIMITED = 1024, + CLOUD_GAMING_DEMO = 2048, + GATEWAY_PRESENCE = 4096, + GATEWAY_PRESENCE_LIMITED = 8192, + GATEWAY_GUILD_MEMBERS = 16384, + GATEWAY_GUILD_MEMBERS_LIMITED = 32768, + EMBEDDED = 131072, + GATEWAY_MESSAGE_CONTENT = 262144, + GATEWAY_MESSAGE_CONTENT_LIMITED = 524288, + EMBEDDED_FIRST_PARTY = 1048576, + APPLICATION_COMMAND_BADGE = 8388608, + SOCIAL_LAYER_INTEGRATION = 134217728, + PROMOTED = 536870912, + PARTNER = 1073741824, + PARENT = 8589934592, + DISABLE_RELATIONSHIPS_ACCESS = 17179869184, +} diff --git a/packages/discord-types/enums/channel.ts b/packages/discord-types/enums/channel.ts index a068b101b1..85ce11f357 100644 --- a/packages/discord-types/enums/channel.ts +++ b/packages/discord-types/enums/channel.ts @@ -1,3 +1,58 @@ +export const enum PermissionOverwriteType { + ROLE = 0, + MEMBER = 1, + OWNER = 2 +} + +export const enum PermissionOverwriteRowType { + EMPTY_STATE = 0, + ADMINISTRATOR = 1, + ROLE = 2, + OWNER = 3, + MEMBER = 4, + USER = 5, + GUILD = 6, +} + +export const enum PermissionOverwriteSectionType { + ROLES = 0, + MEMBERS = 1, + USERS = 2, + GUILDS = 3, +} + +export const enum ForumLayout { + DEFAULT = 0, + LIST = 1, + GRID = 2, +} + +export const enum SafetyWarningType { + STRANGER_DANGER = 1, + INAPPROPRIATE_CONVERSATION_TIER_1 = 2, + INAPPROPRIATE_CONVERSATION_TIER_2 = 3, + LIKELY_ATO = 4, +} + +export const enum ChannelFlags { + GUILD_FEED_REMOVED = 1, + PINNED = 2, + ACTIVE_CHANNELS_REMOVED = 4, + REQUIRE_TAG = 16, + IS_SPAM = 32, + IS_GUILD_RESOURCE_CHANNEL = 128, + CLYDE_AI = 256, + IS_SCHEDULED_FOR_DELETION = 512, + IS_MEDIA_CHANNEL = 1024, + SUMMARIES_DISABLED = 2048, + IS_ROLE_SUBSCRIPTION_TEMPLATE_PREVIEW_CHANNEL = 8192, + IS_BROADCASTING = 16384, + HIDE_MEDIA_DOWNLOAD_OPTIONS = 32768, + IS_JOIN_REQUEST_INTERVIEW_CHANNEL = 65536, + OBFUSCATED = 131072, + IS_MODERATOR_REPORT_CHANNEL = 524288, +} + export const enum ChannelType { GUILD_TEXT = 0, DM = 1, @@ -5,11 +60,100 @@ export const enum ChannelType { GROUP_DM = 3, GUILD_CATEGORY = 4, GUILD_ANNOUNCEMENT = 5, + GUILD_STORE = 6, ANNOUNCEMENT_THREAD = 10, PUBLIC_THREAD = 11, PRIVATE_THREAD = 12, GUILD_STAGE_VOICE = 13, GUILD_DIRECTORY = 14, GUILD_FORUM = 15, - GUILD_MEDIA = 16 + GUILD_MEDIA = 16, + LOBBY = 17, + DM_SDK = 18, + UNKNOWN = 10000, +} + +/** + * Pre-defined Sets of channel types for grouping related channels. + * Each property is a Set containing channel type numbers. + */ +export interface ChannelTypesSets { + /** DM and GROUP_DM, channels that support calling. */ + CALLABLE: Set; + /** Channels that support text messages. */ + TEXTUAL: Set; + /** Forum and media channels, threads only, no direct messages. */ + GUILD_THREADS_ONLY: Set; + /** Channels that support stickers. */ + STICKERS: Set; + /** Channels that can be read/viewed. */ + READABLE: Set; + /** All guild channel types including threads. */ + GUILD: Set; + /** Guild channels excluding threads. */ + GUILD_CHANNEL: Set; + /** All thread types (announcement, public, private). */ + THREADS: Set; + /** DM and GROUP_DM, private/non-guild channels. */ + PRIVATE_CHANNEL: Set; + /** Announcement and public threads only. */ + PUBLIC_THREADS: Set; + /** Guild channels that can have threads. */ + GUILD_THREADED: Set; + /** Guild channels that are persisted/stored. */ + GUILD_STORED: Set; + /** Guild channels with text capability. */ + GUILD_TEXTUAL: Set; + /** Guild voice and stage channels. */ + GUILD_VOCAL: Set; + /** Thread types that support voice. */ + VOCAL_THREAD: Set; + /** All channels with voice capability. */ + VOCAL: Set; + /** Channels that support voice effects. */ + VOICE_EFFECTS: Set; + /** Guild text-only channels (no voice). */ + GUILD_TEXT_ONLY: Set; + /** Channels with character-limited names. */ + LIMITED_CHANNEL_NAME: Set; + /** Channels that support message search. */ + SEARCHABLE: Set; + /** Guild channels with user-generated content. */ + GUILD_USER_CONTENT: Set; + /** Guild channels that can have topics. */ + GUILD_TOPICAL: Set; + /** Guild channels that support webhooks. */ + GUILD_WEBHOOKS: Set; + /** Guild channels usable as system message channel. */ + GUILD_SYSTEM_CHANNEL: Set; + /** Guild channels that can have a parent category. */ + GUILD_PARENTABLE: Set; + /** Guild channels subject to auto-moderation. */ + GUILD_AUTO_MODERATED: Set; + /** Basic guild channel types for creation. */ + GUILD_BASIC: Set; + /** Guild channel types that can be created. */ + CREATEABLE_GUILD_CHANNELS: Set; + /** GROUP_DM only, multi-user DMs. */ + MULTI_USER_DMS: Set; + /** DM and GROUP_DM. */ + ALL_DMS: Set; + /** Channels that support invites. */ + INVITABLE: Set; + /** Guild channels supporting feed-featurable messages. */ + GUILD_FEED_FEATURABLE_MESSAGES: Set; + /** Channels supporting role subscriptions. */ + ROLE_SUBSCRIPTIONS: Set; + /** Channels supporting icon emojis. */ + ICON_EMOJIS: Set; + /** Channels that can be summarized. */ + SUMMARIZEABLE: Set; + /** Channels supporting content entry embeds. */ + CONTENT_ENTRY_EMBEDS: Set; + /** Channels that support polls. */ + POLLS: Set; + /** Channels that can launch activities. */ + ACTIVITY_LAUNCHABLE: Set; + /** All known channel types. */ + ALL: Set; } diff --git a/packages/discord-types/enums/commands.ts b/packages/discord-types/enums/commands.ts index 298f9b7a36..f534dce81d 100644 --- a/packages/discord-types/enums/commands.ts +++ b/packages/discord-types/enums/commands.ts @@ -21,12 +21,45 @@ export const enum ApplicationCommandInputType { } export const enum ApplicationCommandType { + /** + * @remarks Discord API calls this just CHAT + */ CHAT_INPUT = 1, USER = 2, MESSAGE = 3, + PRIMARY_ENTRY_POINT = 4, } export const enum ApplicationIntegrationType { GUILD_INSTALL = 0, - USER_INSTALL = 1 + USER_INSTALL = 1, +} + +export const enum InteractionType { + APPLICATION_COMMAND = 2, + MESSAGE_COMPONENT = 3, + APPLICATION_COMMAND_AUTOCOMPLETE = 4, + MODAL_SUBMIT = 5, +} + +export const enum ApplicationCommandSectionType { + BUILT_IN = 0, + APPLICATION = 1, +} + +export const enum ApplicationCommandPermissionType { + ROLE = 1, + USER = 2, + CHANNEL = 3, +} + +export const enum InteractionContextType { + GUILD = 0, + BOT_DM = 1, + PRIVATE_CHANNEL = 2, +} + +export const enum ApplicationCommandHandlerType { + APP_HANDLER = 1, + DISCORD_LAUNCH_ACTIVITY = 2, } diff --git a/packages/discord-types/enums/guild.ts b/packages/discord-types/enums/guild.ts new file mode 100644 index 0000000000..fdb0bfc266 --- /dev/null +++ b/packages/discord-types/enums/guild.ts @@ -0,0 +1,103 @@ +export const enum GuildScheduledEventStatus { + SCHEDULED = 1, + ACTIVE = 2, + COMPLETED = 3, + CANCELED = 4, +} + +export const enum GuildScheduledEventEntityType { + NONE = 0, + STAGE_INSTANCE = 1, + VOICE = 2, + EXTERNAL = 3, + PRIME_TIME = 4, +} + +export const enum GuildScheduledEventPrivacyLevel { + PUBLIC = 1, + GUILD_ONLY = 2, +} + +export const enum GuildNSFWLevel { + DEFAULT = 0, + EXPLICIT = 1, + SAFE = 2, + AGE_RESTRICTED = 3, +} + +export const enum GuildVerificationLevel { + NONE = 0, + LOW = 1, + MEDIUM = 2, + HIGH = 3, + VERY_HIGH = 4, +} + +export const enum GuildExplicitContentFilter { + DISABLED = 0, + MEMBERS_WITHOUT_ROLES = 1, + ALL_MEMBERS = 2, +} + +export const enum GuildMFALevel { + NONE = 0, + ELEVATED = 1, +} + +export const enum GuildDefaultMessageNotifications { + ALL_MESSAGES = 0, + ONLY_MENTIONS = 1, +} + +export const enum GuildPremiumTier { + NONE = 0, + TIER_1 = 1, + TIER_2 = 2, + TIER_3 = 3, +} + +export const enum GuildSettingsFlags { + UNREADS_ALL_MESSAGES = 2048, + UNREADS_ONLY_MENTIONS = 4096, + OPT_IN_CHANNELS_OFF = 8192, + OPT_IN_CHANNELS_ON = 16384, +} + +export const enum SystemChannelFlags { + SUPPRESS_JOIN_NOTIFICATIONS = 1, + SUPPRESS_PREMIUM_SUBSCRIPTIONS = 2, + SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 4, + SUPPRESS_JOIN_NOTIFICATION_REPLIES = 8, + SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS = 16, + SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES = 32, + SUPPRESS_CHANNEL_PROMPT_DEADCHAT = 128, + SUPPRESS_UGC_ADDED_NOTIFICATIONS = 256, +} + +export const enum GuildMemberFlags { + DID_REJOIN = 1, + COMPLETED_ONBOARDING = 2, + BYPASSES_VERIFICATION = 4, + STARTED_ONBOARDING = 8, + IS_GUEST = 16, + STARTED_HOME_ACTIONS = 32, + COMPLETED_HOME_ACTIONS = 64, + AUTOMOD_QUARANTINED_USERNAME_OR_GUILD_NICKNAME = 128, + AUTOMOD_QUARANTINED_BIO = 256, + DM_SETTINGS_UPSELL_ACKNOWLEDGED = 512, + AUTOMOD_QUARANTINED_SERVER_TAG = 1024, +} + +export const enum RoleFlags { + IN_PROMPT = 1, +} + +export const enum RecurrenceRuleFrequency { + YEARLY = 0, + MONTHLY = 1, + WEEKLY = 2, + DAILY = 3, + HOURLY = 4, + MINUTELY = 5, + SECONDLY = 6, +} diff --git a/packages/discord-types/enums/index.ts b/packages/discord-types/enums/index.ts index e776577f92..6a1b60c4a5 100644 --- a/packages/discord-types/enums/index.ts +++ b/packages/discord-types/enums/index.ts @@ -1,6 +1,11 @@ export * from "./activity"; +export * from "./application"; export * from "./channel"; export * from "./commands"; +export * from "./guild"; export * from "./messages"; export * from "./misc"; +export * from "./quests"; +export * from "./settings"; export * from "./user"; +export * from "./voice"; diff --git a/packages/discord-types/enums/messages.ts b/packages/discord-types/enums/messages.ts index 8aa6fbb385..557e9bb285 100644 --- a/packages/discord-types/enums/messages.ts +++ b/packages/discord-types/enums/messages.ts @@ -1,3 +1,54 @@ +export const enum ComponentType { + UNKNOWN = -1, + ACTION_ROW = 1, + BUTTON = 2, + STRING_SELECT = 3, + TEXT_INPUT = 4, + USER_SELECT = 5, + ROLE_SELECT = 6, + MENTIONABLE_SELECT = 7, + CHANNEL_SELECT = 8, + SECTION = 9, + TEXT_DISPLAY = 10, + THUMBNAIL = 11, + MEDIA_GALLERY = 12, + FILE = 13, + SEPARATOR = 14, + CONTENT_INVENTORY_ENTRY = 16, + CONTAINER = 17, + LABEL = 18, + FILE_UPLOAD = 19, + CHECKPOINT_CARD = 20, +} + +export const enum ButtonStyle { + PRIMARY = 1, + SECONDARY = 2, + SUCCESS = 3, + DESTRUCTIVE = 4, + LINK = 5, + PREMIUM = 6, +} + +export const enum MessageReferenceType { + DEFAULT = 0, + FORWARD = 1, +} + +export const enum PollLayoutType { + UNKNOWN = 0, + DEFAULT = 1, + IMAGE_ONLY_ANSWERS = 2 +} + +export const enum MessageActivityType { + JOIN = 1, + LISTEN = 3, + WATCH = 4, + JOIN_REQUEST = 5, + STREAM_REQUEST = 6, +} + export const enum StickerType { /** an official sticker in a pack */ STANDARD = 1, @@ -92,6 +143,8 @@ export const enum MessageType { * Name: PREMIUM_GUILD_SUBSCRIPTION * Rendered Content: "{author} just boosted the server{content ? " {content} times"}!" * Deletable: true + * + * @remarks Discord API calls this GUILD_BOOST */ PREMIUM_GUILD_SUBSCRIPTION = 8, /** @@ -101,6 +154,8 @@ export const enum MessageType { * Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_1 * Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 1! " * Deletable: true + * + * @remarks Discord API calls this GUILD_BOOST_TIER_1 */ PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9, /** @@ -110,6 +165,8 @@ export const enum MessageType { * Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_2 * Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 2! " * Deletable: true + * + * @remarks Discord API calls this GUILD_BOOST_TIER_2 */ PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, /** @@ -119,6 +176,8 @@ export const enum MessageType { * Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_3 * Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 3! " * Deletable: true + * + * @remarks Discord API calls this GUILD_BOOST_TIER_3 */ PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, /** @@ -130,6 +189,14 @@ export const enum MessageType { * Deletable: true */ CHANNEL_FOLLOW_ADD = 12, + /** + * A message sent when a user starts a stream in a guild. + * + * Value: 13 + * Name: GUILD_STREAM + * Deletable: true + */ + GUILD_STREAM = 13, /** * A message sent when a guild is disqualified from discovery * @@ -301,6 +368,22 @@ export const enum MessageType { * Deletable: true */ GUILD_APPLICATION_PREMIUM_SUBSCRIPTION = 32, + /** + * A message sent when an integration is added to a private channel + * + * Value: 33 + * Name: PRIVATE_CHANNEL_INTEGRATION_ADDED + * Deletable: true + */ + PRIVATE_CHANNEL_INTEGRATION_ADDED = 33, + /** + * A message sent when an integration is removed from a private channel + * + * Value: 34 + * Name: PRIVATE_CHANNEL_INTEGRATION_REMOVED + * Deletable: true + */ + PRIVATE_CHANNEL_INTEGRATION_REMOVED = 34, /** * A message sent when a user gifts a premium (Nitro) referral * @@ -380,6 +463,14 @@ export const enum MessageType { * Deletable: true */ PURCHASE_NOTIFICATION = 44, + /** + * A message sent as a voice hangout invite + * + * Value: 45 + * Name: VOICE_HANGOUT_INVITE + * Deletable: true + */ + VOICE_HANGOUT_INVITE = 45, /** * A message sent when a poll is finalized * @@ -470,6 +561,22 @@ export const enum MessageType { * Deletable: true */ HD_STREAMING_UPGRADED = 55, + /** + * A message sent when a chat wallpaper is set + * + * Value: 56 + * Name: CHAT_WALLPAPER_SET + * Deletable: true + */ + CHAT_WALLPAPER_SET = 56, + /** + * A message sent when a chat wallpaper is removed + * + * Value: 57 + * Name: CHAT_WALLPAPER_REMOVED + * Deletable: true + */ + CHAT_WALLPAPER_REMOVED = 57, /** * A message sent when a user resolves a moderation report by deleting the offending message * @@ -524,6 +631,14 @@ export const enum MessageType { * Deletable: true */ EMOJI_ADDED = 63, + /** + * A message sent as a premium group invite + * + * Value: 64 + * Name: PREMIUM_GROUP_INVITE + * Deletable: true + */ + PREMIUM_GROUP_INVITE = 64, } export const enum MessageFlags { diff --git a/packages/discord-types/enums/misc.ts b/packages/discord-types/enums/misc.ts index 90b67d4388..60b2298a09 100644 --- a/packages/discord-types/enums/misc.ts +++ b/packages/discord-types/enums/misc.ts @@ -11,42 +11,7 @@ export const enum DraftType { Poll = 4, SlashCommand = 5, ForwardContextMessage = 6, -} - -export const enum GuildScheduledEventStatus { - SCHEDULED = 1, - ACTIVE = 2, - COMPLETED = 3, - CANCELED = 4, -} - -export const enum GuildScheduledEventEntityType { - STAGE_INSTANCE = 1, - VOICE = 2, - EXTERNAL = 3, -} - -export const enum GuildScheduledEventPrivacyLevel { - GUILD_ONLY = 2, -} - -export const enum ParticipantType { - STREAM = 0, - HIDDEN_STREAM = 1, - USER = 2, - ACTIVITY = 3, -} - -export const enum RTCPlatform { - DESKTOP = 0, - MOBILE = 1, - XBOX = 2, - PLAYSTATION = 3, -} - -export const enum VideoSourceType { - VIDEO = 0, - CAMERA_PREVIEW = 1, + InteractionModal = 7, } export const enum EmojiIntention { @@ -75,29 +40,15 @@ export const enum LoadState { ERROR = 3, } -export const enum ConnectionStatsFlags { - TRANSPORT = 1, - OUTBOUND = 2, - INBOUND = 4, - ALL = 7, +export const enum InviteTargetType { + STREAM = 1, + EMBEDDED_APPLICATION = 2, + ROLE_SUBSCRIPTIONS_PURCHASE = 3, } -export const enum SpeakingFlags { +export const enum PremiumType { NONE = 0, - VOICE = 1, - SOUNDSHARE = 2, - PRIORITY = 4, - HIDDEN = 8, -} - -export const enum GoLiveQualityMode { - AUTO = 1, - FULL = 2, -} - -export const enum VoiceProcessingStateReason { - CPU_OVERUSE = 1, - FAILED = 2, - VAD_CPU_OVERUSE = 3, - INITIALIZED = 4, + TIER_1 = 1, + TIER_2 = 2, + TIER_0 = 3, } diff --git a/packages/discord-types/enums/quests.ts b/packages/discord-types/enums/quests.ts new file mode 100644 index 0000000000..04915f6a6c --- /dev/null +++ b/packages/discord-types/enums/quests.ts @@ -0,0 +1,390 @@ +export const enum QuestRewardType { + REWARD_CODE = 1, + IN_GAME = 2, + COLLECTIBLE = 3, + VIRTUAL_CURRENCY = 4, + FRACTIONAL_PREMIUM = 5, +} + +export const enum QuestPlatform { + CROSS_PLATFORM = 0, + XBOX = 1, + PLAYSTATION = 2, + SWITCH = 3, + PC = 4, +} + +export const enum QuestTargetedContent { + GIFT_INVENTORY_SETTINGS_BADGE = 0, + QUEST_BAR = 1, + QUEST_INVENTORY_CARD = 2, + QUESTS_EMBED = 3, + ACTIVITY_PANEL = 4, + QUEST_LIVE_STREAM = 5, + MEMBERS_LIST = 6, + QUEST_BADGE = 7, + GIFT_INVENTORY_FOR_YOU = 8, + GIFT_INVENTORY_OTHER = 9, + QUEST_BAR_V2 = 10, + QUEST_HOME_DESKTOP = 11, + QUEST_HOME_MOBILE = 12, + QUEST_BAR_MOBILE = 13, + THIRD_PARTY_APP = 14, + QUEST_BOTTOM_SHEET = 15, + QUEST_EMBED_MOBILE = 16, + QUEST_HOME_MOVE_CALLOUT = 17, + DISCOVERY_SIDEBAR = 18, + QUEST_SHARE_LINK = 19, + CONNECTIONS_MODAL = 20, + DISCOVERY_COMPASS = 21, + TROPHY_CASE_CARD = 22, + VIDEO_MODAL = 23, + VIDEO_MODAL_END_CARD = 24, + REWARD_MODAL = 25, + EXCLUDED_QUEST_EMBED = 26, + VIDEO_MODAL_MOBILE = 27, + ORBS_ANNOUNCEMENT_MODAL = 28, + ORBS_BALANCE_MENU = 29, + QUEST_ENROLLMENT_BLOCKED_BOTTOM_SHEET = 30, + ORBS_SHOP_HERO_CTA = 31, + QUEST_ENROLLMENT_BLOCKED_MODAL = 32, + INTERNAL_PREVIEW_TOOL = 33, + ORBS_REHEAT_COACHMARK_CTA = 34, + INVALID_QUEST_EMBED = 35, + NOT_SHAREABLE_QUEST_EMBED = 36, + QUEST_HOME_MOVE_CALLOUT_DISCOVER = 37, + SPONSORED_QUEST_SHEET = 38, + MOBILE_ORBS_ONBOARDING_DC = 39, + RUNNING_ACTIVITY = 40, + VIDEO_MODAL_PRIMARY_CTA = 41, + QUEST_HOME_TAKEOVER = 42, + USER_PROFILE_ACTIVITY = 43, +} + +export const enum QuestPlacement { + INVALID_PLACEMENT = 0, + DESKTOP_ACCOUNT_PANEL_AREA = 1, + MOBILE_HOME_DOCK_AREA = 2, +} + +export const enum QuestRewardAssignmentMethod { + ALL = 1, + TIERED = 2, +} + +export const enum QuestRewardExpirationMode { + NORMAL = 1, + PREMIUM_EXTENSION = 2, + PREMIUM_PERMANENT = 3, +} + +export const enum QuestFeature { + POST_ENROLLMENT_CTA = 1, + QUEST_BAR_V2 = 3, + EXCLUDE_RUSSIA = 5, + IN_HOUSE_CONSOLE_QUEST = 6, + MOBILE_CONSOLE_QUEST = 7, + START_QUEST_CTA = 8, + REWARD_HIGHLIGHTING = 9, + FRACTIONS_QUEST = 10, + ADDITIONAL_REDEMPTION_INSTRUCTIONS = 11, + PACING_V2 = 12, + DISMISSAL_SURVEY = 13, + MOBILE_QUEST_DOCK = 14, + QUESTS_CDN = 15, + PACING_CONTROLLER = 16, + QUEST_HOME_FORCE_STATIC_IMAGE = 17, + VIDEO_QUEST_FORCE_HLS_VIDEO = 18, + VIDEO_QUEST_FORCE_END_CARD_CTA_SWAP = 19, + EXPERIMENTAL_TARGETING_TRAITS = 20, + DO_NOT_DISPLAY = 21, + EXTERNAL_DIALOG = 22, + MOBILE_ONLY_QUEST_PUSH_TO_MOBILE = 23, + MANUAL_HEARTBEAT_INITIALIZATION = 24, + CLOUD_GAMING_ACTIVITY = 25, + NON_GAMING_PLAY_QUEST = 26, + ACTIVITY_QUEST_AUTO_ENROLLMENT = 27, + PACKAGE_ACTION_ADVENTURE = 28, + PACKAGE_RPG_MMO = 29, + PACKAGE_RACING_SPORTS = 30, + PACKAGE_SANDBOX_CREATIVE = 31, + PACKAGE_FAMILY_FRIENDLY = 32, + PACKAGE_HOLIDAY_SEASON = 33, + PACKAGE_NEW_YEARS = 34, +} + +export const enum QuestDismissibleContentFlags { + GIFT_INVENTORY_SETTINGS_BADGE = 1, + QUEST_BAR = 2, + ACTIVITY_PANEL = 4, + QUEST_LIVE_STREAM = 8, +} + +export const enum QuestUserQuestStatus { + UNACCEPTED = 0, + ACCEPTED = 1, + IN_PROGRESS = 2, + COMPLETED = 3, + CLAIMED = 4, +} + +/** Task types for quest completion requirements. */ +export const enum QuestTaskType { + STREAM_ON_DESKTOP = "STREAM_ON_DESKTOP", + PLAY_ON_DESKTOP = "PLAY_ON_DESKTOP", + PLAY_ON_XBOX = "PLAY_ON_XBOX", + PLAY_ON_PLAYSTATION = "PLAY_ON_PLAYSTATION", + PLAY_ON_DESKTOP_V2 = "PLAY_ON_DESKTOP_V2", + WATCH_VIDEO = "WATCH_VIDEO", + WATCH_VIDEO_ON_MOBILE = "WATCH_VIDEO_ON_MOBILE", + PLAY_ACTIVITY = "PLAY_ACTIVITY", + ACHIEVEMENT_IN_GAME = "ACHIEVEMENT_IN_GAME", + ACHIEVEMENT_IN_ACTIVITY = "ACHIEVEMENT_IN_ACTIVITY", +} + +/** Operator for combining multiple quest tasks. */ +export const enum QuestTaskJoinOperator { + /** All tasks must be completed. */ + AND = "and", + /** Any one task must be completed. */ + OR = "or", +} + +/** Error types returned from quest API operations. */ +export const enum QuestErrorType { + GENERIC = "generic", + RATE_LIMITED = "rate_limited", +} + +/** Platform mode for quest task selection. */ +export const enum QuestPlatformMode { + DESKTOP = "desktop", + CONSOLE = "console", + /** User must select a platform. */ + SELECT = "select", +} + +/** Reasons for pausing quest video playback. */ +export const enum QuestVideoPauseReason { + PAUSE_BUTTON = "PAUSE_BUTTON", + LOST_FOCUS = "LOST_FOCUS", + MODAL_CLOSED = "MODAL_CLOSED", +} + +/** Placement types for quest home takeover. */ +export const enum QuestHomePlacement { + QUEST_HOME_BANNER = "quest_home_banner", +} + +/** Client platforms for quest targeting. */ +export const enum QuestClientPlatform { + IOS = "ios", + ANDROID = "android", + DESKTOP = "desktop", + WEB = "web", + WEB_MOBILE = "web_mobile", + WEB_TABLET = "web_tablet", +} + +/** Quest sharing policy. */ +export const enum QuestSharePolicy { + SHAREABLE_EVERYWHERE = "shareable_everywhere", + NOT_SHAREABLE = "not_shareable", +} + +/** Quest bar UI states. */ +export const enum QuestBarState { + COLLAPSED = "collapsed", + EXPANDED = "expanded", + CLOSED = "closed", + SOFT_DISMISSED = "soft-dismissed", + RESET_TO_PREVIOUS = "reset-to-previous", +} + +/** Reasons for quest embed fallback display. */ +export const enum QuestEmbedFallbackReason { + EXCLUDED_QUEST = "excluded_quest", + UNKNOWN_QUEST = "unknown_quest", + NOT_SHAREABLE_QUEST = "not_shareable_quest", +} + +/** Console platform selection for quest tasks. */ +export const enum QuestConsolePlatformSelection { + CONSOLE = "CONSOLE", + DESKTOP = "DESKTOP", +} + +/** Call-to-action types for quest UI interactions. */ +export const enum QuestContentCTA { + LEARN_MORE = "LEARN_MORE", + SHOW_REWARD = "SHOW_REWARD", + CLAIM_REWARD = "CLAIM_REWARD", + GET_REWARD_CODE = "GET_REWARD_CODE", + COPY_REWARD_CODE = "COPY_REWARD_CODE", + ACCEPT_QUEST = "ACCEPT_QUEST", + COPY_QUEST_URL = "COPY_QUEST_URL", + MOBILE_SHARESHEET = "MOBILE_SHARESHEET", + TRACK_PROGRESS = "TRACK_PROGRESS", + CONNECT_CONSOLE = "CONNECT_CONSOLE", + CONNECT_CONSOLE_LINK = "CONNECT_CONSOLE_LINK", + VIEW_CONSOLE_CONNECTIONS = "VIEW_CONSOLE_CONNECTION", + VIEW_CONSOLE_CONNECTIONS_LINK = "VIEW_CONSOLE_CONNECTIONS_LINK", + VIEW_REQUIREMENTS = "VIEW_REQUIREMENTS", + SELECT_CONSOLE_PLATFORM = "SELECT_CONSOLE_PLATFORM", + SELECT_DESKTOP_PLATFORM = "SELECT_DESKTOP_PLATFORM", + DESELECT_PLATFORM = "DESELECT_PLATFORM", + DEFIBRILLATOR = "DEFIBRILLATOR", + DEFIBRILLATOR_RECONNECT_CONSOLE = "DEFIBRILLATOR_RECONNECT_CONSOLE", + OPEN_DISCLOSURE = "OPEN_DISCLOSURE", + WATCH_STREAM = "WATCH_STREAM", + WATCH_STREAM_CONFIRM = "WATCH_STREAM_CONFIRM", + REWARD_LEARN_MORE = "REWARD_LEARN_MORE", + OPEN_GAME_LINK = "OPEN_GAME_LINK", + OPEN_CONTEXT_MENU = "OPEN_CONTEXT_MENU", + OPEN_QUEST_HOME = "OPEN_QUEST_HOME", + QUEST_BAR_COPY_LINK = "QUEST_BAR.COPY_LINK", + CONTEXT_MENU_COPY_LINK = "CONTEXT_MENU.COPY_LINK", + REWARD_MODAL_COPY_LINK = "REWARD_MODAL.COPY_LINK", + CONTEXT_MENU_HIDE_CONTENT = "CONTEXT_MENU.HIDE_CONTENT", + CONTEXT_MENU_OPEN_GAME_LINK = "CONTEXT_MENU.OPEN_GAME_LINK", + CONTEXT_MENU_OPEN_DISCLOSURE = "CONTEXT_MENU.OPEN_DISCLOSURE", + CONTEXT_MENU_LEARN_MORE = "CONTEXT_MENU.LEARN_MORE", + HOW_TO_HELP_ARTICLE_XBOX = "HOW_TO_HELP_ARTICLE_XBOX", + HOW_TO_HELP_ARTICLE_PLAYSTATION = "HOW_TO_HELP_ARTICLE_PLAYSTATION", + VIEW_QUESTS = "VIEW_QUESTS", + EXPAND = "EXPAND", + COLLAPSE = "COLLAPSE", + START_QUEST = "START_QUEST", + TRANSCRIPT_ENABLE = "TRANSCRIPT_ENABLE", + TRANSCRIPT_DISABLE = "TRANSCRIPT_DISABLE", + CLOSED_CAPTIONING_ENABLE = "CLOSED_CAPTIONING_ENABLE", + CLOSED_CAPTIONING_DISABLE = "CLOSED_CAPTIONING_DISABLE", + SEEK_BACKWARD = "SEEK_BACKWARD", + SEEK_FORWARD = "SEEK_FORWARD", + WATCH_VIDEO = "WATCH_VIDEO", + QUEST_BAR_VIDEO_QUEST_PREVIEW = "QUEST_BAR_VIDEO_QUEST_PREVIEW", + QUEST_HOME_TILE_HEADER_WATCH_VIDEO = "QUEST_HOME_TILE_HEADER_WATCH_VIDEO", + REDEEM_REWARD = "REDEEM_REWARD", + VISIT_REDEMPTION_LINK = "VISIT_REDEMPTION_LINK", + SPONSORED_QUEST_SHEET = "SPONSORED_QUEST_SHEET", + GAME_PROFILE_OPEN = "GAME_PROFILE_OPEN", + GAME_STORE_OPEN_GAME_LINK = "GAME_STORE_OPEN_GAME_LINK", + MOBILE_ORBS_ONBOARDING_DC = "MOBILE_ORBS_ONBOARDING_DC", +} + +/** Sort methods for quest list display. */ +export const enum QuestSortMethod { + /** Default sorting by relevance. */ + SUGGESTED = "suggested", + MOST_RECENT = "most_recent", + EXPIRING_SOON = "expiring_soon", + RECENTLY_ENROLLED = "recently_enrolled", +} + +/** Filter types for quest tasks. */ +export const enum QuestTaskFilter { + VIDEO = "task_video", + PLAY = "task_play", +} + +/** Filter types for quest rewards. */ +export const enum QuestRewardFilter { + VIRTUAL_CURRENCY = "reward_virtual_currency", + COLLECTIBLE = "reward_collectible", + IN_GAME = "reward_in_game", +} + +/** Video playback progress states. */ +export const enum QuestVideoProgressState { + UNKNOWN = "UNKNOWN", + NOT_STARTED = "NOT_STARTED", + IN_PROGRESS = "IN_PROGRESS", + COMPLETED = "COMPLETED", +} + +/** Transcript fetch operation states. */ +export const enum QuestTranscriptFetchStatus { + NONE = "NONE", + FETCHING = "FETCHING", + SUCCESS = "SUCCESS", + FAILURE = "FAILURE", +} + +/** Result types from quest enrollment attempts. */ +export const enum QuestEnrollmentResult { + SUCCESS = "success", + CAPTCHA_FAILED = "captcha_failed", + UNKNOWN_ERROR = "unknown_error", + /** Enrollment already in progress. */ + PREVIOUS_IN_FLIGHT_REQUEST = "previous_in_flight_request", +} + +/** Reasons why a quest embed was not found. */ +export const enum QuestEmbedNotFoundReason { + NOT_FOUND = "not_found", + MOBILE_ONLY = "mobile_only", +} + +/** Tab filter types for quest list. */ +export const enum QuestFilterTab { + ALL = "all", + CLAIMED = "claimed", + /** Internal preview tool only. */ + PREVIEW_TOOL = "preview_tool", +} + +/** URL parameter types for quest filtering. */ +export const enum QuestFilterParamType { + TAB = "tab", + QUEST_ID = "quest_id", + SORT = "sort", + FILTER = "filter", +} + +/** Location identifiers for quest-related UI and tracking. */ +export const enum QuestLocation { + ACTIVITY_PANEL = "quests_bar_activity_panel", + QUESTS_MANAGER = "quests_manager", + QUESTS_CONSOLE_OPTIMISTIC_UPDATES_MANAGER = "quests_console_optimistic_updates_manager", + USER_SETTINGS_GIFT_INVENTORY = "user_settings_gift_inventory", + USER_SETTINGS_SEARCH_GIFT_INVENTORY = "user_settings_search_gift_inventory", + USE_QUESTS = "use_quests", + STREAM_SOURCE_SELECT = "stream_source_select", + MEMBERS_LIST = "members_list", + QUESTS_BAR = "quests_bar", + QUESTS_BAR_MOBILE = "quests_bar_mobile", + REWARD_CODE_MODAL = "reward_code_modal", + INGAME_REWARD_MODAL = "ingame_reward_modal", + COLLECTIBLE_REWARD_MODAL = "collectible_reward_modal", + ORBS_REWARD_MODAL = "orbs_reward_modal", + QUEST_PREVIEW_TOOL = "quest_preview_tool", + QUEST_PREVIEW_TOOL_2 = "quest_preview_tool_2", + QUESTS_MINOR_REWARD_CAPPING_CONFIG = "QUESTS_MINOR_REWARD_CAPPING_CONFIG", + QUESTS_CARD = "quests_card", + QUESTS_STORE = "quests_store", + QUEST_CHANNEL_CALL_HEADER = "quests_channel_call_header", + QUEST_HOME_DESKTOP = "quest_home_desktop", + QUEST_HOME_MOBILE = "quest_home_mobile", + QUEST_PROGRESS_BAR = "quest_progress_bar", + EMBED_MOBILE = "embed_mobile", + EMBED_DESKTOP = "embed_desktop", + QUEST_CONTEXT_MENU = "context_menu", + CODED_LINK = "coded_link", + QUEST_DISCLOSURE_MODAL = "quest_disclosure_modal", + DISCOVERY_SIDEBAR = "discovery_sidebar", + DISCOVERY_COMPASS = "discovery_compass", + BADGE = "badge", + COLLECTIBLES_SHOP_HEADER_BAR = "collectibles_shop_header_bar", + ORBS_ANNOUNCEMENT_MODAL = "orbs_announcement_modal", + CONFLICT_CHECKS = "conflict_checks", + VIDEO_MODAL = "video_modal", + VIDEO_MODAL_MOBILE = "video_modal_mobile", + GAME_WIDGETS_POPOVER = "game_widgets_popover", + PRIVATE_CHANNELS_LIST = "private_channels_list", + INTERNAL_TOOLING = "internal_tooling", + QUEST_HOME_MOVED_CALLOUT = "quest_home_moved_callout", + IN_APP_NAVIGATION = "in_app_navigation", + NAVIGATE_TO_QUEST_HOME_UTIL = "navigate_to_quest_home_util", + QUEST_DEEP_LINK_UTIL = "quest_deep_link_util", + YOU_TAB_PROFILE_HEADER = "you_tab_profile_header", +} diff --git a/packages/discord-types/enums/settings.ts b/packages/discord-types/enums/settings.ts new file mode 100644 index 0000000000..8e3d9769e2 --- /dev/null +++ b/packages/discord-types/enums/settings.ts @@ -0,0 +1,42 @@ +export const enum Theme { + UNSET = 0, + DARK = 1, + LIGHT = 2, + DARKER = 3, + MIDNIGHT = 4, +} + +export const enum UIDensity { + UNSET = 0, + COMPACT = 1, + COZY = 2, + RESPONSIVE = 3, + DEFAULT = 4, +} + +export const enum StickerAnimationSetting { + ALWAYS = 0, + ON_INTERACTION = 1, + NEVER = 2, +} + +export const enum UserNotificationSetting { + ALL_MESSAGES = 0, + ONLY_MENTIONS = 1, + NO_MESSAGES = 2, +} + +export const enum ChannelOverrideFlags { + UNREADS_ONLY_MENTIONS = 512, + UNREADS_ALL_MESSAGES = 1024, + FAVORITED = 2048, + OPT_IN_ENABLED = 4096, + NEW_FORUM_THREADS_OFF = 8192, + NEW_FORUM_THREADS_ON = 16384, +} + +export const enum NotifyHighlights { + NULL = 0, + DISABLED = 1, + ENABLED = 2, +} diff --git a/packages/discord-types/enums/user.ts b/packages/discord-types/enums/user.ts index 171fe5e8c8..0ad2ec6d61 100644 --- a/packages/discord-types/enums/user.ts +++ b/packages/discord-types/enums/user.ts @@ -2,10 +2,16 @@ export const enum RelationshipType { NONE = 0, FRIEND = 1, BLOCKED = 2, + /** + * @remarks Discord API calls this PENDING_INCOMING + */ INCOMING_REQUEST = 3, + /** + * @remarks Discord API calls this PENDING_OUTGOING + */ OUTGOING_REQUEST = 4, IMPLICIT = 5, - SUGGESTION = 6 + SUGGESTION = 6, } export enum GiftIntentType { @@ -20,3 +26,36 @@ export const enum ReadStateType { GUILD_ONBOARDING_QUESTION = 4, MESSAGE_REQUESTS = 5, } + +export const enum UserFlags { + STAFF = 1, + PARTNER = 2, + HYPESQUAD = 4, + BUG_HUNTER_LEVEL_1 = 8, + MFA_SMS = 16, + PREMIUM_PROMO_DISMISSED = 32, + HYPESQUAD_ONLINE_HOUSE_1 = 64, + HYPESQUAD_ONLINE_HOUSE_2 = 128, + HYPESQUAD_ONLINE_HOUSE_3 = 256, + PREMIUM_EARLY_SUPPORTER = 512, + HAS_UNREAD_URGENT_MESSAGES = 8192, + BUG_HUNTER_LEVEL_2 = 16384, + VERIFIED_BOT = 65536, + VERIFIED_DEVELOPER = 131072, + CERTIFIED_MODERATOR = 262144, + BOT_HTTP_INTERACTIONS = 524288, + SPAMMER = 1048576, + DISABLE_PREMIUM = 2097152, + PROVISIONAL_ACCOUNT = 8388608, + QUARANTINED = 17592186044416, + COLLABORATOR = 1125899906842624, + RESTRICTED_COLLABORATOR = 2251799813685248, +} + +export const enum StandingState { + ALL_GOOD = 100, + LIMITED = 200, + VERY_LIMITED = 300, + AT_RISK = 400, + SUSPENDED = 500, +} diff --git a/packages/discord-types/enums/voice.ts b/packages/discord-types/enums/voice.ts new file mode 100644 index 0000000000..724066cc81 --- /dev/null +++ b/packages/discord-types/enums/voice.ts @@ -0,0 +1,50 @@ +export const enum ParticipantType { + STREAM = 0, + HIDDEN_STREAM = 1, + USER = 2, + ACTIVITY = 3, +} + +export const enum RTCPlatform { + DESKTOP = 0, + MOBILE = 1, + XBOX = 2, + PLAYSTATION = 3, +} + +export const enum VideoSourceType { + VIDEO = 0, + CAMERA_PREVIEW = 1, +} + +export const enum ConnectionStatsFlags { + TRANSPORT = 1, + OUTBOUND = 2, + INBOUND = 4, + ALL = 7, +} + +export const enum SpeakingFlags { + NONE = 0, + VOICE = 1, + SOUNDSHARE = 2, + PRIORITY = 4, + HIDDEN = 8, +} + +export const enum GoLiveQualityMode { + AUTO = 1, + FULL = 2, +} + +export const enum VoiceProcessingStateReason { + CPU_OVERUSE = 1, + FAILED = 2, + VAD_CPU_OVERUSE = 3, + INITIALIZED = 4, +} + +export const enum VideoQualityMode { + AUTO = 1, + FULL = 2, +} diff --git a/packages/discord-types/src/common/Activity.d.ts b/packages/discord-types/src/common/Activity.d.ts index 5f7b903760..03426a3964 100644 --- a/packages/discord-types/src/common/Activity.d.ts +++ b/packages/discord-types/src/common/Activity.d.ts @@ -1,5 +1,7 @@ import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "../../enums"; +export type ActivityPlatform = "desktop" | "mobile" | "web" | "embedded" | "xbox" | "playstation" | "samsung" | "ios" | "android"; + export interface ActivityAssets { large_image?: string; large_text?: string; @@ -15,9 +17,18 @@ export interface ActivityButton { } export interface Activity { + created_at?: number; + id?: string; name: string; - application_id: string; + application_id?: string; type: ActivityType; + session_id?: string; + sync_id?: string; + emoji?: { + animated: boolean; + id: string; + name: string; + }; state?: string; state_url?: string; details?: string; @@ -34,6 +45,7 @@ export interface Activity { metadata?: { button_urls?: Array; }; + platform?: ActivityPlatform; party?: { id?: string; size?: [number, number]; diff --git a/packages/discord-types/src/common/Application.d.ts b/packages/discord-types/src/common/Application.d.ts index e59925d96a..cd2696e12d 100644 --- a/packages/discord-types/src/common/Application.d.ts +++ b/packages/discord-types/src/common/Application.d.ts @@ -1,6 +1,36 @@ +import { ActivityLabelType, ApplicationFlags, ApplicationType, CarouselItemType, LinkedGameType, OrientationLockState } from "../../enums"; import { Guild } from "./Guild"; import { User } from "./User"; +export type EmbeddedActivityPlatform = "ios" | "android" | "web"; + +export interface EmbeddedActivityPlatformConfig { + label_type: ActivityLabelType; + label_from: string | null; + label_until: string | null; + release_phase: string; + omit_badge_from_surfaces: string[]; +} + +export interface EmbeddedActivityConfig { + application_id: string; + activity_preview_video_asset_id: string | null; + supported_platforms: EmbeddedActivityPlatform[]; + default_orientation_lock_state: OrientationLockState; + tablet_default_orientation_lock_state: OrientationLockState; + requires_age_gate: boolean; + legacy_responsive_aspect_ratio: boolean; + premium_tier_requirement: number | null; + free_period_starts_at: string | null; + free_period_ends_at: string | null; + client_platform_config: Partial>; + shelf_rank: number; + has_csp_exception: boolean; + displays_advertisements: boolean; + blocked_locales: string[]; + supported_locales: string[]; +} + export interface ApplicationExecutable { os: "win32" | "darwin" | "linux"; name: string; @@ -23,12 +53,23 @@ export interface ApplicationInstallParams { scopes: string[]; } +export interface ApplicationIntegrationTypeConfig { + oauth2InstallParams: ApplicationInstallParams; +} + +export interface ApplicationDirectoryEntry { + guild_count?: number; + detailed_description?: string; + supported_locales?: string[]; + carousel_items?: { asset_id: string; type: CarouselItemType; }[]; +} + export interface Application { id: string; name: string; icon: string | null; description: string; - type: number | null; + type: ApplicationType | null; coverImage: string | null; primarySkuId: string | undefined; bot: User | null; @@ -54,24 +95,30 @@ export interface Application { hashes: string[]; eulaId: string | undefined; slug: string | undefined; - flags: number; - maxParticipants: number | undefined; + flags: ApplicationFlags; + maxParticipants: number | null; tags: string[]; - embeddedActivityConfig: Record | undefined; + embeddedActivityConfig: EmbeddedActivityConfig | undefined; team: ApplicationTeam | undefined; - integrationTypesConfig: Record>; + integrationTypesConfig: Record; storefront_available: boolean; termsOfServiceUrl: string | undefined; privacyPolicyUrl: string | undefined; isDiscoverable: boolean; customInstallUrl: string | undefined; installParams: ApplicationInstallParams | undefined; - directoryEntry: Record | undefined; + directoryEntry: ApplicationDirectoryEntry | undefined; categories: string[] | undefined; - linkedGames: string[] | undefined; + linkedGames: ApplicationLinkedGame[] | undefined; deepLinkUri: string | undefined; } +export interface ApplicationLinkedGame { + id: string; + type: LinkedGameType; + application?: Application; +} + export interface ApplicationTeam { id: string; name: string; diff --git a/packages/discord-types/src/common/Channel.d.ts b/packages/discord-types/src/common/Channel.d.ts index 7ad5ce5358..21f2dc10e9 100644 --- a/packages/discord-types/src/common/Channel.d.ts +++ b/packages/discord-types/src/common/Channel.d.ts @@ -1,83 +1,369 @@ +import { ChannelFlags, ChannelType, ForumLayout, PermissionOverwriteType, SafetyWarningType, UserFlags, VideoQualityMode } from "../../enums"; import { DiscordRecord } from "./Record"; +/** Permission overwrite for a role or member. */ +export interface PermissionOverwrite { + id: string; + /** 0 = role, 1 = member. */ + type: PermissionOverwriteType; + deny: bigint; + allow: bigint; +} + +/** Avatar decoration data for user profiles. */ +export interface AvatarDecorationData { + asset: string; + expires_at: string | null; + skuId: string; +} + +/** Clan identity information. */ +export interface ClanData { + badge: string; + tag: string; + identityEnabled: boolean; + identityGuildId: string; +} + +/** Display name style configuration. */ +export interface DisplayNameStyles { + colors: number[]; + effect_id: number; + font_id: number; +} + +/** Collectible item data. */ +export interface CollectibleItem { + asset: string; + expires_at: string | null; + label: string; + palette: string; + type: number; + skuId: string; +} + +/** User collectibles configuration. */ +export interface Collectibles { + nameplate?: CollectibleItem; +} + +/** Raw recipient data from API. */ +export interface RawRecipient { + id: string; + avatar: string | null; + avatar_decoration_data: AvatarDecorationData | null; + bot: boolean; + clan: ClanData | null; + collectibles: Collectibles | null; + discriminator: string; + display_name: string | null; + display_name_styles: DisplayNameStyles | null; + global_name: string | null; + primary_guild: ClanData | null; + public_flags: UserFlags; + username: string; +} + +/** Thread metadata for thread channels. */ +export interface ThreadMetadata { + archived: boolean; + autoArchiveDuration: number; + archiveTimestamp: string | undefined; + createTimestamp: string | undefined; + locked: boolean; + invitable: boolean; +} + +/** Icon emoji for channels that support it. */ +export interface ChannelIconEmoji { + id: string | null; + name: string; +} + +/** Thread member info, present when user has joined a thread. */ +export interface ThreadMember { + flags: number; + joinTimestamp: string; + muted: boolean; + muteConfig: { + end_time: string | null; + selected_time_window: number; + } | null; +} + +/** Available tag for forum/media channels. */ +export interface ForumTag { + id: string; + name: string; + emojiId: string | null; + emojiName: string | null; + moderated: boolean; + color: number | null; +} + +/** Default reaction emoji for forum/media channels. */ +export interface DefaultReactionEmoji { + emojiId: string | null; + emojiName: string; +} + +/** Linked lobby for voice channels. */ +export interface LinkedLobby { + application_id: string; + lobby_id: string; + linked_by: string; + linked_at: string; + require_application_authorization: boolean; +} + +/** Safety warning for DM spam detection. */ +export interface SafetyWarning { + id: string; + type: SafetyWarningType; + expiry: string; + dismiss_timestamp: string | null; +} + +/** Sort order for forum/media channels. */ +export type ForumSortOrder = 0 | 1; + +/** Tag setting for forum/media channels. */ +export type ForumTagSetting = "match_all" | "match_some"; + +/** Discord channel object. */ export class Channel extends DiscordRecord { constructor(channel: object); - application_id: number | undefined; - bitrate: number; + + /** Application ID for bot-created channels. */ + application_id: string | undefined; + /** Applied tag IDs. Threads in forum/media channels only. */ + appliedTags: string[] | undefined; + /** Available tags for forum/media channels. */ + availableTags: ForumTag[] | undefined; + /** Internal, use bitrate getter. Voice channels only. */ + bitrate_: number | undefined; + /** Whether blocked user warning was dismissed. */ + blockedUserWarningDismissed: boolean | undefined; + /** Default auto-archive duration for threads in minutes. Guild text channels only. */ defaultAutoArchiveDuration: number | undefined; - flags: number; + /** Default layout for forum/media channels. */ + defaultForumLayout: ForumLayout | undefined; + /** Default reaction emoji for forum/media channels. */ + defaultReactionEmoji: DefaultReactionEmoji | undefined; + /** Default sort order for forum/media channels. */ + defaultSortOrder: ForumSortOrder | undefined; + /** Default tag setting for forum/media channels. */ + defaultTagSetting: ForumTagSetting | undefined; + /** Default slowmode for new threads. Guild text channels only. */ + defaultThreadRateLimitPerUser: number | undefined; + /** Internal, use flags getter. */ + flags_: ChannelFlags; + /** Guild ID. */ guild_id: string; - icon: string; + /** User ID who purchased HD streaming. */ + hdStreamingBuyerId: string | undefined; + /** HD streaming end timestamp. */ + hdStreamingUntil: string | undefined; + /** Icon hash for group DMs. */ + icon: string | undefined; + /** Icon emoji for channels that support it. */ + iconEmoji: ChannelIconEmoji | undefined; + /** Channel snowflake ID. */ id: string; - lastMessageId: string; + /** For DMs, whether this is a message request. */ + isMessageRequest: boolean; + /** Timestamp when message request was created. */ + isMessageRequestTimestamp: string | null; + /** Whether the DM is flagged as spam. */ + isSpam: boolean; + /** ID of the last message in the channel. */ + lastMessageId: string | null; + /** ISO timestamp of the last pinned message. */ lastPinTimestamp: string | undefined; - member: unknown; + /** Linked lobby for voice channels. */ + linkedLobby: LinkedLobby | null; + /** Thread member info if user joined thread. Threads only. */ + member: ThreadMember | undefined; + /** Approximate member count. Threads only. */ memberCount: number | undefined; + /** Preview of member IDs in the thread. Threads only. */ memberIdsPreview: string[] | undefined; - memberListId: unknown; + /** Member list ID for guild channels. */ + memberListId: string | undefined; + /** Approximate message count. Threads only. */ messageCount: number | undefined; + /** Channel name. */ name: string; - nicks: Record; - nsfw: boolean; - originChannelId: unknown; - ownerId: string; + /** Custom nicknames in group DMs, keyed by user ID. */ + nicks: Record; + /** Internal, use nsfw getter. Guild channels only. */ + nsfw_: boolean; + /** Origin channel ID for crossposted messages. */ + originChannelId: string | undefined; + /** Owner ID for group DMs and threads. */ + ownerId: string | undefined; + /** Parent category or channel ID. */ parent_id: string; - permissionOverwrites: { - [role: string]: { - id: string; - type: number; - deny: bigint; - allow: bigint; - }; - }; - position: number; - rateLimitPerUser: number; - rawRecipients: { - id: string; - avatar: string; - username: string; - public_flags: number; - discriminator: string; - }[]; + /** Parent channel type for threads. */ + parentChannelThreadType: ChannelType | undefined; + /** Internal, use permissionOverwrites getter. Guild channels only. */ + permissionOverwrites_: Record; + /** Internal, use position getter. Guild channels only. */ + position_: number; + /** Internal, use rateLimitPerUser getter. */ + rateLimitPerUser_: number; + /** Raw recipient data from API. DMs and group DMs. */ + rawRecipients: RawRecipient[]; + /** Recipient flags for DMs. */ + recipientFlags: number; + /** Recipient user IDs. DMs and group DMs. */ recipients: string[]; - rtcRegion: string; - threadMetadata: { - locked: boolean; - archived: boolean; - invitable: boolean; - createTimestamp: string | undefined; - autoArchiveDuration: number; - archiveTimestamp: string | undefined; - }; - topic: string; - type: number; - userLimit: number; - videoQualityMode: undefined; + /** RTC region for voice channels, null for automatic. Voice channels only. */ + rtcRegion: string | null; + /** Safety warnings for DM spam detection. */ + safetyWarnings: SafetyWarning[]; + /** Template string. */ + template: string | undefined; + /** Theme color for group DMs. */ + themeColor: number | undefined; + /** Thread metadata. Threads only. */ + threadMetadata: ThreadMetadata | undefined; + /** Internal, use topic getter. */ + topic_: string | null; + /** Total messages sent in thread. Threads only. */ + totalMessageSent: number | undefined; + /** Channel type from ChannelType enum. */ + type: ChannelType; + /** Internal, use userLimit getter. Voice channels only. */ + userLimit_: number | undefined; + /** Channel version number. */ + version: number | undefined; + /** Video quality mode for voice channels. Voice channels only. */ + videoQualityMode: VideoQualityMode | undefined; + /** Computed access permissions for the current user. */ get accessPermissions(): bigint; - get lastActiveTimestamp(): number; + /** Bitrate in bits per second. Voice channels only. */ + get bitrate(): number; + /** Channel flags bitmask. */ + get flags(): ChannelFlags; + /** Whether HD streaming splash is active. */ + get isHDStreamSplashed(): boolean; + /** Whether the channel is marked as NSFW. */ + get nsfw(): boolean; + /** Permission overwrites keyed by role or user ID. */ + get permissionOverwrites(): Record; + /** Channel position in the channel list. */ + get position(): number; + /** Slowmode delay in seconds. */ + get rateLimitPerUser(): number; + /** Channel topic or description. */ + get topic(): string; + /** Maximum users allowed in voice channel. 0 = unlimited. */ + get userLimit(): number; - computeLurkerPermissionsAllowList(): unknown; - getApplicationId(): unknown; + /** Computes allowed permissions for lurkers. */ + computeLurkerPermissionsAllowList(): bigint | undefined; + /** Gets the application ID for bot-created channels. */ + getApplicationId(): string | undefined; + /** Gets the default layout for forum channels. */ + getDefaultLayout(): ForumLayout; + /** Gets the default sort order for forum channels. */ + getDefaultSortOrder(): ForumSortOrder; + /** Gets the default tag setting for forum channels. */ + getDefaultTagSetting(): ForumTagSetting; + /** Gets the guild ID this channel belongs to. */ getGuildId(): string; - getRecipientId(): unknown; + /** Gets the recipient user ID for DMs. */ + getRecipientId(): string | undefined; + /** Checks if the channel has a specific flag. */ hasFlag(flag: number): boolean; + /** Returns a new Channel with the given properties merged. */ + merge(props: Record): this; + /** Returns a new Channel with the given property set. */ + set(key: string, value: unknown): this; + /** Converts the channel to a plain JavaScript object. */ + toJS(): Record; + /** Whether this is an active (non-archived) thread. */ isActiveThread(): boolean; + /** Whether this is an announcement thread. */ + isAnnouncementThread(): boolean; + /** Whether this is an archived and locked thread. */ + isArchivedLockedThread(): boolean; + /** Whether this is an archived thread. */ isArchivedThread(): boolean; + /** Whether this is a category channel. */ isCategory(): boolean; + /** Whether this is a DM channel. */ isDM(): boolean; + /** Whether this is a directory channel. */ isDirectory(): boolean; + /** Whether this is a forum channel. */ isForumChannel(): boolean; + /** Whether this is a forum-like channel (forum or media). */ + isForumLikeChannel(): boolean; + /** Whether this is a forum post thread. */ + isForumPost(): boolean; + /** Whether this is a group DM. */ isGroupDM(): boolean; + /** Whether this is a stage voice channel. */ isGuildStageVoice(): boolean; + /** Whether this is a guild voice or stage channel. */ + isGuildVocal(): boolean; + /** Whether this is a guild vocal channel or vocal thread. */ + isGuildVocalOrThread(): boolean; + /** Whether this is a guild voice channel. */ isGuildVoice(): boolean; + /** Whether this is a guild voice channel or voice thread. */ + isGuildVoiceOrThread(): boolean; + /** Whether this channel supports listen mode. */ isListenModeCapable(): boolean; + /** Whether this is a locked thread. */ + isLockedThread(): boolean; + /** Whether this channel is managed by an integration. */ isManaged(): boolean; + /** Whether this is a media channel. */ + isMediaChannel(): boolean; + /** Whether this is a media post thread. */ + isMediaPost(): boolean; + /** Whether this is a moderator report channel. */ + isModeratorReportChannel(): boolean; + /** Whether this is a multi-user DM (group DM). */ isMultiUserDM(): boolean; + /** Whether the channel is marked as NSFW. */ isNSFW(): boolean; - isOwner(): boolean; + /** + * Checks if the given user is the channel owner. + * @param userId User ID to check. + */ + isOwner(userId: string): boolean; + /** Whether this is a private channel (DM or group DM). */ isPrivate(): boolean; + /** Whether this channel supports ringing. */ + isRingable(): boolean; + /** Whether this is a role subscription template preview channel. */ + isRoleSubscriptionTemplatePreviewChannel(): boolean; + /** Whether this channel is scheduled for deletion. */ + isScheduledForDeletion(): boolean; + /** Whether this is a system DM (from Discord). */ isSystemDM(): boolean; + /** Whether this is any type of thread. */ isThread(): boolean; + /** Whether this channel supports voice. */ isVocal(): boolean; + /** Whether this is a vocal thread. */ + isVocalThread(): boolean; + + /** + * Adds a recipient to a group DM. + * @param userId User ID to add. + * @param nick Optional nickname for the user. + * @param currentUserId Current user's ID. + */ + addRecipient(userId: string, nick?: string | null, currentUserId?: string): this; + /** + * Removes a recipient from a group DM. + * @param userId User ID to remove. + */ + removeRecipient(userId: string): this; } diff --git a/packages/discord-types/src/common/Guild.d.ts b/packages/discord-types/src/common/Guild.d.ts index 65e973ffe7..79965d1871 100644 --- a/packages/discord-types/src/common/Guild.d.ts +++ b/packages/discord-types/src/common/Guild.d.ts @@ -1,9 +1,18 @@ -import { Role } from './Role'; import { DiscordRecord } from './Record'; +import { + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildMFALevel, + GuildNSFWLevel, + GuildPremiumTier, + GuildVerificationLevel, + PermissionOverwriteType, + SystemChannelFlags, +} from "../../enums"; // copy(Object.keys(findByProps("CREATOR_MONETIZABLE")).map(JSON.stringify).join("|")) export type GuildFeatures = - "INVITE_SPLASH" | "VIP_REGIONS" | "VANITY_URL" | "MORE_EMOJI" | "MORE_STICKERS" | "MORE_SOUNDBOARD" | "VERIFIED" | "COMMERCE" | "DISCOVERABLE" | "COMMUNITY" | "FEATURABLE" | "NEWS" | "HUB" | "PARTNERED" | "ANIMATED_ICON" | "BANNER" | "ENABLED_DISCOVERABLE_BEFORE" | "WELCOME_SCREEN_ENABLED" | "MEMBER_VERIFICATION_GATE_ENABLED" | "PREVIEW_ENABLED" | "ROLE_SUBSCRIPTIONS_ENABLED" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_STORE_PAGE" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "GUILD_WEB_PAGE_VANITY_URL" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "NEW_THREAD_PERMISSIONS" | "ROLE_ICONS" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "HAS_DIRECTORY_ENTRY" | "ANIMATED_BANNER" | "LINKED_TO_HUB" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_HOME_OVERRIDE" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_SERVER_GUIDE" | "INTERNAL_EMPLOYEE_ONLY" | "AUTO_MODERATION" | "INVITES_DISABLED" | "BURST_REACTIONS" | "SOUNDBOARD" | "SHARD" | "ACTIVITY_FEED_ENABLED_BY_USER" | "ACTIVITY_FEED_DISABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "LEADERBOARD_ENABLED" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "NON_COMMUNITY_RAID_ALERTS" | "RAID_ALERTS_DISABLED" | "AUTOMOD_TRIGGER_USER_PROFILE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "CLAN" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "FORWARDING_DISABLED" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "VIDEO_BITRATE_ENHANCED" | "MAX_FILE_SIZE_50_MB" | "MAX_FILE_SIZE_100_MB" | "GUILD_TAGS" | "ENHANCED_ROLE_COLORS" | "PREMIUM_TIER_3_OVERRIDE" | "REPORT_TO_MOD_PILOT" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE"; + "ACTIVITY_FEED_DISABLED_BY_USER" | "ACTIVITY_FEED_ENABLED_BY_USER" | "AGE_VERIFICATION_LARGE_GUILD" | "ANIMATED_BANNER" | "ANIMATED_ICON" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "AUTOMOD_TRIGGER_USER_PROFILE" | "AUTO_MODERATION" | "BANNER" | "BURST_REACTIONS" | "BYPASS_SLOWMODE_PERMISSION_MIGRATION_COMPLETE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "CLAN" | "COMMERCE" | "COMMUNITY" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_STORE_PAGE" | "DISCOVERABLE" | "ENABLED_DISCOVERABLE_BEFORE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "ENHANCED_ROLE_COLORS" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "FEATURABLE" | "FORWARDING_DISABLED" | "GAME_SERVERS" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "GUILD_SERVER_GUIDE" | "GUILD_TAGS" | "GUILD_TAGS_BADGE_PACK_FLEX" | "GUILD_TAGS_BADGE_PACK_PETS" | "GUILD_WEB_PAGE_VANITY_URL" | "HAS_DIRECTORY_ENTRY" | "HUB" | "INTERNAL_EMPLOYEE_ONLY" | "INVITES_DISABLED" | "INVITE_SPLASH" | "LINKED_TO_HUB" | "MAX_FILE_SIZE_100_MB" | "MAX_FILE_SIZE_50_MB" | "MEMBER_VERIFICATION_GATE_ENABLED" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "MORE_EMOJI" | "MORE_SOUNDBOARD" | "MORE_STICKERS" | "NEWS" | "NEW_THREAD_PERMISSIONS" | "NON_COMMUNITY_RAID_ALERTS" | "PARTNERED" | "PIN_PERMISSION_MIGRATION_COMPLETE" | "PREMIUM_TIER_3_OVERRIDE" | "PREVIEW_ENABLED" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "RAID_ALERTS_DISABLED" | "RELAY_ENABLED" | "REPORT_TO_MOD_PILOT" | "REPORT_TO_MOD_SURVEY" | "ROLE_ICONS" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "ROLE_SUBSCRIPTIONS_ENABLED" | "SOCIAL_LAYER_STOREFRONT" | "SOUNDBOARD" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE" | "VANITY_URL" | "VERIFIED" | "VIDEO_BITRATE_ENHANCED" | "VIP_REGIONS" | "WELCOME_SCREEN_ENABLED"; export type GuildPremiumFeatures = "ANIMATED_ICON" | "STAGE_CHANNEL_VIEWERS_150" | "ROLE_ICONS" | "GUILD_TAGS" | "BANNER" | "MAX_FILE_SIZE_50_MB" | "VIDEO_QUALITY_720_60FPS" | "STAGE_CHANNEL_VIEWERS_50" | "VIDEO_QUALITY_1080_60FPS" | "MAX_FILE_SIZE_100_MB" | "VANITY_URL" | "VIDEO_BITRATE_ENHANCED" | "STAGE_CHANNEL_VIEWERS_300" | "AUDIO_BITRATE_128_KBPS" | "ANIMATED_BANNER" | "TIERLESS_BOOSTING" | "ENHANCED_ROLE_COLORS" | "INVITE_SPLASH" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS"; @@ -16,15 +25,15 @@ export class Guild extends DiscordRecord { 1: number; 2: number; }; - application_id: unknown; + application_id: string | null; banner: string | undefined; - defaultMessageNotifications: number; + defaultMessageNotifications: GuildDefaultMessageNotifications; description: string | undefined; discoverySplash: string | undefined; - explicitContentFilter: number; + explicitContentFilter: GuildExplicitContentFilter; features: Set; homeHeader: string | undefined; - hubType: unknown; + hubType: number | null; icon: string | undefined; id: string; joinedAt: Date; @@ -32,10 +41,13 @@ export class Guild extends DiscordRecord { maxMembers: number; maxStageVideoChannelUsers: number; maxVideoChannelUsers: number; - mfaLevel: number; - moderatorReporting: unknown; + mfaLevel: GuildMFALevel; + moderatorReporting: { + moderatorReportingEnabled: boolean; + moderatorReportChannelId: string; + } | null; name: string; - nsfwLevel: number; + nsfwLevel: GuildNSFWLevel; ownerConfiguredContentLevel: number; ownerId: string; preferredLocale: string; @@ -47,18 +59,25 @@ export class Guild extends DiscordRecord { }; premiumProgressBarEnabled: boolean; premiumSubscriberCount: number; - premiumTier: 0 | 1 | 2 | 3; + premiumTier: GuildPremiumTier; profile: { badge: string | undefined; tag: string | undefined; } | undefined; publicUpdatesChannelId: string | undefined; - roles: Record; rulesChannelId: string | undefined; safetyAlertsChannelId: string | undefined; splash: string | undefined; - systemChannelFlags: number; + systemChannelFlags: SystemChannelFlags; systemChannelId: string | undefined; vanityURLCode: string | undefined; - verificationLevel: number; + verificationLevel: GuildVerificationLevel; +} + +export interface RoleOrUserPermission { + type: PermissionOverwriteType; + id?: string; + permissions?: bigint; + overwriteAllow?: bigint; + overwriteDeny?: bigint; } diff --git a/packages/discord-types/src/common/GuildMember.d.ts b/packages/discord-types/src/common/GuildMember.d.ts index 5cd4768242..d3d16ccd4b 100644 --- a/packages/discord-types/src/common/GuildMember.d.ts +++ b/packages/discord-types/src/common/GuildMember.d.ts @@ -1,26 +1,30 @@ +import { GuildMemberFlags } from "../../enums"; +import { Collectibles, DisplayNameStyles } from "./Channel"; + export interface GuildMember { - avatar: string | undefined; - avatarDecoration: string | undefined; - banner: string | undefined; - bio: string; + avatar: string | null | undefined; + avatarDecoration: string | null | undefined; + collectibles: Collectibles | null; colorRoleId: string | undefined; - colorString: string; + colorString: string | undefined; colorStrings: { primaryColor: string | undefined; secondaryColor: string | undefined; tertiaryColor: string | undefined; - }; - communicationDisabledUntil: string | undefined; - flags: number; - fullProfileLoadedTimestamp: number; + } | null; + communicationDisabledUntil: string | null | undefined; + displayNameStyles: DisplayNameStyles | null; + flags: GuildMemberFlags; + fullProfileLoadedTimestamp: number | undefined; guildId: string; - highestRoleId: string; - hoistRoleId: string; - iconRoleId: string; + highestRoleId: string | undefined; + hoistRoleId: string | undefined; + iconRoleId: string | undefined; isPending: boolean | undefined; joinedAt: string | undefined; - nick: string | undefined; - premiumSince: string | undefined; + nick: string | null | undefined; + premiumSince: string | null | undefined; roles: string[]; + unusualDMActivityUntil: string | undefined; userId: string; } diff --git a/packages/discord-types/src/common/Role.d.ts b/packages/discord-types/src/common/Role.d.ts index 7b03898440..7271868133 100644 --- a/packages/discord-types/src/common/Role.d.ts +++ b/packages/discord-types/src/common/Role.d.ts @@ -1,3 +1,5 @@ +import { RoleFlags } from "../../enums"; + export interface Role { color: number; colorString: string | undefined; @@ -11,23 +13,25 @@ export interface Role { secondary_color: number | undefined; tertiary_color: number | undefined; }; - flags: number; + description: string | undefined; + flags: RoleFlags; + guildId: string; hoist: boolean; icon: string | undefined; id: string; managed: boolean; mentionable: boolean; name: string; - originalPosition: number; permissions: bigint; position: number; - /** - * probably incomplete - */ tags: { - bot_id: string; - integration_id: string; - premium_subscriber: unknown; + bot_id?: string; + integration_id?: string; + premium_subscriber?: unknown; + subscription_listing_id?: string; + available_for_purchase?: unknown; + guild_connections?: unknown; } | undefined; unicodeEmoji: string | undefined; + version: number | undefined; } diff --git a/packages/discord-types/src/common/User.d.ts b/packages/discord-types/src/common/User.d.ts index 07eb471874..f3007f1203 100644 --- a/packages/discord-types/src/common/User.d.ts +++ b/packages/discord-types/src/common/User.d.ts @@ -1,65 +1,134 @@ // TODO: a lot of optional params can also be null, not just undef import { DiscordRecord } from "./Record"; +import { AvatarDecorationData, ClanData, Collectibles, DisplayNameStyles } from "./Channel"; +import { PremiumType, UserFlags } from "../../enums"; export class User extends DiscordRecord { constructor(user: object); - accentColor: number; + ageVerificationStatus: number; avatar: string; + avatarDecorationData: AvatarDecorationData | null; banner: string | null | undefined; - bio: string; bot: boolean; + collectibles: Collectibles | null; desktop: boolean; discriminator: string; + displayNameStyles: DisplayNameStyles | null; email: string | undefined; - flags: number; + flags: UserFlags; globalName: string | undefined; guildMemberAvatars: Record; + hasBouncedEmail: boolean; id: string; mfaEnabled: boolean; mobile: boolean; nsfwAllowed: boolean | undefined; + personalConnectionId: string | null; phone: string | undefined; - premiumType: number | undefined; + premiumState: { subscriptionId: string; } | null; + premiumType: PremiumType | undefined; premiumUsageFlags: number; - publicFlags: number; + primaryGuild: ClanData | null; + publicFlags: UserFlags; purchasedFlags: number; system: boolean; username: string; verified: boolean; + get avatarDecoration(): AvatarDecorationData | null; get createdAt(): Date; - get hasPremiumPerks(): boolean; + get isProvisional(): boolean; + get nameplate(): { asset: string; skuId: string; } | null; + get premiumGroupRole(): { id: string; name: string; color: number; } | null; get tag(): string; - get usernameNormalized(): string; - addGuildAvatarHash(guildId: string, avatarHash: string): User; - getAvatarSource(guildId: string, canAnimate?: boolean): { uri: string; }; - getAvatarURL(guildId?: string | null, t?: unknown, canAnimate?: boolean): string; + addGuildAvatarHash(guildId: string, avatarHash: string): this; + getAvatarSource(guildId: string): { uri: string; }; + getAvatarURL(guildId?: string | null, size?: number, canAnimate?: boolean, format?: string): string; + hadPremiumSubscription(): boolean; hasAvatarForGuild(guildId: string): boolean; - hasDisabledPremium(): boolean; - hasFlag(flag: number): boolean; + hasFlag(flag: UserFlags): boolean; hasFreePremium(): boolean; - hasHadSKU(e: unknown): boolean; + hasHadPremium(): boolean; + hasHadSKU(sku: string): boolean; hasPremiumUsageFlag(flag: number): boolean; hasPurchasedFlag(flag: number): boolean; + hasUniqueUsername(): boolean; hasUrgentMessages(): boolean; + hasVerifiedEmailOrPhone(): boolean; isClaimed(): boolean; + isFractionalPremiumWithNoSubscription(): boolean; isLocalBot(): boolean; isNonUserBot(): boolean; isPhoneVerified(): boolean; - isStaff(): boolean; + isPremiumGroupMember(): boolean; + isPremiumGroupPrimary(): boolean; + isPremiumWithFractionalPremiumOnly(): boolean; + isPremiumWithPremiumGroup(): boolean; isSystemUser(): boolean; isVerifiedBot(): boolean; - removeGuildAvatarHash(guildId: string): User; + removeGuildAvatarHash(guildId: string): this; + toJS(): object; toString(): string; + update(props: Partial): this; } export interface UserJSON { avatar: string; - avatarDecoration: unknown | undefined; + avatarDecoration: AvatarDecorationData | null; discriminator: string; id: string; - publicFlags: number; + publicFlags: UserFlags; username: string; + globalName: string | undefined; +} + +export interface ProfileEffect { + skuId: string; + title?: string; + description?: string; + accessibilityLabel?: string; + reducedMotionSrc?: string; + thumbnailPreviewSrc?: string; + effects?: any[]; + animationType?: number; + staticFrameSrc?: string; + type?: number; +} + +export interface Nameplate { + skuId: string; + asset: string; + label?: string; + palette?: string; + type?: number; +} + +export interface ProfilePreset { + name: string; + timestamp: number; + avatarDataUrl?: string | null; + bannerDataUrl?: string | null; + bio?: string | null; + accentColor?: number | null; + themeColors?: number[] | null; + globalName?: string | null; + pronouns?: string | null; + avatarDecoration?: { + asset: string; + skuId: string; + } | null; + profileEffect?: ProfileEffect | null; + nameplate?: Nameplate | null; + primaryGuildId?: string | null; + customStatus?: CustomStatus | null; + displayNameStyles?: DisplayNameStyles | null; +} + +export interface CustomStatus { + text?: string; + emojiId?: string; + emojiName?: string; + expiresAtMs?: string; } diff --git a/packages/discord-types/src/common/messages/Embed.d.ts b/packages/discord-types/src/common/messages/Embed.d.ts index 4edd9ced1a..9142d417cf 100644 --- a/packages/discord-types/src/common/messages/Embed.d.ts +++ b/packages/discord-types/src/common/messages/Embed.d.ts @@ -1,41 +1,74 @@ +export type EmbedType = + | "image" + | "video" + | "link" + | "article" + | "tweet" + | "rich" + | "gifv" + | "application_news" + | "auto_moderation_message" + | "auto_moderation_notification" + | "text" + | "post_preview" + | "gift" + | "safety_policy_notice" + | "safety_system_notification" + | "age_verification_system_notification" + | "voice_channel" + | "gaming_profile" + | "poll_result"; + +export interface EmbedMedia { + height: number; + width: number; + url: string; + proxyURL?: string; + placeholder: string; + placeholderVersion: number; + description?: string; + srcIsAnimated: boolean; + flags: number; + contentType: string; +} + +export interface EmbedField { + rawName: string; + rawValue: string; + inline: boolean; +} + export interface Embed { + id: string; + url: string; + type: EmbedType; + rawTitle: string; + rawDescription: string; + referenceId: string | undefined; + flags: number | undefined; + contentScanVersion: number; author?: { name: string; url: string; iconURL: string | undefined; iconProxyURL: string | undefined; }; - color: string; - fields: []; - id: string; - image?: { - height: number; - width: number; - url: string; - proxyURL: string; + footer?: { + text: string; + iconURL: string | undefined; + iconProxyURL: string | undefined; }; provider?: { name: string; url: string | undefined; }; - rawDescription: string; - rawTitle: string; - referenceId: unknown; - timestamp: string; - thumbnail?: { - height: number; - proxyURL: string | undefined; - url: string; - width: number; - }; - type: string; - url: string | undefined; - video?: { - height: number; - width: number; - url: string; - proxyURL: string | undefined; - }; + timestamp?: Date; + color: string; + thumbnail?: EmbedMedia; + image?: EmbedMedia; + images?: EmbedMedia[]; + video?: EmbedMedia; + fields: EmbedField[]; } export interface EmbedJSON { @@ -48,7 +81,7 @@ export interface EmbedJSON { title: string; color: string; description: string; - type: string; + type: EmbedType; url: string | undefined; provider?: { name: string; diff --git a/packages/discord-types/src/common/messages/Message.d.ts b/packages/discord-types/src/common/messages/Message.d.ts index 4a6f3e8b52..b347eecbd8 100644 --- a/packages/discord-types/src/common/messages/Message.d.ts +++ b/packages/discord-types/src/common/messages/Message.d.ts @@ -2,60 +2,135 @@ import { CommandOption } from './Commands'; import { User, UserJSON } from '../User'; import { Embed, EmbedJSON } from './Embed'; import { DiscordRecord } from "../Record"; -import { ApplicationIntegrationType, MessageFlags, MessageType, StickerFormatType } from "../../../enums"; +import { ApplicationCommandOptionType, ApplicationCommandType, ApplicationIntegrationType, ButtonStyle, ComponentType, InteractionType, MessageActivityType, MessageFlags, MessageReferenceType, MessageType, PollLayoutType, StickerFormatType } from "../../../enums"; + +export type MessageState = "SENT" | "SENDING" | "SEND_FAILED"; + +export type CodedLinkType = + | "INVITE" + | "TEMPLATE" + | "BUILD_OVERRIDE" + | "MANUAL_BUILD_OVERRIDE" + | "EXPERIMENT" + | "EVENT" + | "CHANNEL_LINK" + | "APP_DIRECTORY_PROFILE" + | "APP_DIRECTORY_STOREFRONT" + | "APP_DIRECTORY_STOREFRONT_SKU" + | "APP_OAUTH2_LINK" + | "ACTIVITY_BOOKMARK" + | "EMBEDDED_ACTIVITY_INVITE" + | "GUILD_PRODUCT" + | "SERVER_SHOP" + | "SOCIAL_LAYER_STOREFRONT" + | "QUESTS_EMBED" + | "COLLECTIBLES_SHOP"; + +export interface MessageActivity { + type: MessageActivityType; + party_id?: string; +} + +export interface PollMedia { + text?: string; + emoji?: ReactionEmoji; +} + +export interface PollAnswer { + answer_id: number; + poll_media: PollMedia; +} + +export interface Poll { + question: PollMedia; + answers: PollAnswer[]; + expiry: string; + allow_multiselect: boolean; + layout_type: PollLayoutType; +} + +export interface RoleSubscriptionData { + role_subscription_listing_id: string; + tier_name: string; + total_months_subscribed: number; + is_renewal: boolean; +} + +export interface MessageComponent { + type: ComponentType; + id?: string; + custom_id?: string; + disabled?: boolean; + style?: ButtonStyle; + label?: string; + emoji?: ReactionEmoji; + url?: string; + options?: { label: string; value: string; description?: string; emoji?: ReactionEmoji; default?: boolean; }[]; + placeholder?: string; + min_values?: number; + max_values?: number; + components?: MessageComponent[]; +} /* * TODO: looks like discord has moved over to Date instead of Moment; */ export class Message extends DiscordRecord { constructor(message: object); - activity: unknown; - application: unknown; - applicationId: string | unknown; + activity: MessageActivity | null; + activityInstance: { applicationId: string; instanceId: string; } | null; + application: { id: string; name: string; icon: string | null; } | null; + applicationId: string | null; attachments: MessageAttachment[]; author: User; blocked: boolean; bot: boolean; call: { - duration: moment.Duration; - endedTimestamp: moment.Moment; + duration: number | null; + endedTimestamp: Date | null; participants: string[]; - }; + } | null; + changelogId: string | null; channel_id: string; /** * NOTE: not fully typed */ codedLinks: { code?: string; - type: string; + type: CodedLinkType; }[]; - colorString: unknown; - components: unknown[]; + colorString: string | null; + components: MessageComponent[]; content: string; - customRenderedContent: unknown; - editedTimestamp: Date; + customRenderedContent: { + content: React.ReactNode; + [key: string]: unknown; + } | null; + editedTimestamp: Date | null; embeds: Embed[]; flags: MessageFlags; giftCodes: string[]; + giftInfo: { sku_id: string; slug: string; } | null; + giftingPrompt: { recipientUserId: string; } | null; id: string; interaction: { id: string; name: string; - type: number; + type: InteractionType; user: User; - }[] | undefined; + }[] | null; interactionData: { application_command: { application_id: string; - default_member_permissions: unknown; + default_member_permissions: string | null; default_permission: boolean; description: string; - dm_permission: unknown; + dm_permission: boolean | null; id: string; name: string; options: CommandOption[]; - permissions: unknown[]; - type: number; + permissions: string[]; + type: ApplicationCommandType; version: string; }; attachments: MessageAttachment[]; @@ -63,19 +138,19 @@ export class Message extends DiscordRecord { id: string; name: string; options: { - focused: unknown; + focused: boolean | undefined; name: string; - type: number; + type: ApplicationCommandOptionType; value: string; }[]; - type: number; + type: InteractionType; version: string; - }[]; - interactionMetadata?: { + }[] | null; + interactionMetadata: { id: string; - type: number; + type: InteractionType; name?: string; - command_type?: number; + command_type?: ApplicationCommandType; ephemerality_reason?: number; user: User; authorizing_integration_owners: Record; @@ -83,16 +158,20 @@ export class Message extends DiscordRecord { interacted_message_id?: string; target_user?: User; target_message_id?: string; - }; - interactionError: unknown[]; + } | null; + interactionError: string[] | null; + ignored: boolean; isSearchHit: boolean; - loggingName: unknown; + isUnsupported: boolean; + loggingName: string | null; mentionChannels: string[]; mentionEveryone: boolean; + mentionGames: { id: string; name: string; }[]; mentionRoles: string[]; mentioned: boolean; mentions: string[]; messageReference: { + type?: MessageReferenceType; guild_id?: string; channel_id: string; message_id: string; @@ -100,18 +179,26 @@ export class Message extends DiscordRecord { messageSnapshots: { message: Message; }[]; - nick: unknown; // probably a string + nick: string | null; nonce: string | undefined; pinned: boolean; + poll: Poll | null; + potions: { id: string; expiresAt: string; }[]; + premiumGroupInviteId: string | null; + purchaseNotification: { type: number; guild_product_purchase?: { product_name: string; }; } | null; reactions: MessageReaction[]; - state: string; + referralTrialOfferId: string | null; + roleSubscriptionData: RoleSubscriptionData | null; + sharedClientTheme: { primary_color: number; secondary_color: number; } | null; + soundboardSounds: { sound_id: string; volume: number; emoji_id?: string; emoji_name?: string; }[]; + state: MessageState; stickerItems: { format_type: StickerFormatType; id: string; name: string; }[]; - stickers: unknown[]; - timestamp: moment.Moment; + stickers: { id: string; name: string; format_type: StickerFormatType; }[]; + timestamp: Date; tts: boolean; type: MessageType; webhookId: string | undefined; @@ -134,10 +221,18 @@ export class Message extends DiscordRecord { removeReaction(emoji: ReactionEmoji, fromCurrentUser: boolean): Message; getChannelId(): string; + getContentMessage(): Message; hasFlag(flag: MessageFlags): boolean; + hasPotions(): boolean; isCommandType(): boolean; isEdited(): boolean; + isFirstMessageInForumPost(channel: unknown): boolean; + isInteractionPlaceholder(): boolean; + isPoll(): boolean; isSystemDM(): boolean; + canDeleteOwnMessage(userId: string): boolean; + userHasReactedWithEmoji(emoji: ReactionEmoji, burst?: boolean): boolean; + addReactionBatch(reactions: { emoji: ReactionEmoji; users: string[]; }[], burstReactions: { emoji: ReactionEmoji; users: string[]; }[]): Message; /** Vencord added */ deleted?: boolean; @@ -148,14 +243,14 @@ export interface MessageJSON { attachments: MessageAttachment[]; author: UserJSON; channel_id: string; - components: unknown[]; + components: MessageComponent[]; content: string; edited_timestamp: string; embeds: EmbedJSON[]; - flags: number; + flags: MessageFlags; guild_id: string | undefined; id: string; - loggingName: unknown; + loggingName: string | null; member: { avatar: string | undefined; communication_disabled_until: string | undefined; @@ -180,10 +275,10 @@ export interface MessageJSON { nonce: string | undefined; pinned: boolean; referenced_message: MessageJSON | undefined; - state: string; + state: MessageState; timestamp: string; tts: boolean; - type: number; + type: MessageType; } export interface MessageAttachment { diff --git a/packages/discord-types/src/common/messages/Sticker.d.ts b/packages/discord-types/src/common/messages/Sticker.d.ts index 744b062316..84be901581 100644 --- a/packages/discord-types/src/common/messages/Sticker.d.ts +++ b/packages/discord-types/src/common/messages/Sticker.d.ts @@ -1,7 +1,7 @@ import { StickerFormatType, StickerType } from "../../../enums"; interface BaseSticker { - asset: string; + asset?: string; available: boolean; description: string; format_type: StickerFormatType; diff --git a/packages/discord-types/src/components.d.ts b/packages/discord-types/src/components.d.ts index 9a394677f0..8d0aa0ed46 100644 --- a/packages/discord-types/src/components.d.ts +++ b/packages/discord-types/src/components.d.ts @@ -1,3 +1,4 @@ +import { Moment } from "moment"; import type { ComponentClass, ComponentPropsWithRef, ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, JSX, KeyboardEvent, MouseEvent, PointerEvent, PropsWithChildren, ReactNode, Ref, RefObject } from "react"; @@ -153,7 +154,7 @@ export type Checkbox = ComponentType, "onCha inputRef?: Ref; }>; -interface SelectOption { +export interface SelectOption { disabled?: boolean; value: any; label: string; @@ -392,6 +393,7 @@ export type Paginator = ComponentType<{ pageSize: number; totalCount: number; + className?: string; onPageChange?(page: number): void; hideMaxPage?: boolean; }>; @@ -409,6 +411,24 @@ export type MaskedLink = ComponentType>; +interface ScrollToOptions { + animate?: boolean; + callback?: (() => unknown); +} + +/** Full type can be found at {@link https://github.com/fedeericodl/discord-client-types/blob/main/src/discord_common/js/packages/design/components/Scroller/utils/core/getAnimatedScrollHelpers.ts} */ +export interface ScrollerBaseRef { + scrollTo: (props: { to: number; } & ScrollToOptions) => void; + scrollPageUp: (props?: ScrollToOptions) => void; + scrollPageDown: (props?: ScrollToOptions) => void; + scrollToTop: (props?: ScrollToOptions) => void; + scrollToBottom: (props?: ScrollToOptions) => void; + isScrolledToTop: () => boolean; + isScrolledToBottom: () => boolean; + getDistanceFromTop: () => number; + getDistanceFromBottom: () => number; +} + export interface ScrollerBaseProps { className?: string; style?: CSSProperties; @@ -416,6 +436,7 @@ export interface ScrollerBaseProps { paddingFix?: boolean; onClose?(): void; onScroll?(): void; + ref?: Ref; } export type ScrollerThin = ComponentType React.ReactNode; wrapSection?: (section: number, children: React.ReactNode) => React.ReactNode; - sectionHeight: number; - rowHeight: number; - footerHeight?: number; + sectionHeight: number | ((section: number) => number); + rowHeight: number | ((section: number, row: number) => number); + footerHeight?: number | ((section: number) => number); sidebarHeight?: number; chunkSize?: number; @@ -479,6 +500,7 @@ export type Avatar = ComponentType; }>>; +export type Dots = ComponentType>; + export type Icon = ComponentType; }>; MenuSliderControl: RC<{ - minValue: number, - maxValue: number, - value: number, - onChange(value: number): void, + minValue?: number, + maxValue?: number, + value?: number, + onChange?(value: number): void, renderValue?(value: number): string, }>; MenuSearchControl: RC<{ @@ -77,4 +77,3 @@ export interface ContextMenuApi { options?: { enableSpellCheck?: boolean; } ): void; } - diff --git a/packages/discord-types/src/stores/AccessibilityStore.d.ts b/packages/discord-types/src/stores/AccessibilityStore.d.ts index 86ad4c5050..cf0248962e 100644 --- a/packages/discord-types/src/stores/AccessibilityStore.d.ts +++ b/packages/discord-types/src/stores/AccessibilityStore.d.ts @@ -4,12 +4,13 @@ export type ReducedMotionPreference = "auto" | "reduce" | "no-preference"; export type ForcedColorsPreference = "none" | "active"; export type ContrastPreference = "no-preference" | "more" | "less" | "custom"; export type RoleStyle = "username" | "dot" | "hidden"; +export type ContrastMode = "default" | "high"; export interface AccessibilityState { fontSize: number; zoom: number; keyboardModeEnabled: boolean; - contrastMode: string; + contrastMode: ContrastMode; colorblindMode: boolean; lowContrastMode: boolean; saturation: number; diff --git a/packages/discord-types/src/stores/ApplicationCommandIndexStore.d.ts b/packages/discord-types/src/stores/ApplicationCommandIndexStore.d.ts new file mode 100644 index 0000000000..2b1affd755 --- /dev/null +++ b/packages/discord-types/src/stores/ApplicationCommandIndexStore.d.ts @@ -0,0 +1,443 @@ +import { Application, Channel, FluxStore } from ".."; +import { CommandArgument, CommandContext } from "../common/messages/Commands"; +import { + ApplicationCommandHandlerType, + ApplicationCommandInputType, + ApplicationCommandOptionType, + ApplicationCommandPermissionType, + ApplicationCommandSectionType, + ApplicationCommandType, + ApplicationIntegrationType, + ChannelType, + InteractionContextType +} from "../../enums"; + +/** Score method for ranking command results. */ +export type ApplicationCommandScoreMethod = + | "none" + | "application_only" + | "command_only" + | "command_or_application"; + +/** Built-in command handling mode. */ +export type BuiltInCommandMode = + | "allow" + | "deny" + | "only_text"; + +/** Target for fetching guild command index. */ +export interface ApplicationCommandIndexGuildTarget { + type: "guild"; + guildId: string; +} + +/** Target for fetching channel command index. */ +export interface ApplicationCommandIndexChannelTarget { + type: "channel"; + channelId: string; +} + +/** Target for fetching user command index. */ +export interface ApplicationCommandIndexUserTarget { + type: "user"; +} + +/** Target for fetching application-specific command index. */ +export interface ApplicationCommandIndexApplicationTarget { + type: "application"; + applicationId: string; +} + +/** Union of all fetch target types. */ +export type ApplicationCommandIndexFetchTarget = + | ApplicationCommandIndexGuildTarget + | ApplicationCommandIndexChannelTarget + | ApplicationCommandIndexUserTarget + | ApplicationCommandIndexApplicationTarget; + +/** Context for querying commands with a channel. */ +export interface ApplicationCommandChannelContext { + type: "channel"; + channel: Channel; +} + +/** Context for querying commands without a channel. */ +export interface ApplicationCommandContextlessContext { + type: "contextless"; +} + +/** Union of query context types. */ +export type ApplicationCommandContext = + | ApplicationCommandChannelContext + | ApplicationCommandContextlessContext; + +/** Fetch state when not fetching. */ +export interface ApplicationCommandIndexFetchStateIdle { + fetching: false; + retryAfter?: number; +} + +/** Fetch state when actively fetching. */ +export interface ApplicationCommandIndexFetchStateFetching { + fetching: true; + abort: AbortController; + promise: Promise; +} + +/** Union of fetch state types. */ +export type ApplicationCommandIndexFetchState = + | ApplicationCommandIndexFetchStateIdle + | ApplicationCommandIndexFetchStateFetching; + +/** Result of a successful command index fetch. */ +export interface ApplicationCommandIndexResult { + /** Command sections keyed by application ID. */ + sections: Record; + /** Maps bot user ID to application ID. */ + sectionIdsByBotId: Record; + /** Version symbol for cache invalidation. */ + version: symbol; +} + +/** State for a command index entry. */ +export interface ApplicationCommandIndexState { + /** Server version symbol for staleness detection. */ + serverVersion: symbol; + /** Current fetch state. */ + fetchState: ApplicationCommandIndexFetchState; + /** Fetched result, if available. */ + result?: ApplicationCommandIndexResult; +} + +/** A section containing commands from a single application. */ +export interface ApplicationCommandSection { + /** Section descriptor with application info. */ + descriptor: ApplicationCommandSectionDescriptor; + /** Commands keyed by command ID. */ + commands: Record; +} + +/** Descriptor for a command section. */ +export interface ApplicationCommandSectionDescriptor { + /** Section ID, typically the application ID or a special value like "-1" for built-in. */ + id: string; + /** Section type. */ + type: ApplicationCommandSectionType; + /** Display name for the section. */ + name: string; + /** Application icon hash. */ + icon?: string | null; + /** Full application object for application sections. */ + application?: Application; + /** Whether this is a user-installed app. */ + isUserApp?: boolean; + /** Bot user ID for this application. */ + botId?: string; + /** Permissions for the application's commands. */ + permissions?: ApplicationCommandPermission[] | Record; +} + +/** Permission override for a command. */ +export interface ApplicationCommandPermission { + /** Type of permission target. */ + type: ApplicationCommandPermissionType; + /** ID of the role, user, or channel. */ + id: string; + /** Whether the target has permission to use the command. */ + permission: boolean; +} + +/** Option for an application command. */ +export interface ApplicationCommandOption { + /** Option type. */ + type: ApplicationCommandOptionType; + /** Option name. */ + name: string; + /** Localized display name for the option. */ + displayName?: string; + /** Localized option name from server. Bot commands only. */ + serverLocalizedName?: string; + /** Option description. */ + description: string; + /** Localized display description for the option. */ + displayDescription?: string; + /** Localized option description from server. Bot commands only. */ + serverLocalizedDescription?: string; + /** Whether this option is required. */ + required?: boolean; + /** Choices for string/integer/number options. */ + choices?: ApplicationCommandOptionChoice[]; + /** Nested options for subcommands. */ + options?: ApplicationCommandOption[]; + /** Channel types allowed for channel options. */ + channel_types?: ChannelType[]; + /** Minimum value for number/integer options. */ + min_value?: number; + /** Maximum value for number/integer options. */ + max_value?: number; + /** Minimum length for string options. */ + min_length?: number; + /** Maximum length for string options. */ + max_length?: number; + /** Whether autocomplete is enabled. */ + autocomplete?: boolean; +} + +/** Choice for a command option. */ +export interface ApplicationCommandOptionChoice { + /** Choice name. */ + name: string; + /** Localized choice name, if available. */ + name_localized?: string; + /** Choice value. */ + value: string | number; +} + +/** Raw application command from the API. */ +export interface RawApplicationCommand { + id: string; + application_id: string; + version: string; + guild_id?: string; + type?: ApplicationCommandType; + name: string; + name_default?: string; + name_localized?: string; + description: string; + description_default?: string; + description_localized?: string; + options?: ApplicationCommandOption[]; + default_member_permissions?: string | null; + dm_permission?: boolean; + nsfw?: boolean; + contexts?: InteractionContextType[]; + integration_types?: ApplicationIntegrationType[]; + permissions?: ApplicationCommandPermission[]; + global_popularity_rank?: number; + handler?: ApplicationCommandHandlerType; +} + +/** Processed application command. */ +export interface ApplicationCommand { + /** Command version string. Bot commands only. */ + version?: string; + /** Guild ID if guild-specific. Bot commands only. */ + guildId?: string; + /** Composite command ID including subcommand path. */ + id: string; + /** Original untranslated command name. */ + untranslatedName: string; + /** Localized command name from server. Bot commands only. */ + serverLocalizedName?: string; + /** Application ID. */ + applicationId: string; + /** Command type. */ + type: ApplicationCommandType; + /** Input type. */ + inputType: ApplicationCommandInputType; + /** Original untranslated description. */ + untranslatedDescription: string; + /** Command options. */ + options: ApplicationCommandOption[]; + /** Root command reference for subcommands. Bot commands only. */ + rootCommand?: RawApplicationCommand; + /** Path of subcommand options for nested commands. Bot commands only. */ + subCommandPath?: ApplicationCommandOption[]; + /** Default member permissions required as bigint. Bot commands only. */ + defaultMemberPermissions?: bigint; + /** Whether usable in DMs. Bot commands only. */ + dmPermission?: boolean; + /** Command permissions. Bot commands only. */ + permissions?: ApplicationCommandPermission[] | Record; + /** Localized display name. */ + displayName: string; + /** Localized display description. */ + displayDescription: string; + /** Whether this is an NSFW command. Bot commands only. */ + nsfw?: boolean; + /** Allowed interaction contexts. Bot commands only. */ + contexts?: InteractionContextType[]; + /** Integration types that can use this command. Bot commands only. */ + integration_types?: ApplicationIntegrationType[]; + /** Global popularity ranking. Bot commands only. */ + global_popularity_rank?: number; + /** Handler type. Bot commands only. */ + handler?: ApplicationCommandHandlerType; + /** Section descriptor for display purposes. */ + section?: ApplicationCommandSectionDescriptor; + /** Score for search ranking. */ + score?: number; + /** Predicate to check if command should be shown. Built-in commands only. */ + predicate?(ctx: CommandContext): boolean; + /** Execute the command. Built-in commands only. */ + execute?(args: CommandArgument[], ctx: CommandContext): void; +} + +/** Sectioned command group for display. */ +export interface SectionedApplicationCommands { + /** Section this group belongs to. */ + section: ApplicationCommandSectionDescriptor; + /** Commands in this section. */ + data: ApplicationCommand[]; +} + +/** Filter options for querying commands. */ +export interface ApplicationCommandQueryFilters { + /** Command types to include. */ + commandTypes: ApplicationCommandType[]; + /** Search text. */ + text?: string; + /** Built-in command handling mode. */ + builtIns?: BuiltInCommandMode; + /** Whether to include application commands. */ + applicationCommands?: boolean; +} + +/** Options for querying commands. */ +export interface ApplicationCommandQueryOptions { + /** Number of placeholder commands to show while loading. */ + placeholderCount?: number; + /** Score method for ranking results. */ + scoreMethod?: ApplicationCommandScoreMethod; + /** Whether to allow empty sections in results. */ + allowEmptySections?: boolean; + /** Whether to allow fetching if needed. */ + allowFetch?: boolean; + /** Whether to include application state. */ + allowApplicationState?: boolean; + /** Specific application ID to query. */ + applicationId?: string; + /** Sorting options. */ + sortOptions?: ApplicationCommandSortOptions; + /** Whether to include install-on-demand apps. */ + installOnDemand?: boolean; +} + +/** Sorting options for application command queries. */ +export interface ApplicationCommandSortOptions { + /** Sorting options for applications. */ + applications: ApplicationCommandSortConfig; + /** Sorting options for commands. */ + commands: ApplicationCommandSortConfig; +} + +/** Sort configuration for frecency and score. */ +export interface ApplicationCommandSortConfig { + /** Whether to use frecency for sorting. */ + useFrecency: boolean; + /** Whether to use score for sorting. */ + useScore: boolean; +} + +/** Result of a command query. */ +export interface ApplicationCommandQueryResult { + /** All section descriptors. */ + descriptors: ApplicationCommandSectionDescriptor[]; + /** Flat list of all commands. */ + commands: ApplicationCommand[]; + /** Commands grouped by section. */ + sectionedCommands: SectionedApplicationCommands[]; + /** Whether data is still loading. */ + loading: boolean; +} + +/** Parameters for checking context state application. */ +export interface ApplicationCommandContextStateParams { + applicationId: string; + channelId: string; + guildId?: string; +} + +/** Result of getting section info. */ +export interface ApplicationCommandSectionInfo { + /** Section descriptor. */ + descriptor?: ApplicationCommandSectionDescriptor; + /** Commands in this section. */ + sectionCommands?: ApplicationCommand[]; + /** Whether installed in a guild. */ + isGuildInstalled: boolean; + /** Whether installed for user. */ + isUserInstalled: boolean; +} + +/** + * Store for application command indexes. + * Manages fetching, caching, and querying of slash commands and context menu commands. + */ +export class ApplicationCommandIndexStore extends FluxStore { + /** Internal index cache keyed by guild/channel/user ID. */ + indices: Record; + /** + * Gets the command index state for the given context. + * @param context Channel context or contextless context. + * @returns Index state for the context. + */ + getContextState(context: ApplicationCommandContext): ApplicationCommandIndexState; + + /** + * Checks if an application has commands in the context state. + * @param params Application and channel info. + * @returns Whether the application has commands in context. + */ + hasContextStateApplication(params: ApplicationCommandContextStateParams): boolean; + + /** + * Gets the command index state for a guild. + * @param guildId Guild ID. + * @returns Index state for the guild. + */ + getGuildState(guildId: string): ApplicationCommandIndexState; + + /** + * Gets the command index state for the current user's installed apps. + * @returns Index state for user-installed apps. + */ + getUserState(): ApplicationCommandIndexState; + + /** + * Checks if an application has commands in the user state. + * @param applicationId Application ID. + * @returns Whether the application has user commands. + */ + hasUserStateApplication(applicationId: string): boolean; + + /** + * Gets the command index state for a specific application. + * @param applicationId Application ID. + * @returns Index state for the application. + */ + getApplicationState(applicationId: string): ApplicationCommandIndexState; + + /** + * Gets all application index states. + * @returns Map of application ID to index state. + */ + getApplicationStates(): Map; + + /** + * Checks if an application state exists. + * @param applicationId Application ID. + * @returns Whether the application state exists. + */ + hasApplicationState(applicationId: string): boolean; + + /** + * Queries commands based on context and filters. + * @param context Channel or contextless context. + * @param filters Query filters. + * @param options Query options. + * @returns Query result with commands and sections. + */ + query( + context: ApplicationCommandContext, + filters: ApplicationCommandQueryFilters, + options: ApplicationCommandQueryOptions + ): ApplicationCommandQueryResult; + + /** + * Queries for install-on-demand app commands. + * @param applicationId Application ID. + * @param channelId Channel ID. + */ + queryInstallOnDemandApp(applicationId: string, channelId: string): void; +} diff --git a/packages/discord-types/src/stores/ApplicationStore.d.ts b/packages/discord-types/src/stores/ApplicationStore.d.ts index 6bfb51056e..165f468b04 100644 --- a/packages/discord-types/src/stores/ApplicationStore.d.ts +++ b/packages/discord-types/src/stores/ApplicationStore.d.ts @@ -1,4 +1,5 @@ import { Application, FluxStore } from ".."; +import { ApplicationType } from "../../enums"; export interface ApplicationStoreState { botUserIdToAppUsage: Record; @@ -10,11 +11,12 @@ export interface ApplicationUsage { } export class ApplicationStore extends FluxStore { + _getAllApplications(): Application[]; getState(): ApplicationStoreState; getApplication(applicationId: string): Application; getApplicationByName(name: string): Application | undefined; getApplicationLastUpdated(applicationId: string): number | undefined; - getGuildApplication(guildId: string, type: number): Application | undefined; + getGuildApplication(guildId: string, type: ApplicationType): Application | undefined; getGuildApplicationIds(guildId: string): string[]; getAppIdForBotUserId(botUserId: string): string | undefined; getFetchingOrFailedFetchingIds(): string[]; diff --git a/packages/discord-types/src/stores/ChannelRTCStore.d.ts b/packages/discord-types/src/stores/ChannelRTCStore.d.ts index 13fedf0fa8..0c8271581b 100644 --- a/packages/discord-types/src/stores/ChannelRTCStore.d.ts +++ b/packages/discord-types/src/stores/ChannelRTCStore.d.ts @@ -1,5 +1,6 @@ -import { FluxStore, User, VoiceState } from ".."; -import { ParticipantType, RTCPlatform } from "../../enums"; +import { AvatarDecorationData, FluxStore, User, VoiceState } from ".."; +import { ActivityType, ParticipantType, RTCPlatform } from "../../enums"; +import { StreamType } from "./FriendsStore"; export type RTCLayout = "normal" | "minimum" | "no-chat" | "full-screen" | "haven"; export type RTCMode = "video" | "voice"; @@ -15,7 +16,7 @@ export interface Stream { channelId: string; guildId: string | null; ownerId: string; - streamType: string; + streamType: StreamType; } export interface BaseParticipant { @@ -36,8 +37,7 @@ export interface UserParticipant extends BaseParticipant { soundsharing: boolean; ringing: boolean; userNick: string; - // TODO: type - userAvatarDecoration: any | null; + userAvatarDecoration: AvatarDecorationData | null; localVideoDisabled: boolean; userVideo?: boolean; streamId?: string; @@ -57,7 +57,7 @@ export interface StreamParticipant extends BaseParticipant { export interface ActivityParticipant extends BaseParticipant { type: ParticipantType.ACTIVITY; applicationId: string; - activityType: number; + activityType: ActivityType; activityUrl: string; participants: string[]; guildId: string | null; diff --git a/packages/discord-types/src/stores/ChannelStore.d.ts b/packages/discord-types/src/stores/ChannelStore.d.ts index 81b006cd65..dccd79e1ab 100644 --- a/packages/discord-types/src/stores/ChannelStore.d.ts +++ b/packages/discord-types/src/stores/ChannelStore.d.ts @@ -1,31 +1,111 @@ import { Channel, FluxStore } from ".."; +/** Debug info for channel store state. */ +export interface ChannelStoreDebugInfo { + /** Guild IDs that have been loaded. */ + loadedGuildIds: string[]; + /** Guild IDs currently being loaded. */ + pendingGuildLoads: string[]; + /** String descriptions of guild channel counts. */ + guildSizes: string[]; +} + +/** + * Flux store managing all channel data including guild channels, + * threads, DMs, and group DMs. + */ export class ChannelStore extends FluxStore { + /** + * Gets a channel by ID. + * @param channelId Channel ID to look up. + */ getChannel(channelId: string): Channel; + /** + * Gets basic channel info by ID, returns undefined if not found. + * @param channelId Channel ID to look up. + */ getBasicChannel(channelId: string): Channel | undefined; + /** + * Checks if a channel exists in the store. + * @param channelId Channel ID to check. + */ hasChannel(channelId: string): boolean; + /** + * Gets all channel IDs, optionally filtered by guild. + * @param guildId Guild ID to filter by, or null/undefined for all channels. + */ getChannelIds(guildId?: string | null): string[]; + /** + * Gets basic guild channels as a mutable record. + * @param guildId Guild ID to get channels for. + * @returns Record keyed by channel ID. + */ getMutableBasicGuildChannelsForGuild(guildId: string): Record; + /** + * Gets all guild channels as a mutable record. + * @param guildId Guild ID to get channels for. + * @returns Record keyed by channel ID. + */ getMutableGuildChannelsForGuild(guildId: string): Record; + /** + * Gets all threads for a guild. + * @param guildId Guild ID to get threads for. + */ getAllThreadsForGuild(guildId: string): Channel[]; - getAllThreadsForParent(channelId: string): Channel[]; + /** + * Gets all threads under a parent channel. + * @param parentChannelId Parent channel ID. + */ + getAllThreadsForParent(parentChannelId: string): Channel[]; + /** + * Gets sorted linked channels for a guild, such as stage instances and events. + * @param guildId Guild ID. + */ getSortedLinkedChannelsForGuild(guildId: string): Channel[]; - getDMFromUserId(userId: string): string; + /** + * Gets DM channel ID for a user. + * @param userId User ID to get DM for. + * @returns Channel ID, not the channel object. + */ + getDMFromUserId(userId: string): string | undefined; + /** + * Gets DM channel object for a user. + * @param userId User ID to get DM for. + */ getDMChannelFromUserId(userId: string): Channel | undefined; + /** Gets all user IDs that have DM channels. */ getDMUserIds(): string[]; + /** + * Gets mutable map of user ID to DM channel ID. + * @returns Record keyed by user ID. + */ getMutableDMsByUserIds(): Record; + /** + * Gets mutable map of all private channels. + * @returns Record keyed by channel ID. + */ getMutablePrivateChannels(): Record; + /** Gets private channels sorted by last message. */ getSortedPrivateChannels(): Channel[]; + /** + * Gets version number for guild channels, incremented on changes. + * @param guildId Guild ID. + */ getGuildChannelsVersion(guildId: string): number; + /** Gets version number for private channels, incremented on changes. */ getPrivateChannelsVersion(): number; + /** + * Gets initial channel state for overlay rendering. + * @returns Record keyed by channel ID. + */ getInitialOverlayState(): Record; - getDebugInfo(): { - loadedGuildIds: string[]; - pendingGuildLoads: string[]; - guildSizes: string[]; - }; + /** Gets debug info about store state. */ + getDebugInfo(): ChannelStoreDebugInfo; + + /** Loads all guild and private channels from disk cache. */ + loadAllGuildAndPrivateChannelsFromDisk(): Promise; } diff --git a/packages/discord-types/src/stores/EditMessageStore.d.ts b/packages/discord-types/src/stores/EditMessageStore.d.ts new file mode 100644 index 0000000000..f66786aa5c --- /dev/null +++ b/packages/discord-types/src/stores/EditMessageStore.d.ts @@ -0,0 +1,253 @@ +import { ApplicationCommandOptionType } from "../../enums"; +import { FluxStore, Message } from ".."; + +/** Slate node type values used in the rich text editor. */ +export type SlateNodeType = + | "text" + | "line" + | "s" + | "u" + | "strong" + | "em" + | "image" + | "emoji" + | "customEmoji" + | "link" + | "url" + | "autolink" + | "highlight" + | "paragraph" + | "br" + | "newline" + | "escape" + | "spoiler" + | "blockQuote" + | "inlineCode" + | "codeBlock" + | "mention" + | "userMention" + | "channelMention" + | "channel" + | "guild" + | "attachmentLink" + | "shopLink" + | "soundboard" + | "staticRouteLink" + | "roleMention" + | "commandMention" + | "timestamp" + | "timestampMentionInput" + | "list" + | "heading" + | "subtext" + | "silentPrefix" + | "gameMention" + | "gameMentionInput" + | "textMention" + | "applicationCommandOption"; + +/** A plain text leaf node. */ +export interface SlateTextNode { + text: string; +} + +/** Base interface for Slate element nodes with children. */ +export interface SlateBaseElement { + type: string; + children: SlateNode[]; +} + +/** A line element in the editor. */ +export interface SlateLineElement extends SlateBaseElement { + type: "line"; + codeBlockState?: { + isInCodeBlock: boolean; + }; +} + +/** A block quote element. */ +export interface SlateBlockQuoteElement extends SlateBaseElement { + type: "blockQuote"; +} + +/** An emoji element. */ +export interface SlateEmojiElement extends SlateBaseElement { + type: "emoji"; + emoji: { + name: string; + src?: string; + surrogate: string; + jumboable?: boolean; + }; +} + +/** A custom emoji element. */ +export interface SlateCustomEmojiElement extends SlateBaseElement { + type: "customEmoji"; + emoji: { + emojiId: string; + name: string; + animated: boolean; + jumboable?: boolean; + }; +} + +/** A user mention element. */ +export interface SlateUserMentionElement extends SlateBaseElement { + type: "userMention"; + userId: string; +} + +/** A channel mention element. */ +export interface SlateChannelMentionElement extends SlateBaseElement { + type: "channelMention"; + channelId: string; +} + +/** A role mention element. */ +export interface SlateRoleMentionElement extends SlateBaseElement { + type: "roleMention"; + roleId: string; +} + +/** A text mention element (for @everyone, @here, etc.). */ +export interface SlateTextMentionElement extends SlateBaseElement { + type: "textMention"; + name: string; +} + +/** A soundboard element. */ +export interface SlateSoundboardElement extends SlateBaseElement { + type: "soundboard"; + guildId: string; + soundId: string; +} + +/** Timestamp format style characters. */ +export type TimestampStyle = "t" | "T" | "d" | "D" | "f" | "F" | "R"; + +/** Parsed timestamp data. */ +export interface ParsedTimestamp { + /** The Unix timestamp in seconds as a string. */ + timestamp: string; + /** The format style character. */ + format: TimestampStyle | undefined; + /** The parsed Moment.js object. */ + parsed: object; + /** The full formatted date string. */ + full: string; + /** The formatted string based on the format style. */ + formatted: string; +} + +/** A timestamp element. */ +export interface SlateTimestampElement extends SlateBaseElement { + type: "timestamp"; + parsed: ParsedTimestamp; +} + +/** A static route link element. */ +export interface SlateStaticRouteLinkElement extends SlateBaseElement { + type: "staticRouteLink"; + id: string; + itemId?: string; +} + +/** A game mention element. */ +export interface SlateGameMentionElement extends SlateBaseElement { + type: "gameMention"; + applicationId: string; +} + +/** A timestamp mention input element (while typing). */ +export interface SlateTimestampMentionInputElement extends SlateBaseElement { + type: "timestampMentionInput"; +} + +/** A game mention input element (while typing). */ +export interface SlateGameMentionInputElement extends SlateBaseElement { + type: "gameMentionInput"; +} + +/** An application command option element. */ +export interface SlateApplicationCommandOptionElement extends SlateBaseElement { + type: "applicationCommandOption"; + optionType: ApplicationCommandOptionType; +} + +/** Union of all Slate element types. */ +export type SlateElement = + | SlateLineElement + | SlateBlockQuoteElement + | SlateEmojiElement + | SlateCustomEmojiElement + | SlateUserMentionElement + | SlateChannelMentionElement + | SlateRoleMentionElement + | SlateTextMentionElement + | SlateSoundboardElement + | SlateTimestampElement + | SlateTimestampMentionInputElement + | SlateStaticRouteLinkElement + | SlateGameMentionElement + | SlateGameMentionInputElement + | SlateApplicationCommandOptionElement + | SlateBaseElement; + +/** A Slate node can be either an element or a text leaf. */ +export type SlateNode = SlateElement | SlateTextNode; + +/** The rich value representation used by Slate editor for message editing. */ +export type SlateValue = SlateLineElement[]; + +export class EditMessageStore extends FluxStore { + /** + * Gets the action source that triggered editing for a channel. + * @param channelId The channel ID. + * @returns The source string or undefined if not editing. + */ + getEditActionSource(channelId: string): string | undefined; + + /** + * Gets the message currently being edited in a channel. + * @param channelId The channel ID. + * @returns The message being edited or null if not editing. + */ + getEditingMessage(channelId: string): Message | null; + + /** + * Gets the ID of the message currently being edited in a channel. + * @param channelId The channel ID. + * @returns The message ID or undefined if not editing. + */ + getEditingMessageId(channelId: string): string | undefined; + + /** + * Gets the rich value (Slate editor format) of the editing text. + * @param channelId The channel ID. + * @returns The Slate value or undefined if not editing. + */ + getEditingRichValue(channelId: string): SlateValue | undefined; + + /** + * Gets the plain text value of the editing text. + * @param channelId The channel ID. + * @returns The text value or undefined if not editing. + */ + getEditingTextValue(channelId: string): string | undefined; + + /** + * Checks if a specific message is currently being edited. + * @param channelId The channel ID. + * @param messageId The message ID to check. + * @returns True if the specific message is being edited. + */ + isEditing(channelId: string, messageId: string): boolean; + + /** + * Checks if any message is currently being edited in a channel. + * @param channelId The channel ID. + * @returns True if any message is being edited in the channel. + */ + isEditingAny(channelId: string): boolean; +} diff --git a/packages/discord-types/src/stores/ExperimentStore.d.ts b/packages/discord-types/src/stores/ExperimentStore.d.ts new file mode 100644 index 0000000000..27152dc020 --- /dev/null +++ b/packages/discord-types/src/stores/ExperimentStore.d.ts @@ -0,0 +1,101 @@ +import { FluxStore } from ".."; + +interface ExperimentAssignmentOverride { + type: "user" | "guild"; + revision: number; + population?: number; + bucket: number; + override: boolean; +} + +interface UserExperimentAssignment { + aaMode: boolean; + assignmentSource: string; + bucket: number; + fingerprint: string | null; + hashResult: number; + holdoutBucket: number | null; + holdoutName: string | null; + holdoutRevision: number | null; + loadedFromCache: boolean; + override: boolean; + population: number; + revision: number; + sessionId: string; + triggerDebuggingEnabled: boolean; + type: string; +} + +interface GuildExperimentAssignment { + aaMode: boolean; + assignmentSource: string; + fingerprint: string | null; + hashKey: string | null; + holdoutControlBucket: number | null; + holdoutName: string | null; + loadedFromCache: boolean; + overrides: Record; + overridesFormatted: unknown[]; + populations: unknown[]; + revision: number; + sessionId: string; + triggerDebuggingEnabled: boolean; +} + +interface ExperimentDescriptor { + buckets: number[]; + commonTriggerPoint?: string; + description: string[]; + title: string; + type: "user" | "guild"; +} + +interface ExperimentExposureEntry { + time: number; + hash: number; +} + +type GuildExposureKey = `guild|${string}|${string}`; +type UserExposureKey = `user|${string}`; + +interface TrackedExposures { + [key: UserExposureKey]: ExperimentExposureEntry; + [key: GuildExposureKey]: ExperimentExposureEntry; +} + +interface ExperimentState { + assignmentFingerprint: string | null; + assignmentSessionId: string; + assignmentSource: string; + cookieOverrides: unknown; + guildExperimentOverrides: ExperimentAssignmentOverride; + hasLoadedExperiments: boolean; + loadedGuildExperiments: GuildExperimentAssignment; + loadedUserExperiments: UserExperimentAssignment; + trackedExposureExperiments: TrackedExposures; + userExperimentOverrides: ExperimentAssignmentOverride; +} + +export class ExperimentStore extends FluxStore { + hasLoadedExperiments: boolean; + persistKey: string; + getAllExperimentAssignments(): Record; + getAllExperimentOverrideDescriptors(): ExperimentAssignmentOverride; + getAllUserExperimentDescriptors(): Record; + getExperimentOverrideDescriptor(experimentId: string): ExperimentAssignmentOverride; + getGuildExperimentBucket(experimentId: string, guildId: string): number; + getGuildExperimentDescriptor(experimentId: string, guildId: string): ExperimentAssignmentOverride; + getGuildExperiments(): Record; + getLoadedGuildExperiment(experimentId: string): GuildExperimentAssignment; + getLoadedUserExperiment(experimentId: string): UserExperimentAssignment; + getRegisteredExperiments(): ExperimentDescriptor; + getSerializedState(): ExperimentState; + getUserExperimentBucket(experimentId: string): number; + getUserExperimentDescriptor(experimentId: string): ExperimentAssignmentOverride; + hasRegisteredExperiment(experimentId: string): boolean; + + // has two args + getRecentExposures(): unknown; + // has four args + hasExperimentTrackedExposure(): unknown; +} diff --git a/packages/discord-types/src/stores/FriendsStore.d.ts b/packages/discord-types/src/stores/FriendsStore.d.ts index e0611bca4f..4a1d1c71e1 100644 --- a/packages/discord-types/src/stores/FriendsStore.d.ts +++ b/packages/discord-types/src/stores/FriendsStore.d.ts @@ -5,11 +5,13 @@ export type FriendsSection = "ADD_FRIEND" | "ALL" | "ONLINE" | "PENDING" | "PEND export type StatusType = "online" | "offline" | "idle" | "dnd" | "invisible" | "streaming" | "unknown"; +export type StreamType = "call" | "guild"; + export interface ApplicationStream { channelId: string; guildId: string | null; ownerId: string; - streamType: string; + streamType: StreamType; } export interface FriendsRow { diff --git a/packages/discord-types/src/stores/GuildScheduledEventStore.d.ts b/packages/discord-types/src/stores/GuildScheduledEventStore.d.ts index 23e7977470..ea60f94bd8 100644 --- a/packages/discord-types/src/stores/GuildScheduledEventStore.d.ts +++ b/packages/discord-types/src/stores/GuildScheduledEventStore.d.ts @@ -1,5 +1,5 @@ import { FluxStore } from ".."; -import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus } from "../../enums"; +import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus, RecurrenceRuleFrequency } from "../../enums"; export interface GuildScheduledEventEntityMetadata { location?: string; @@ -8,7 +8,7 @@ export interface GuildScheduledEventEntityMetadata { export interface GuildScheduledEventRecurrenceRule { start: string; end: string | null; - frequency: number; + frequency: RecurrenceRuleFrequency; interval: number; byWeekday: number[] | null; byNWeekday: { n: number; day: number; }[] | null; diff --git a/packages/discord-types/src/stores/InviteStore.d.ts b/packages/discord-types/src/stores/InviteStore.d.ts index 9ea8f2a2e3..2f27d8cad5 100644 --- a/packages/discord-types/src/stores/InviteStore.d.ts +++ b/packages/discord-types/src/stores/InviteStore.d.ts @@ -1,4 +1,17 @@ import { Channel, FluxStore, Guild, User } from ".."; +import { Application } from "../common/Application"; +import { GuildScheduledEvent } from "./GuildScheduledEventStore"; +import { GuildScheduledEventPrivacyLevel, InviteTargetType } from "../../enums"; + +export interface StageInstance { + id: string; + guild_id: string; + channel_id: string; + topic: string; + privacy_level: GuildScheduledEventPrivacyLevel; + discoverable_disabled: boolean; + guild_scheduled_event_id: string | null; +} export interface Invite { code: string; @@ -9,12 +22,11 @@ export interface Invite { approximate_presence_count?: number; expires_at?: string | null; flags?: number; - target_type?: number; + target_type?: InviteTargetType; target_user?: User; - // TODO: type these - target_application?: any; - stage_instance?: any; - guild_scheduled_event?: any; + target_application?: Application; + stage_instance?: StageInstance; + guild_scheduled_event?: GuildScheduledEvent; } export class InviteStore extends FluxStore { diff --git a/packages/discord-types/src/stores/MediaEngineStore.d.ts b/packages/discord-types/src/stores/MediaEngineStore.d.ts index f5861bc00d..6f358164c6 100644 --- a/packages/discord-types/src/stores/MediaEngineStore.d.ts +++ b/packages/discord-types/src/stores/MediaEngineStore.d.ts @@ -675,7 +675,7 @@ export interface MediaEngineConnection { /** whether QoS is enabled. */ qos: boolean; /** current input mode. */ - inputMode: string; + inputMode: VoiceMode; /** VAD threshold in dB, default -60. */ vadThreshold: number; /** whether VAD auto threshold is enabled, default true. */ diff --git a/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts b/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts index f14342d7fe..b9c3adca4b 100644 --- a/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts +++ b/packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts @@ -1,15 +1,16 @@ import { FluxStore } from ".."; +import { PremiumType } from "../../enums"; export interface OverridePremiumTypeState { createdAtOverride: Date | undefined; - premiumTypeActual: number | null; - premiumTypeOverride: number | undefined; + premiumTypeActual: PremiumType | null; + premiumTypeOverride: PremiumType | undefined; } export class OverridePremiumTypeStore extends FluxStore { getState(): OverridePremiumTypeState; getCreatedAtOverride(): Date | undefined; - getPremiumTypeActual(): number | null; - getPremiumTypeOverride(): number | undefined; - get premiumType(): number | undefined; + getPremiumTypeActual(): PremiumType | null; + getPremiumTypeOverride(): PremiumType | undefined; + get premiumType(): PremiumType | undefined; } diff --git a/packages/discord-types/src/stores/PendingReplyStore.d.ts b/packages/discord-types/src/stores/PendingReplyStore.d.ts index 687601f10d..afbd5bb4ca 100644 --- a/packages/discord-types/src/stores/PendingReplyStore.d.ts +++ b/packages/discord-types/src/stores/PendingReplyStore.d.ts @@ -8,7 +8,14 @@ export interface PendingReply { showMentionToggle: boolean; } +interface PendingReplyState { + channelId: string; + messageId: string; + shouldMention: boolean; + showMentionToggle: boolean; +} export class PendingReplyStore extends FluxStore { + getState(): Record; getPendingReply(channelId: string): PendingReply | undefined; /** Discord doesn't use this method. Also seems to always return undefined */ getPendingReplyActionSource(channelId: string): unknown; diff --git a/packages/discord-types/src/stores/QuestStore.d.ts b/packages/discord-types/src/stores/QuestStore.d.ts new file mode 100644 index 0000000000..54ce89e78c --- /dev/null +++ b/packages/discord-types/src/stores/QuestStore.d.ts @@ -0,0 +1,738 @@ +import { + QuestDismissibleContentFlags, + QuestFeature, + QuestPlatform, + QuestPlacement, + QuestRewardAssignmentMethod, + QuestRewardExpirationMode, + QuestRewardType, + QuestTargetedContent, + QuestTaskType, + QuestHomePlacement, + QuestTranscriptFetchStatus, + QuestErrorType, + QuestSharePolicy, + QuestTaskJoinOperator, + QuestPlatformMode, +} from "../../enums"; +import { FluxStore } from "./FluxStore"; + +/** Video asset for quest tasks. */ +export interface QuestVideoAsset { + /** Video URL path relative to CDN. */ + url: string; + /** Width in pixels. */ + width: number; + /** Height in pixels. */ + height: number; + /** Thumbnail image URL. */ + thumbnail: string; + /** VTT caption file URL. */ + caption?: string; + /** Transcript file URL. */ + transcript?: string; +} + +/** Video assets for video-based quest tasks. */ +export interface QuestTaskVideoAssets { + /** Full resolution video (1080p). */ + video: QuestVideoAsset; + /** Low resolution video (720p). */ + videoLowRes?: QuestVideoAsset; + /** HLS streaming video (.m3u8). */ + videoHls?: QuestVideoAsset; +} + +/** Display messages for video-based quest tasks. */ +export interface QuestTaskVideoMessages { + videoTitle: string; +} + +/** Display messages for achievement-based quest tasks. */ +export interface QuestTaskAchievementMessages { + taskTitle: string; + taskDescription: string; +} + +/** Application reference in quest tasks. */ +export interface QuestTaskApplication { + /** Discord application ID. */ + id: string; +} + +/** Base properties shared by all quest task types. */ +interface QuestTaskBase { + /** Target value to complete (seconds for play tasks, seconds for video tasks). */ + target: number; +} + +/** Play on desktop quest task. */ +export interface QuestTaskPlayOnDesktop extends QuestTaskBase { + type: QuestTaskType.PLAY_ON_DESKTOP; + /** Applications that qualify for completion. */ + applications: QuestTaskApplication[]; +} + +/** Play on desktop v2 quest task with enhanced tracking. */ +export interface QuestTaskPlayOnDesktopV2 extends QuestTaskBase { + type: QuestTaskType.PLAY_ON_DESKTOP_V2; + applications: QuestTaskApplication[]; +} + +/** Stream on desktop quest task. */ +export interface QuestTaskStreamOnDesktop extends QuestTaskBase { + type: QuestTaskType.STREAM_ON_DESKTOP; + applications: QuestTaskApplication[]; +} + +/** Play Discord activity quest task. */ +export interface QuestTaskPlayActivity extends QuestTaskBase { + type: QuestTaskType.PLAY_ACTIVITY; + applications: QuestTaskApplication[]; +} + +/** Play on Xbox quest task. */ +export interface QuestTaskPlayOnXbox extends QuestTaskBase { + type: QuestTaskType.PLAY_ON_XBOX; + /** Xbox title IDs. */ + externalIds: string[]; + applications: QuestTaskApplication[]; +} + +/** Play on PlayStation quest task. */ +export interface QuestTaskPlayOnPlayStation extends QuestTaskBase { + type: QuestTaskType.PLAY_ON_PLAYSTATION; + /** PlayStation title IDs (e.g., "PPSA09016_00"). */ + externalIds: string[]; + applications: QuestTaskApplication[]; +} + +/** Watch video quest task for desktop. */ +export interface QuestTaskWatchVideo extends QuestTaskBase { + type: QuestTaskType.WATCH_VIDEO; + assets: QuestTaskVideoAssets; + messages: QuestTaskVideoMessages; +} + +/** Watch video quest task for mobile. */ +export interface QuestTaskWatchVideoOnMobile extends QuestTaskBase { + type: QuestTaskType.WATCH_VIDEO_ON_MOBILE; + assets: QuestTaskVideoAssets; + messages: QuestTaskVideoMessages; +} + +/** Achievement in game quest task. */ +export interface QuestTaskAchievementInGame extends QuestTaskBase { + type: QuestTaskType.ACHIEVEMENT_IN_GAME; + /** Event name dispatched when achievement is unlocked. */ + eventName: string; + messages: QuestTaskAchievementMessages; + applications: QuestTaskApplication[]; +} + +/** Achievement in Discord activity quest task. */ +export interface QuestTaskAchievementInActivity extends QuestTaskBase { + type: QuestTaskType.ACHIEVEMENT_IN_ACTIVITY; + eventName: string; + messages: QuestTaskAchievementMessages; + applications: QuestTaskApplication[]; +} + +/** Union of all quest task types. */ +export type QuestTask = + | QuestTaskPlayOnDesktop + | QuestTaskPlayOnDesktopV2 + | QuestTaskStreamOnDesktop + | QuestTaskPlayActivity + | QuestTaskPlayOnXbox + | QuestTaskPlayOnPlayStation + | QuestTaskWatchVideo + | QuestTaskWatchVideoOnMobile + | QuestTaskAchievementInGame + | QuestTaskAchievementInActivity; + +/** Task configuration for a quest. */ +export interface QuestTaskConfig { + /** Map of task type to task configuration. */ + tasks: Partial>; + /** How tasks are combined. Default is "or" (any task completes the quest). */ + joinOperator: QuestTaskJoinOperator; +} + +/** Display messages for quest rewards. */ +export interface QuestRewardMessages { + /** Redemption instructions keyed by {@link QuestPlatform}. */ + redemptionInstructionsByPlatform: Partial>; + /** Reward display name (e.g., "700 Orbs"). */ + name: string; + /** Name with article (e.g., "700 Orbs"). */ + nameWithArticle: string; +} + +/** Base properties shared by all quest reward types. */ +interface QuestRewardBase { + /** SKU ID for the reward entitlement. */ + skuId: string; + messages: QuestRewardMessages; +} + +/** Reward code reward type. */ +export interface QuestRewardCode extends QuestRewardBase { + type: QuestRewardType.REWARD_CODE; + /** Reward image URL. */ + asset?: string; + /** Reward video URL. */ + assetVideo?: string | null; + /** Approximate codes remaining, null if unlimited. */ + approximateCount?: number | null; + /** External URL to redeem the code. */ + redemptionLink?: string | null; +} + +/** In-game reward type. */ +export interface QuestRewardInGame extends QuestRewardBase { + type: QuestRewardType.IN_GAME; + asset?: string; + assetVideo?: string | null; +} + +/** Collectible avatar decoration reward type. */ +export interface QuestRewardCollectible extends QuestRewardBase { + type: QuestRewardType.COLLECTIBLE; + asset?: string; + assetVideo?: string | null; + /** ISO timestamp when collectible expires. */ + expiresAt?: string; + /** Expiration behavior. */ + expirationMode?: QuestRewardExpirationMode; + /** Extended expiration for Nitro users. */ + expiresAtPremium?: string | null; +} + +/** Virtual currency (Orbs) reward type. */ +export interface QuestRewardVirtualCurrency extends QuestRewardBase { + type: QuestRewardType.VIRTUAL_CURRENCY; + /** Number of orbs awarded. */ + orbQuantity: number; +} + +/** Fractional Nitro premium time reward type. */ +export interface QuestRewardFractionalPremium extends QuestRewardBase { + type: QuestRewardType.FRACTIONAL_PREMIUM; + asset?: string; + assetVideo?: string | null; + /** Premium time quantity. */ + quantity: number; +} + +/** Union of all quest reward types. */ +export type QuestReward = + | QuestRewardCode + | QuestRewardInGame + | QuestRewardCollectible + | QuestRewardVirtualCurrency + | QuestRewardFractionalPremium; + +/** Rewards configuration for a quest. */ +export interface QuestRewardsConfig { + /** How rewards are distributed to users. */ + assignmentMethod: QuestRewardAssignmentMethod; + /** Available reward options. */ + rewards: QuestReward[]; + /** ISO timestamp when rewards can no longer be claimed. */ + rewardsExpireAt: string; + /** Platforms where rewards can be claimed. */ + platforms: QuestPlatform[]; +} + +/** Visual assets for quest display. */ +export interface QuestAssets { + /** Hero banner image URL. */ + hero: string; + /** Hero banner video URL. */ + heroVideo: string | null; + /** Quest bar hero image URL. */ + questBarHero: string; + /** Quest bar hero video URL. */ + questBarHeroVideo: string | null; + /** Game tile image URL. */ + gameTile: string; + /** Game logotype image URL. */ + logotype: string; + /** Light theme game tile URL. */ + gameTileLight: string; + /** Dark theme game tile URL. */ + gameTileDark: string; + /** Light theme logotype URL. */ + logotypeLight: string; + /** Dark theme logotype URL. */ + logotypeDark: string; +} + +/** Color scheme for quest UI theming. */ +export interface QuestColors { + /** Primary hex color (e.g., "#4752C4"). */ + primary: string; + /** Secondary hex color. */ + secondary: string; +} + +/** Display messages for quest UI. */ +export interface QuestMessages { + /** Quest display name. */ + questName: string; + /** Game title. */ + gameTitle: string; + /** Game publisher name. */ + gamePublisher: string; +} + +/** Application reference in quest configuration. */ +export interface QuestApplication { + /** Discord application ID. */ + id: string; + /** Application display name. */ + name: string; +} + +/** Platform-specific app store configuration. */ +export interface QuestCtaPlatformConfig { + /** Android package name. */ + androidAppId?: string; + /** iOS App Store ID. */ + iosAppId?: string; +} + +/** Call-to-action button configuration. */ +export interface QuestCtaConfig { + /** CTA destination URL. */ + link: string; + /** Button label text. */ + buttonLabel: string; + /** Optional subtitle text. */ + subtitle?: string; + /** Android-specific configuration. */ + android?: QuestCtaPlatformConfig; + /** iOS-specific configuration. */ + ios?: QuestCtaPlatformConfig; +} + +/** Co-sponsor branding metadata for partnered quests. */ +export interface QuestCosponsorMetadata { + /** Co-sponsor company name. */ + name: string; + /** Logotype image URL. */ + logotype: string; + /** Redemption instructions text. */ + redemptionInstructions: string; + /** Light theme logotype URL. */ + logotypeLight: string; + /** Dark theme logotype URL. */ + logotypeDark: string; +} + +/** Complete quest configuration. */ +export interface QuestConfig { + /** Quest ID (snowflake). */ + id: string; + /** Configuration version number. */ + configVersion: number; + /** ISO timestamp when quest becomes available. */ + startsAt: string; + /** ISO timestamp when quest expires. */ + expiresAt: string; + /** Enabled feature flags for this quest. */ + features: QuestFeature[]; + /** Associated Discord application. */ + application: QuestApplication; + /** Visual assets. */ + assets: QuestAssets; + /** Color scheme. */ + colors: QuestColors; + /** Display messages. */ + messages: QuestMessages; + /** Task requirements configuration. */ + taskConfigV2: QuestTaskConfig; + /** Rewards configuration. */ + rewardsConfig: QuestRewardsConfig; + /** Optional co-sponsor branding. */ + cosponsorMetadata?: QuestCosponsorMetadata; + /** Sharing policy. */ + sharePolicy: QuestSharePolicy; + /** Call-to-action configuration. */ + ctaConfig: QuestCtaConfig; +} + +/** Heartbeat tracking for quest progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */ +export interface QuestProgressHeartbeat { + /** ISO timestamp of last heartbeat. */ + lastBeatAt: string; + /** ISO timestamp when heartbeat tracking expires. */ + expiresAt: string | null; +} + +/** Progress tracking for a single quest task. Updated via QUESTS_USER_STATUS_UPDATE. */ +export interface QuestTaskProgress { + /** Task event name matching {@link QuestTaskType}. */ + eventName: string; + /** Current progress value (seconds played/watched). */ + value: number; + /** ISO timestamp of last progress update. */ + updatedAt: string; + /** ISO timestamp when task was completed, null if incomplete. */ + completedAt: string | null; + /** Heartbeat tracking for active progress. */ + heartbeat: QuestProgressHeartbeat | null; +} + +/** User's status for a specific quest. Updated via QUESTS_USER_STATUS_UPDATE. */ +export interface QuestUserStatus { + /** User ID (snowflake). */ + userId: string; + /** Quest ID (snowflake). */ + questId: string; + /** ISO timestamp when user enrolled. */ + enrolledAt: string; + /** ISO timestamp when quest was completed, null if incomplete. */ + completedAt: string | null; + /** ISO timestamp when reward was claimed, null if unclaimed. */ + claimedAt: string | null; + /** Claimed reward tier for tiered rewards, null otherwise. */ + claimedTier: number | null; + /** ISO timestamp of last stream heartbeat. */ + lastStreamHeartbeatAt: string | null; + /** Total stream progress in seconds. */ + streamProgressSeconds: number; + /** Bitmask of dismissed UI content. */ + dismissedQuestContent: QuestDismissibleContentFlags; + /** Progress by task event name. */ + progress: Record; +} + +/** Quest object with configuration and user status. */ +export interface Quest { + /** Quest ID (snowflake). */ + id: string; + /** Whether this is a preview/test quest. */ + preview: boolean; + /** Quest configuration. */ + config: QuestConfig; + /** User's status, null if not enrolled. */ + userStatus: QuestUserStatus | null; + /** UI placements where this quest should appear. */ + targetedContent: QuestTargetedContent[]; +} + +/** Reference to an excluded quest. */ +export interface ExcludedQuest { + /** Excluded quest ID. */ + id: string; + /** Replacement quest ID to show instead. */ + replacementId: string; +} + +/** Ad tracking identifiers for quest delivery. */ +export interface QuestAdIdentifiers { + ad_id?: string; + adset_id?: string; + ad_set_id?: string; + campaign_id?: string; + creative_id?: string; + creative_type?: string; + /** Request ID from ad decision. */ + decision_id?: string; + /** Whether quest was served via targeting. */ + is_targeted: boolean; +} + +/** Quest delivery information for a placement. */ +export interface QuestDeliveryInfo { + /** Quest to deliver. */ + quest: Quest; + /** Ad tracking data. */ + adDecisionData: QuestAdIdentifiers; + /** Ad context for analytics. */ + adContext: string | null; + /** Raw metadata for ad attribution. */ + metadataRaw: string | null; + /** Sealed metadata for verification. */ + metadataSealed: string | null; +} + +/** Ad decision cache entry for quest delivery. */ +export interface QuestAdDecision { + /** Quest ID or null if no quest to deliver. */ + questId: string | null; + /** Unix timestamp when decision was fetched. */ + fetchedAt: number; + /** Cache TTL in milliseconds. Default 6 hours. */ + ttlMillis: number; + /** Ad tracking data. */ + adDecisionData: QuestAdIdentifiers; + adContext: string | null; + metadataRaw: string | null; + metadataSealed: string | null; +} + +/** Stream heartbeat failure tracking. Updated via QUESTS_SEND_HEARTBEAT_FAILURE. */ +export interface StreamHeartbeatFailure { + /** Quest ID. */ + questId: string; + /** Stream identifier. */ + streamKey: string; + /** Unix timestamp of first failure. */ + firstFailedAt: number; +} + +/** Asset for quest home takeover display. */ +export interface QuestHomeTakeoverAsset { + /** Accessibility text. */ + altText: string; + /** Asset type identifier. */ + assetType: string; + /** Asset URL. */ + url: string; +} + +/** Sponsor CTA for quest home takeover. */ +export interface QuestHomeTakeoverCtaSponsor { + ctaType: string; + title: string; + /** Sponsor destination URL. */ + url: string; +} + +/** Quest CTA for quest home takeover. */ +export interface QuestHomeTakeoverCtaQuest { + ctaType: string; + title: string; + /** Quest ID to navigate to. */ + questId: string; +} + +/** Quest home takeover banner configuration. */ +export interface QuestHomeTakeoverConfig { + placementType: QuestHomePlacement; + /** Campaign identifier. */ + campaignId: string; + labelTitle: string; + labelSubtitle: string; + /** Hero banner asset. */ + assetHeroImage: QuestHomeTakeoverAsset; + /** Sponsor logo asset. */ + assetSponsorImage: QuestHomeTakeoverAsset; + /** Sponsor link CTA. */ + ctaSponsorUrl: QuestHomeTakeoverCtaSponsor; + /** Quest navigation CTAs. */ + ctaQuests: QuestHomeTakeoverCtaQuest[]; + /** ISO timestamp when takeover starts. */ + startsAt: string; + /** ISO timestamp when takeover expires. */ + expiresAt: string; +} + +/** Claimed reward code details. Returned by QUESTS_FETCH_REWARD_CODE_SUCCESS. */ +export interface QuestClaimedRewardCode { + userId: string; + questId: string; + /** The reward code string. */ + code: string; + /** Platform the code is for. */ + platform: QuestPlatform; + /** ISO timestamp when claimed. */ + claimedAt: string; + /** Reward tier if applicable. */ + tier: number | null; +} + +/** Entitlement item from reward claim. */ +export interface QuestEntitlementItem { + /** SKU ID. */ + skuId: string; + /** Metadata containing reward details. */ + tenantMetadata: { + questRewards?: { + reward: { + tag: QuestRewardType; + rewardCode?: QuestClaimedRewardCode; + }; + }; + } | null; + /** Whether entitlement has been consumed. */ + consumed: boolean; +} + +/** Error from reward claim operation. */ +export interface QuestEntitlementError { + code?: string; + message?: string; +} + +/** Response from claiming quest rewards. Returned by QUESTS_CLAIM_REWARD_SUCCESS. */ +export interface QuestEntitlements { + /** ISO timestamp when claimed. */ + claimedAt: string; + /** Entitlement items received. */ + items: QuestEntitlementItem[]; + /** Errors encountered during claim. */ + errors: QuestEntitlementError[]; +} + +/** Video progress tracking state. */ +export interface QuestVideoProgress { + /** Current playback position in seconds. */ + timestampSec: number; + /** Total video duration in seconds. */ + duration: number; + /** Maximum position reached in seconds. */ + maxTimestampSec: number; +} + +/** Transcript asset for quest videos. */ +export interface QuestTranscriptAsset { + questId: string; + fetchStatus: QuestTranscriptFetchStatus; + /** Transcript text content when loaded. */ + text?: string; + /** Transcript file URL. */ + url?: string; +} + +/** Error hint from console quest operations. */ +export interface QuestConsoleErrorHint { + type: QuestErrorType; + /** User-facing error message. */ + message: string; + /** Connected account ID that caused the error. */ + connected_account_id: string; + /** Account type (e.g., "xbox", "playstation"). */ + connected_account_type: string; +} + +/** Computed task details for display. */ +export interface QuestTaskDetails { + taskType: QuestTaskType; + /** Target completion time in minutes. */ + targetMinutes: number; + /** Progress as decimal (0.0 to 1.0). */ + percentComplete: number; + /** Applications for this task. */ + applications?: QuestTaskApplication[]; +} + +/** Third-party task details for external quests. */ +export interface QuestThirdPartyTaskDetails { + description: string; + /** Current progress value. */ + progress: number; + /** Target completion value. */ + target: number; + /** Progress as decimal (0.0 to 1.0). */ + percentComplete: number; + title?: string; +} + +/** Store for Discord Quests data. Manages quest configs, user progress, rewards, and delivery. */ +export class QuestStore extends FluxStore { + /** All quests keyed by quest ID. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */ + get quests(): Map; + + /** Quests the user is excluded from. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */ + get excludedQuests(): Map; + + /** Quests with claimed rewards. Updated via QUESTS_FETCH_CLAIMED_QUESTS_SUCCESS. */ + get claimedQuests(): Map; + + /** Whether fetching current quests. Set via QUESTS_FETCH_CURRENT_QUESTS_BEGIN. */ + get isFetchingCurrentQuests(): boolean; + + /** Whether fetching claimed quests. Set via QUESTS_FETCH_CLAIMED_QUESTS_BEGIN. */ + get isFetchingClaimedQuests(): boolean; + + /** Unix timestamp of last current quests fetch. Default 0. */ + get lastFetchedCurrentQuests(): number; + + /** Unix timestamp of last quest-to-deliver fetch. Default 0. */ + get lastFetchedQuestToDeliver(): number; + + /** Whether fetching quest to deliver. Set via QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN. */ + get isFetchingQuestToDeliver(): boolean; + + /** Override quest for delivery testing. Set via QUESTS_DELIVERY_OVERRIDE. */ + get questDeliveryOverride(): Quest | undefined; + + /** Quest delivery info keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */ + get questToDeliverForPlacement(): Map; + + /** Date until enrollment is blocked, null if not blocked. Set via QUESTS_ENROLL_FAILURE. */ + get questEnrollmentBlockedUntil(): Date | null; + + /** Ad decision cache keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */ + get questAdDecisionByPlacement(): Map; + + /** Quest configs keyed by quest ID. */ + get questConfigs(): Map; + + /** Whether fetching preview for a quest. */ + isFetchingQuestPreview(questId: string): boolean; + + /** Whether fetching quest to deliver for a placement. */ + isFetchingQuestToDeliverByPlacement(placement: QuestPlacement): boolean; + + /** Gets preview fetch error for a quest. */ + getFetchQuestPreviewError(questId: string): QuestErrorType | undefined; + + /** Whether user is currently enrolling in a quest. Set via QUESTS_ENROLL_BEGIN. */ + isEnrolling(questId: string): boolean; + + /** Whether user is currently claiming reward for a quest. Set via QUESTS_CLAIM_REWARD_BEGIN. */ + isClaimingReward(questId: string): boolean; + + /** Whether fetching reward code for a quest. Set via QUESTS_FETCH_REWARD_CODE_BEGIN. */ + isFetchingRewardCode(questId: string): boolean; + + /** Whether dismissing content for a quest. Set via QUESTS_DISMISS_CONTENT_BEGIN. */ + isDismissingContent(questId: string): boolean; + + /** Gets claimed reward code for a quest. Updated via QUESTS_FETCH_REWARD_CODE_SUCCESS. */ + getRewardCode(questId: string): QuestClaimedRewardCode | undefined; + + /** Gets entitlement items for a quest. Updated via QUESTS_CLAIM_REWARD_SUCCESS. */ + getRewards(questId: string): QuestEntitlementItem[] | undefined; + + /** Gets stream heartbeat failure info. Cleared via STREAM_CLOSE. */ + getStreamHeartbeatFailure(streamKey: string): StreamHeartbeatFailure | undefined; + + /** Gets a quest by ID. */ + getQuest(questId: string): Quest | undefined; + + /** Gets quest config by ID. */ + getQuestConfig(questId: string): QuestConfig | undefined; + + /** Whether quest has active desktop progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */ + isProgressingOnDesktop(questId: string): boolean; + + /** Gets selected task platform for a quest. Set via QUESTS_SELECT_TASK_PLATFORM. */ + selectedTaskPlatform(questId: string): QuestPlatformMode | null; + + /** Gets optimistic progress for a task. Set via QUESTS_UPDATE_OPTIMISTIC_PROGRESS, cleared via QUESTS_RESET_OPTIMISTIC_PROGRESS. */ + getOptimisticProgress(questId: string, taskEventName: string): number | undefined; + + /** Gets map of quest IDs to expired status. Computed from quest config expiresAt. */ + getExpiredQuestsMap(): Map; + + /** Whether a quest has expired. Computed from quest config expiresAt. */ + isQuestExpired(questId: string): boolean; + + /** Gets quest loaded via preview tool. Updated via QUESTS_FETCH_PREVIEW_SUCCESS. */ + getQuestLoadedViaPreview(questId: string): Quest | undefined; + + /** Whether fetching quest home takeover config. Set via QUESTS_FETCH_QUEST_HOME_TAKEOVER_BEGIN. */ + isFetchingQuestHomeTakeover(): boolean; + + /** Gets quest home takeover config. Updated via QUESTS_FETCH_QUEST_HOME_TAKEOVER_SUCCESS. */ + getQuestHomeTakeoverConfig(): QuestHomeTakeoverConfig | null; + + /** Gets Unix timestamp of last takeover fetch, null if never fetched. */ + getLastFetchedQuestHomeTakeover(): number | null; +} diff --git a/packages/discord-types/src/stores/RTCConnectionStore.d.ts b/packages/discord-types/src/stores/RTCConnectionStore.d.ts index 588defc8d2..3dac744ae6 100644 --- a/packages/discord-types/src/stores/RTCConnectionStore.d.ts +++ b/packages/discord-types/src/stores/RTCConnectionStore.d.ts @@ -36,7 +36,8 @@ export interface VoiceStateStats { } export interface SecureFramesState { - state: string; + version: number; + epochAuthenticator: string; } export interface SecureFramesRosterMapEntry { diff --git a/packages/discord-types/src/stores/RelationshipStore.d.ts b/packages/discord-types/src/stores/RelationshipStore.d.ts index b1c24886a9..d63d094ccc 100644 --- a/packages/discord-types/src/stores/RelationshipStore.d.ts +++ b/packages/discord-types/src/stores/RelationshipStore.d.ts @@ -1,4 +1,5 @@ import { FluxStore } from ".."; +import { Message, MessageJSON } from "../common/messages"; import { RelationshipType } from "../../enums"; export class RelationshipStore extends FluxStore { @@ -24,18 +25,18 @@ export class RelationshipStore extends FluxStore { getVersion(): number; isBlocked(userId: string): boolean; - isBlockedForMessage(userId: string): boolean; + isBlockedForMessage(message: Message | MessageJSON): boolean; /** * @see {@link isBlocked} * @see {@link isIgnored} */ isBlockedOrIgnored(userId: string): boolean; - isBlockedOrIgnoredForMessage(userId: string): boolean; + isBlockedOrIgnoredForMessage(message: Message | MessageJSON): boolean; isFriend(userId: string): boolean; isIgnored(userId: string): boolean; - isIgnoredForMessage(userId: string): boolean; + isIgnoredForMessage(message: Message | MessageJSON): boolean; isSpam(userId: string): boolean; isStranger(userId: string): boolean; isUnfilteredPendingIncoming(userId: string): boolean; diff --git a/packages/discord-types/src/stores/RunningGameStore.d.ts b/packages/discord-types/src/stores/RunningGameStore.d.ts index 34b6f4960c..99b2987b09 100644 --- a/packages/discord-types/src/stores/RunningGameStore.d.ts +++ b/packages/discord-types/src/stores/RunningGameStore.d.ts @@ -21,8 +21,10 @@ export interface GameOverlayStatus { enabledOOP: boolean; } +export type SystemServiceState = "unknown" | "running" | "stopped" | "error"; + export interface SystemServiceStatus { - state: string; + state: SystemServiceState; } export class RunningGameStore extends FluxStore { diff --git a/packages/discord-types/src/stores/SpotifyStore.d.ts b/packages/discord-types/src/stores/SpotifyStore.d.ts index 7a207f92d6..64cf08c5d4 100644 --- a/packages/discord-types/src/stores/SpotifyStore.d.ts +++ b/packages/discord-types/src/stores/SpotifyStore.d.ts @@ -1,4 +1,9 @@ import { FluxStore } from ".."; +import { ActivityFlags } from "../../enums"; + +export type SpotifyDeviceType = "computer" | "smartphone" | "speaker" | "tv" | "game_console" | "automobile" | "unknown"; +export type SpotifyMediaType = "track" | "episode"; +export type SpotifyAlbumType = "album" | "single" | "compilation"; export interface SpotifyDevice { id: string; @@ -7,7 +12,7 @@ export interface SpotifyDevice { is_restricted: boolean; name: string; supports_volume: boolean; - type: string; + type: SpotifyDeviceType; volume_percent: number; } @@ -38,7 +43,7 @@ export interface SpotifyImage { export interface SpotifyAlbum { id: string; name: string; - type: string; + type: SpotifyAlbumType; image: SpotifyImage | null; } @@ -47,7 +52,7 @@ export interface SpotifyTrack { name: string; duration: number; isLocal: boolean; - type: string; + type: SpotifyMediaType; album: SpotifyAlbum; artists: SpotifyArtist[]; } @@ -55,7 +60,7 @@ export interface SpotifyTrack { export interface SpotifyPlayerState { track: SpotifyTrack; startTime: number; - context: { uri: string } | null; + context: { uri: string; } | null; } export interface SpotifyActivity { @@ -74,12 +79,12 @@ export interface SpotifyActivity { id: string; }; sync_id?: string; - flags?: number; + flags?: ActivityFlags; metadata?: { context_uri: string | undefined; album_id: string; artist_ids: string[]; - type: string; + type: SpotifyMediaType; button_urls: string[]; }; } diff --git a/packages/discord-types/src/stores/StickersStore.d.ts b/packages/discord-types/src/stores/StickersStore.d.ts index 5c0bb84cbd..639e62da0f 100644 --- a/packages/discord-types/src/stores/StickersStore.d.ts +++ b/packages/discord-types/src/stores/StickersStore.d.ts @@ -1,21 +1,57 @@ import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from ".."; +import { LoadState } from "../../enums"; export type StickerGuildMap = Map; export type StickerPackMap = Map; +export interface StickerPackMeta { + id: string; + title: string; + author?: { + name: string; + url?: string; + }; + logo: Sticker; + + dynamic?: DynamicStickerPackMeta["dynamic"]; +} + +export interface DynamicStickerPackMeta extends StickerPackMeta { + dynamic: { + version?: string; + refreshUrl: string; + authHeaders?: Record; + }; +} + +export interface StickerPack extends StickerPackMeta { + stickers: Sticker[]; +} + + +export interface StickerCategoryType { + id: string; + name: string; + iconUrl?: string; +} + +export interface StickerMetadataEntry { + type: number; + value: string; +} + export class StickersStore extends FluxStore { hasLoadedStickerPacks: boolean; isFetchingStickerPacks: boolean; isLoaded: boolean; - loadState: number; + loadState: LoadState; getAllGuildStickers(): StickerGuildMap; getAllPackStickers(): StickerPackMap; getPremiumPacks(): PremiumStickerPack[]; getRawStickersByGuild(): StickerGuildMap; getStickerById(id: string): Sticker | undefined; - // TODO: type - getStickerMetadataArrays(): any[]; + getStickerMetadataArrays(): [Record, Record]; getStickerPack(id: string): PremiumStickerPack | undefined; getStickersByGuildId(guildId: string): Sticker[] | undefined; isPremiumPack(id: string): boolean; diff --git a/packages/discord-types/src/stores/UserAffinitiesStore.d.ts b/packages/discord-types/src/stores/UserAffinitiesStore.d.ts new file mode 100644 index 0000000000..d81209bf27 --- /dev/null +++ b/packages/discord-types/src/stores/UserAffinitiesStore.d.ts @@ -0,0 +1,33 @@ +import { FluxStore } from ".."; + +interface UserAffinity { + otherUserId: string; + userSegment: string; + otherUserSegment: string; + isFriend: boolean; + dmProbability: number; + dmRank: number; + vcProbability: number; + vcRank: number; + serverMessageProbability: number; + serverMessageRank: number; + communicationProbability: number; + communicationRank: number; +} + +interface UserAffinitiesResponse { + lastFetched: number; + userAffinities: UserAffinity[]; +} + +export class UserAffinitiesStore extends FluxStore { + compare(firstUserId: string, secondUserId: string): number; + compareByDmProbability(firstUserId: string, secondUserId: string): number; + getState(): UserAffinitiesResponse; + getUserAffinities(): UserAffinity[]; + getUserAffinitiesMap(): Map; + getUserAffinity(userId: string): UserAffinity; + isFetching(): boolean; + isHighlyAffinedVCUser(userId: string): boolean; + shouldFetch(): boolean; +} diff --git a/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts b/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts index e7f0059220..9e5e03873e 100644 --- a/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts +++ b/packages/discord-types/src/stores/UserGuildSettingsStore.d.ts @@ -1,4 +1,5 @@ -import { Channel, FluxStore } from ".."; +import { Channel, FluxStore, Guild } from ".."; +import { ChannelOverrideFlags, GuildSettingsFlags, NotifyHighlights, UserNotificationSetting } from "../../enums"; export interface MuteConfig { selected_time_window: number; @@ -8,8 +9,8 @@ export interface MuteConfig { export interface ChannelOverride { muted: boolean; mute_config: MuteConfig | null; - message_notifications: number; - flags: number; + message_notifications: UserNotificationSetting; + flags: ChannelOverrideFlags; collapsed: boolean; channel_id: string; } @@ -20,10 +21,10 @@ export interface GuildSettings { mute_scheduled_events: boolean; mobile_push: boolean; muted: boolean; - message_notifications: number; - flags: number; + message_notifications: UserNotificationSetting; + flags: GuildSettingsFlags; channel_overrides: Record; - notify_highlights: number; + notify_highlights: NotifyHighlights; hide_muted_channels: boolean; version: number; mute_config: MuteConfig | null; @@ -43,26 +44,26 @@ export class UserGuildSettingsStore extends FluxStore { get mentionOnAllMessages(): boolean; get useNewNotifications(): boolean; - allowAllMessages(guildId: string): boolean; - allowNoMessages(guildId: string): boolean; + allowAllMessages(channel: Channel): boolean; + allowNoMessages(channel: Channel): boolean; getAddedToMessages(): string[]; // TODO: finish typing getAllSettings(): { userGuildSettings: Record; }; - getChannelFlags(channel: Channel): number; - getChannelIdFlags(guildId: string, channelId: string): number; - getChannelMessageNotifications(guildId: string, channelId: string): number | null; + getChannelFlags(channel: Channel): ChannelOverrideFlags; + getChannelIdFlags(guildId: string, channelId: string): ChannelOverrideFlags; + getChannelMessageNotifications(guildId: string, channelId: string): UserNotificationSetting | null; getChannelMuteConfig(guildId: string, channelId: string): MuteConfig | null; getChannelOverrides(guildId: string): Record; getChannelRecordUnreadSetting(channel: Channel): number; getChannelUnreadSetting(guildId: string, channelId: string): number; getGuildFavorites(guildId: string): string[]; - getGuildFlags(guildId: string): number; + getGuildFlags(guildId: string): GuildSettingsFlags; getGuildUnreadSetting(guildId: string): number; - getMessageNotifications(guildId: string): number; + getMessageNotifications(guildId: string): UserNotificationSetting; getMuteConfig(guildId: string): MuteConfig | null; getMutedChannels(guildId: string): string[]; - getNewForumThreadsCreated(guildId: string): boolean; - getNotifyHighlights(guildId: string): number; + getNewForumThreadsCreated(channel: Channel): boolean; + getNotifyHighlights(guildId: string): NotifyHighlights; getOptedInChannels(guildId: string): string[]; // TODO: finish typing these getOptedInChannelsWithPendingUpdates(guildId: string): Record; @@ -85,7 +86,7 @@ export class UserGuildSettingsStore extends FluxStore { isSuppressEveryoneEnabled(guildId: string): boolean; isSuppressRolesEnabled(guildId: string): boolean; isTemporarilyMuted(guildId: string): boolean; - resolveGuildUnreadSetting(guildId: string): number; + resolveGuildUnreadSetting(guild: Guild): number; resolveUnreadSetting(channel: Channel): number; - resolvedMessageNotifications(guildId: string): number; + resolvedMessageNotifications(channel: Channel): UserNotificationSetting; } diff --git a/packages/discord-types/src/stores/UserProfileStore.d.ts b/packages/discord-types/src/stores/UserProfileStore.d.ts index cdbbe3d576..84929d60be 100644 --- a/packages/discord-types/src/stores/UserProfileStore.d.ts +++ b/packages/discord-types/src/stores/UserProfileStore.d.ts @@ -1,5 +1,5 @@ -import { FluxStore, Guild, User, Application, ApplicationInstallParams } from ".."; -import { ApplicationIntegrationType } from "../../enums"; +import { FluxStore, Guild, User, Application, ApplicationInstallParams, ProfileEffect } from ".."; +import { ApplicationFlags, ApplicationIntegrationType } from "../../enums"; export interface MutualFriend { /** @@ -54,7 +54,7 @@ export interface ProfileApplication { id: string; customInstallUrl: string | undefined; installParams: ApplicationInstallParams | undefined; - flags: number; + flags: ApplicationFlags; popularApplicationCommandIds?: string[]; integrationTypesConfig: Record { */ badges: ProfileBadge[]; bio: string | undefined; + collectibles: ProfileEffect[]; popoutAnimationParticleType: string | null; profileEffectExpiresAt: number | Date | undefined; profileEffectId: undefined | string; + profileEffect: ProfileEffect; /** * often an empty string when not set */ diff --git a/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts b/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts index 9aaf8dd14a..66b02352d4 100644 --- a/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts +++ b/packages/discord-types/src/stores/UserSettingsProtoStore.d.ts @@ -1,4 +1,7 @@ import { FluxStore } from ".."; +import { StickerAnimationSetting, Theme, UIDensity } from "../../enums"; + +export type UserStatus = "online" | "idle" | "dnd" | "invisible"; export interface GuildFolder { guildIds: string[]; @@ -68,7 +71,7 @@ export interface TextAndImagesSettings { renderEmbeds: boolean; renderReactions: boolean; animateEmoji: boolean; - animateStickers: number; + animateStickers: StickerAnimationSetting; enableTtsCommand: boolean; messageDisplayCompact: boolean; explicitContentFilter: number; @@ -122,7 +125,7 @@ export interface GameLibrarySettings { export interface StatusSettings { statusExpiresAtMs: string; - status: { status: string; } | null; + status: { value: UserStatus; } | null; showCurrentGame: boolean; statusCreatedAtMs: string; } @@ -133,12 +136,12 @@ export interface LocalizationSettings { } export interface AppearanceSettings { - theme: number; + theme: Theme; developerMode: boolean; mobileRedesignDisabled: boolean; timestampHourCycle: number; launchPadMode: number; - uiDensity: number; + uiDensity: UIDensity; swipeRightToLeftMode: number; // TODO: type clientThemeSettings: any; diff --git a/packages/discord-types/src/stores/VoiceStateStore.d.ts b/packages/discord-types/src/stores/VoiceStateStore.d.ts index 51724cd267..95e917f942 100644 --- a/packages/discord-types/src/stores/VoiceStateStore.d.ts +++ b/packages/discord-types/src/stores/VoiceStateStore.d.ts @@ -10,6 +10,7 @@ export interface VoiceState extends DiscordRecord { sessionId: string | null | undefined; mute: boolean; deaf: boolean; + stream: boolean; selfMute: boolean; selfDeaf: boolean; selfVideo: boolean; @@ -20,6 +21,9 @@ export interface VoiceState extends DiscordRecord { isVoiceMuted(): boolean; isVoiceDeafened(): boolean; + + oldChannelId?: string; + guildId?: string; } export class VoiceStateStore extends FluxStore { diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts index 366467f1ae..ba6c0aa5c0 100644 --- a/packages/discord-types/src/stores/index.d.ts +++ b/packages/discord-types/src/stores/index.d.ts @@ -1,13 +1,16 @@ // please keep in alphabetical order export * from "./AccessibilityStore"; export * from "./ActiveJoinedThreadsStore"; +export * from "./ApplicationCommandIndexStore"; export * from "./ApplicationStore"; export * from "./AuthenticationStore"; export * from "./CallStore"; export * from "./ChannelRTCStore"; export * from "./ChannelStore"; export * from "./DraftStore"; +export * from "./EditMessageStore"; export * from "./EmojiStore"; +export * from "./ExperimentStore"; export * from "./FluxStore"; export * from "./FriendsStore"; export * from "./GuildChannelStore"; @@ -27,6 +30,7 @@ export * from "./PendingReplyStore"; export * from "./PermissionStore"; export * from "./PopoutWindowStore"; export * from "./PresenceStore"; +export * from "./QuestStore"; export * from "./ReadStateStore"; export * from "./RelationshipStore"; export * from "./RTCConnectionStore"; @@ -41,6 +45,7 @@ export * from "./StreamerModeStore"; export * from "./ThemeStore"; export * from "./TypingStore"; export * from "./UploadAttachmentStore"; +export * from "./UserAffinitiesStore"; export * from "./UserGuildSettingsStore"; export * from "./UserProfileStore"; export * from "./UserSettingsProtoStore"; diff --git a/packages/discord-types/src/utils.d.ts b/packages/discord-types/src/utils.d.ts index e17844f4f9..1dbebbb26d 100644 --- a/packages/discord-types/src/utils.d.ts +++ b/packages/discord-types/src/utils.d.ts @@ -3,6 +3,7 @@ import type { ReactNode } from "react"; import { LiteralUnion } from "type-fest"; import type { FluxEvents } from "./fluxEvents"; +import { ApplicationCommandOptionType, ChannelType, PremiumType } from "../enums"; export { FluxEvents }; @@ -10,7 +11,9 @@ type FluxEventsAutoComplete = LiteralUnion; export interface FluxDispatcher { _actionHandlers: any; + _interceptors: any; _subscriptions: any; + addInterceptor(interceptor: any): void; dispatch(event: { [key: string]: unknown; type: FluxEventsAutoComplete; }): Promise; isDispatching(): boolean; subscribe(event: FluxEventsAutoComplete, callback: (data: any) => void): void; @@ -22,14 +25,30 @@ export type Parser = Record< | "parse" | "parseTopic" | "parseEmbedTitle" + | "parseEmbedTitleWithoutLinks" | "parseInlineReply" | "parseGuildVerificationFormRule" | "parseGuildEventDescription" | "parseAutoModerationSystemMessage" | "parseForumPostGuidelines" - | "parseForumPostMostRecentMessage", + | "parseForumPostMostRecentMessage" + | "parseVoiceChannelStatus", (content: string, inline?: boolean, state?: Record) => ReactNode[] -> & Record<"defaultRules" | "guildEventRules", Record>>; +> & Record< + | "parseToAST" + | "parseTopicToAST" + | "parseEmbedTitleToAST" + | "parseEmbedTitleWithoutLinksToAST" + | "parseInlineReplyToAST" + | "parseAutoModerationSystemMessageToAST", + (content: string, inline?: boolean, state?: Record) => any[] +> & Record<"defaultRules" | "guildEventRules" | "notifCenterV2MessagePreviewRules" | "lockscreenWidgetMessageRules", Record>> & { + reactParserFor(rules: Record): (content: string, inline?: boolean, state?: Record) => ReactNode[]; + astParserFor(rules: Record): (content: string, inline?: boolean, state?: Record) => any[]; + createReactRules(options: Record): Record; + defaultReactRuleOptions: Record; + combineAndInjectMentionRule(rules: Record, mentionRule: Record): Record; +}; export interface Alerts { show(alert: { @@ -45,16 +64,39 @@ export interface Alerts { onConfirmSecondary?(): void; onCloseCallback?(): void; }): void; + confirm(alert: { + title: any; + body: React.ReactNode; + className?: string; + confirmColor?: string; + cancelText?: string; + confirmText?: string; + secondaryConfirmText?: string; + onCancel?(): void; + onConfirmSecondary?(): void; + onCloseCallback?(): void; + }): Promise; /** This is a noop, it does nothing. */ close(): void; } export interface SnowflakeUtils { fromTimestamp(timestamp: number): string; + fromTimestampWithSequence(timestamp: number, sequence: number): string; extractTimestamp(snowflake: string): number; age(snowflake: string): number; atPreviousMillisecond(snowflake: string): string; + atNextMillisecond(snowflake: string): string; compare(snowflake1?: string, snowflake2?: string): number; + isProbablyAValidSnowflake(snowflake: string): boolean; + castChannelIdAsMessageId(channelId: string): string; + castMessageIdAsChannelId(messageId: string): string; + castGuildIdAsEveryoneGuildRoleId(guildId: string): string; + cast(snowflake: string): string; + keys(obj: Record): string[]; + forEach(obj: Record, callback: (value: any, key: string) => void): void; + forEachKey(obj: Record, callback: (key: string) => void): void; + entries(obj: Record): [string, any][]; } interface RestRequestData { @@ -84,6 +126,8 @@ export type Permissions = "CREATE_INSTANT_INVITE" | "VIEW_GUILD_ANALYTICS" | "VIEW_CREATOR_MONETIZATION_ANALYTICS" | "MODERATE_MEMBERS" + | "USE_EMBEDDED_ACTIVITIES" + | "USE_EXTERNAL_APPS" | "SEND_MESSAGES" | "SEND_TTS_MESSAGES" | "MANAGE_MESSAGES" @@ -100,6 +144,9 @@ export type Permissions = "CREATE_INSTANT_INVITE" | "USE_EXTERNAL_STICKERS" | "SEND_MESSAGES_IN_THREADS" | "SEND_VOICE_MESSAGES" + | "SEND_POLLS" + | "PIN_MESSAGES" + | "BYPASS_SLOWMODE" | "CONNECT" | "SPEAK" | "MUTE_MEMBERS" @@ -108,9 +155,9 @@ export type Permissions = "CREATE_INSTANT_INVITE" | "USE_VAD" | "PRIORITY_SPEAKER" | "STREAM" - | "USE_EMBEDDED_ACTIVITIES" | "USE_SOUNDBOARD" | "USE_EXTERNAL_SOUNDS" + | "SET_VOICE_CHANNEL_STATUS" | "REQUEST_TO_SPEAK" | "MANAGE_EVENTS" | "CREATE_EVENTS"; @@ -156,7 +203,7 @@ export interface IconUtils { getUserAvatarURL(user: User, canAnimate?: boolean, size?: number, format?: string): string; getDefaultAvatarURL(id: string, discriminator?: string): string; getUserBannerURL(data: { id: string, banner: string, canAnimate?: boolean, size: number; }): string | undefined; - getAvatarDecorationURL(dara: { avatarDecoration: string, size: number; canCanimate?: boolean; }): string | undefined; + getAvatarDecorationURL(data: { avatarDecoration: string, size: number; canCanimate?: boolean; }): string | undefined; getGuildMemberAvatarURL(member: GuildMember, canAnimate?: string): string | null; getGuildMemberAvatarURLSimple(data: { guildId: string, userId: string, avatar: string, canAnimate?: boolean; size?: number; }): string; @@ -241,45 +288,55 @@ export interface UsernameUtils { useName(user: User): string; getUserTag(user: User, options?: UserNameUtilsTagOptions): string; useUserTag(user: User, options?: UserNameUtilsTagOptions): string; - - + isNameConcealed(user: User): boolean; + getUserIsStaff(user: User): boolean; useDirectMessageRecipient: any; humanizeStatus: any; } -// TODO: fix type export class DisplayProfile { userId: string; + guildId?: string; banner?: string; bio?: string; pronouns?: string; accentColor?: number; themeColors?: number[]; + profileEffect?: any; popoutAnimationParticleType?: any; - profileEffectId?: string; + fetchStartedAt?: Date | null; + fetchEndedAt?: Date | null; _userProfile?: any; _guildMemberProfile?: any; - canUsePremiumProfileCustomization: boolean; - canEditThemes: boolean; - premiumGuildSince: Date | null; - premiumSince: Date | null; - premiumType?: number; - primaryColor?: number; + get premiumSince(): Date | null; + get premiumGuildSince(): Date | null; + get premiumType(): PremiumType | undefined; + get private(): boolean; + get widgets(): any[] | undefined; + get gameWidgets(): any[] | undefined; + get primaryColor(): number | undefined; + get canUsePremiumProfileCustomization(): boolean; + get canEditThemes(): boolean; + get application(): any; + get isLoaded(): boolean; + + hasThemeColors(): boolean; + hasPremiumCustomization(): boolean; + isUsingGuildMemberBanner(): boolean; + isUsingGuildMemberBio(): boolean; + isUsingGuildMemberPronouns(): boolean; + getBannerURL(options: { canAnimate: boolean; size: number; }): string; + getPreviewBanner(banner: string | null, canAnimate: boolean, size?: number): string | null; + getPreviewBio(bio: string | undefined): string | undefined; + getPreviewThemeColors(themeColors: number[] | undefined): number[] | undefined; getBadges(): Array<{ id: string; description: string; icon: string; link?: string; }>; - getBannerURL(options: { canAnimate: boolean; size: number; }): string; getLegacyUsername(): string | null; - hasFullProfile(): boolean; - hasPremiumCustomization(): boolean; - hasThemeColors(): boolean; - isUsingGuildMemberBanner(): boolean; - isUsingGuildMemberBio(): boolean; - isUsingGuildMemberPronouns(): boolean; } export interface DisplayProfileUtils { @@ -295,7 +352,7 @@ export interface DateUtils { } export interface CommandOptions { - type: number; + type: ApplicationCommandOptionType; name: string; description: string; required?: boolean; @@ -304,8 +361,56 @@ export interface CommandOptions { values: string | number; }[]; options?: CommandOptions[]; - channel_types?: number[]; + channel_types?: ChannelType[]; min_value?: number; max_value?: number; autocomplete?: boolean; } + +export interface URLUtils { + URL_REGEX: RegExp; + makeUrl(url: string): URL | null; + isDiscordUrl(url: string): boolean; + isDiscordCdnUrl(url: string): boolean; + isDiscordAssetUrl(url: string, proxyUrl?: string, originalUrl?: string): boolean; + isDiscordDirectAssetUrl(url: string): boolean; + isDiscordProxiedAssetUrl(url: string, proxyUrl?: string, originalUrl?: string): boolean; + isDiscordHostname(hostname: string): boolean; + isDiscordLocalhost(hostname: string): boolean; + isDiscordProtocol(url: string): boolean; + isDiscordUri(url: string): boolean; + isDiscordUrlOrUri(url: string): boolean; + isAllowedGifProviderUrl(url: string): boolean; + isAppRoute(url: string): boolean; + isOriginalContentTypeDifferent(url: string, proxyUrl: string): boolean; + toURLSafe(url: string): URL | null; + safeDecodeURIComponent(component: string): string; + safeParseWithQuery(url: string): URL | null; + format(url: URL): string; + formatPathWithQuery(path: string, query: Record): string; + formatSearch(query: Record): string; +} + +export interface Humanize { + filesize(bytes: number, base?: number, decimals?: number, decimalSep?: string, thousandsSep?: string, suffix?: string): string; + intword(number: number, units?: string[], base?: number, decimals?: number, decimalSep?: string, thousandsSep?: string): string; + relativeTime(timestamp?: number): string; + naturalDay(timestamp?: number, format?: string): string; + ordinal(value: number): string; + numberFormat(number: number, decimals?: number, decimalSep?: string, thousandsSep?: string): string; + truncatechars(str: string, maxLength: number): string; + truncatewords(str: string, maxWords: number): string; + pad(str: string, length: number, padChar?: string, direction?: "left" | "right"): string; + date(format: string, timestamp?: Date | number): string; + time(): number; + linebreaks(str: string): string; + nl2br(str: string): string; +} + +export interface EmojiUtils { + getEmojiColors(emoji: any): number[] | null; + getURL(emoji: any): string; + filterUnsupportedEmojis(emojis: any[]): any[]; + triggerFullscreenAnimation(emoji: any, node: HTMLElement): void; + applyPlatformToThemedEmojiColorPalette(colors: any): any; +} diff --git a/src/plugins/implicitRelationships/index.ts b/src/plugins/implicitRelationships/index.ts index 2987f14d53..9e0a3e2345 100644 --- a/src/plugins/implicitRelationships/index.ts +++ b/src/plugins/implicitRelationships/index.ts @@ -20,12 +20,9 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType } from "@utils/types"; -import { findStoreLazy } from "@webpack"; -import { Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common"; +import { Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserAffinitiesStore, UserStore } from "@webpack/common"; import { Settings } from "Vencord"; -const UserAffinitiesStore = findStoreLazy("UserAffinitiesV2Store"); - export default definePlugin({ name: "ImplicitRelationships", description: "Shows your implicit relationships in the Friends tab.", diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 31d552f8a1..9750f2800e 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -80,6 +80,11 @@ export let LocaleStore: t.LocaleStore; export let RTCConnectionStore: t.RTCConnectionStore; export let SoundboardStore: t.SoundboardStore; export let PopoutWindowStore: t.PopoutWindowStore; +export let ApplicationCommandIndexStore: t.ApplicationCommandIndexStore; +export let EditMessageStore: t.EditMessageStore; +export let QuestStore: t.QuestStore; +export let ExperimentStore: t.ExperimentStore; +export let UserAffinitiesStore: t.UserAffinitiesStore; /** * @see jsdoc of {@link t.useStateFromStores} @@ -132,6 +137,11 @@ waitForStore("RTCConnectionStore", m => RTCConnectionStore = m); waitForStore("SoundboardStore", m => SoundboardStore = m); waitForStore("PopoutWindowStore", m => PopoutWindowStore = m); waitForStore("PendingReplyStore", m => PendingReplyStore = m); +waitForStore("ApplicationCommandIndexStore", m => ApplicationCommandIndexStore = m); +waitForStore("EditMessageStore", m => EditMessageStore = m); +waitForStore("ExperimentStore", m => ExperimentStore = m); +waitForStore("QuestStore", m => QuestStore = m); +waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m); waitForStore("ThemeStore", m => { ThemeStore = m; // Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies. From bf180bbba3ab2dd9b588e3753c16db84497343e8 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:53:26 -0400 Subject: [PATCH 02/14] "He's dead, Jim" - Discord Remix --- packages/discord-types/src/modules/CloudUpload.d.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/discord-types/src/modules/CloudUpload.d.ts b/packages/discord-types/src/modules/CloudUpload.d.ts index ecd525a5a2..1a2aceceea 100644 --- a/packages/discord-types/src/modules/CloudUpload.d.ts +++ b/packages/discord-types/src/modules/CloudUpload.d.ts @@ -16,7 +16,6 @@ export interface ReactNativeUploadItem extends BaseUploadItem { mimeType?: string; durationSecs?: number; waveform?: string; - isRemix?: boolean; } export interface WebUploadItem extends BaseUploadItem { @@ -41,7 +40,6 @@ export class CloudUpload extends EventEmitter { filename: string; id: string; isImage: boolean; - isRemix: boolean | undefined; isThumbnail: boolean; isVideo: boolean; item: { From 137b8c6b44b3efe364371298bb2713f407034916 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:59:47 -0400 Subject: [PATCH 03/14] fix lint --- .../components/RolesAndUsersPermissions.tsx | 33 ++++++------------- src/plugins/permissionsViewer/index.tsx | 14 ++++---- .../components/HiddenChannelLockScreen.tsx | 27 +++------------ 3 files changed, 22 insertions(+), 52 deletions(-) diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index bfbc509ae1..c77c7c7061 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -23,27 +23,14 @@ import { cl, getGuildPermissionSpecMap } from "@plugins/permissionsViewer/utils" import { copyToClipboard } from "@utils/clipboard"; import { getIntlMessage, getUniqueUsername } from "@utils/discord"; import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { Guild, Role, UnicodeEmoji, User } from "@vencord/discord-types"; +import { Guild, Role, RoleOrUserPermission, UnicodeEmoji, User } from "@vencord/discord-types"; +import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { findByCodeLazy } from "@webpack"; import { ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildRoleStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, useMemo, UserStore, useState, useStateFromStores } from "@webpack/common"; import { settings } from ".."; import { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from "./icons"; -export const enum PermissionType { - Role = 0, - User = 1, - Owner = 2 -} - -export interface RoleOrUserPermission { - type: PermissionType; - id?: string; - permissions?: bigint; - overwriteAllow?: bigint; - overwriteDeny?: bigint; -} - type GetRoleIconData = (role: Role, size: number) => { customIconSrc?: string; unicodeEmoji?: UnicodeEmoji; }; const getRoleIconData: GetRoleIconData = findByCodeLazy("convertSurrogateToName", "customIconSrc", "unicodeEmoji"); @@ -71,7 +58,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea useEffect(() => { const usersToRequest = permissions - .filter(p => p.type === PermissionType.User && !GuildMemberStore.isMember(guild.id, p.id!)) + .filter(p => p.type === PermissionOverwriteType.MEMBER && !GuildMemberStore.isMember(guild.id, p.id!)) .map(({ id }) => id); FluxDispatcher.dispatch({ @@ -122,7 +109,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
{ - if (permission.type === PermissionType.Role) + if (permission.type === PermissionOverwriteType.ROLE) ContextMenuApi.openContextMenu(e, () => ( )); - else if (permission.type === PermissionType.User) { + else if (permission.type === PermissionOverwriteType.MEMBER) { ContextMenuApi.openContextMenu(e, () => ( - {(permission.type === PermissionType.Role || permission.type === PermissionType.Owner) && ( + {(permission.type === PermissionOverwriteType.ROLE || permission.type === PermissionOverwriteType.OWNER) && ( )} - {permission.type === PermissionType.Role && roleIconSrc != null && ( + {permission.type === PermissionOverwriteType.ROLE && roleIconSrc != null && ( )} - {permission.type === PermissionType.User && user != null && ( + {permission.type === PermissionOverwriteType.MEMBER && user != null && ( { - permission.type === PermissionType.Role + permission.type === PermissionOverwriteType.ROLE ? role?.name ?? "Unknown Role" - : permission.type === PermissionType.User + : permission.type === PermissionOverwriteType.MEMBER ? (user != null && getUniqueUsername(user)) ?? "Unknown User" : ( diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx index 37e68a5f17..8c8c8f73aa 100644 --- a/src/plugins/permissionsViewer/index.tsx +++ b/src/plugins/permissionsViewer/index.tsx @@ -26,11 +26,12 @@ import { TooltipContainer } from "@components/TooltipContainer"; import { Devs } from "@utils/constants"; import { classes } from "@utils/misc"; import definePlugin, { OptionType } from "@utils/types"; -import type { Guild } from "@vencord/discord-types"; +import type { Guild, RoleOrUserPermission } from "@vencord/discord-types"; +import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { findCssClassesLazy } from "@webpack"; import { Button, ChannelStore, Dialog, GuildMemberStore, GuildRoleStore, GuildStore, match, Menu, PermissionsBits, Popout, useRef, UserStore } from "@webpack/common"; -import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "./components/RolesAndUsersPermissions"; +import openRolesAndUsersPermissionsModal from "./components/RolesAndUsersPermissions"; import UserPermissions from "./components/UserPermissions"; import { getSortedRolesForMember, sortPermissionOverwrites } from "./utils"; @@ -75,13 +76,13 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { const permissions: RoleOrUserPermission[] = getSortedRolesForMember(guild, member) .map(role => ({ - type: PermissionType.Role, + type: PermissionOverwriteType.ROLE, ...role })); if (guild.ownerId === id) { permissions.push({ - type: PermissionType.Owner, + type: PermissionOverwriteType.OWNER, permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n) }); } @@ -95,7 +96,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { const channel = ChannelStore.getChannel(id!); const permissions = sortPermissionOverwrites(Object.values(channel.permissionOverwrites).map(({ id, allow, deny, type }) => ({ - type: type as PermissionType, + type, id, overwriteAllow: allow, overwriteDeny: deny @@ -108,7 +109,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { }) .otherwise(() => { const permissions = GuildRoleStore.getSortedRoles(guild.id).map(role => ({ - type: PermissionType.Role, + type: PermissionOverwriteType.ROLE, ...role })); @@ -143,7 +144,6 @@ function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentT .with(MenuItemParentType.Guild, () => MenuItem(props.guild.id)) .otherwise(() => null); - if (item == null) return; if (group) { diff --git a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx index bb7a361fe8..9850a75142 100644 --- a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx +++ b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx @@ -20,11 +20,11 @@ import { isPluginEnabled } from "@api/PluginManager"; import { Settings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import PermissionsViewerPlugin from "@plugins/permissionsViewer"; -import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "@plugins/permissionsViewer/components/RolesAndUsersPermissions"; +import openRolesAndUsersPermissionsModal from "@plugins/permissionsViewer/components/RolesAndUsersPermissions"; import { sortPermissionOverwrites } from "@plugins/permissionsViewer/utils"; import { classes } from "@utils/misc"; import { formatDuration } from "@utils/text"; -import type { Channel } from "@vencord/discord-types"; +import type { Channel, RoleOrUserPermission } from "@vencord/discord-types"; import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack"; import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common"; @@ -46,22 +46,6 @@ interface DefaultReaction { emojiName: string | null; } -interface Tag { - id: string; - name: string; - emojiId: string | null; - emojiName: string | null; - moderated: boolean; -} - -interface ExtendedChannel extends Channel { - defaultThreadRateLimitPerUser?: number; - defaultSortOrder?: SortOrderTypes | null; - defaultForumLayout?: ForumLayoutTypes; - defaultReactionEmoji?: DefaultReaction | null; - availableTags?: Array; -} - const enum ChannelTypes { GUILD_TEXT = 0, GUILD_VOICE = 2, @@ -80,7 +64,6 @@ const enum ChannelFlags { REQUIRE_TAG = 1 << 4 } - const ChatScrollClasses = findCssClassesLazy("auto", "managedReactiveScroller", "customTheme"); const ChannelBeginHeader = findComponentByCodeLazy("#{intl::ROLE_REQUIRED_SINGLE_USER_MESSAGE}"); const TagComponent = findComponentByCodeLazy("#{intl::FORUM_TAG_A11Y_FILTER_BY_TAG}"); @@ -115,7 +98,7 @@ const VideoQualityModesToNames = { // Icon from the modal when clicking a message link you don't have access to view const HiddenChannelLogo = "/assets/433e3ec4319a9d11b0cbe39342614982.svg"; -function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) { +function HiddenChannelLockScreen({ channel }: { channel: Channel; }) { const { defaultAllowedUsersAndRolesDropdownState } = settings.use(["defaultAllowedUsersAndRolesDropdownState"]); const [permissions, setPermissions] = useState([]); @@ -142,7 +125,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) { useEffect(() => { const membersToFetch: Array = []; - const guildOwnerId = GuildStore.getGuild(guild_id).ownerId; + const guildOwnerId = GuildStore.getGuild(guild_id)?.ownerId; if (!GuildMemberStore.getMember(guild_id, guildOwnerId)) membersToFetch.push(guildOwnerId); Object.values(permissionOverwrites).forEach(({ type, id: userId }) => { @@ -161,7 +144,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) { if (Settings.plugins.PermissionsViewer.enabled) { setPermissions(sortPermissionOverwrites(Object.values(permissionOverwrites).map(overwrite => ({ - type: overwrite.type as PermissionType, + type: overwrite.type, id: overwrite.id, overwriteAllow: overwrite.allow, overwriteDeny: overwrite.deny From 09fc3b2793caf2c7e9b2c454a75d4fe45be4d138 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 14 Mar 2026 23:01:58 -0400 Subject: [PATCH 04/14] Update UserPermissions.tsx --- .../permissionsViewer/components/UserPermissions.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/permissionsViewer/components/UserPermissions.tsx b/src/plugins/permissionsViewer/components/UserPermissions.tsx index 3b0c1f30b3..6804899794 100644 --- a/src/plugins/permissionsViewer/components/UserPermissions.tsx +++ b/src/plugins/permissionsViewer/components/UserPermissions.tsx @@ -21,12 +21,13 @@ import { HeadingTertiary } from "@components/Heading"; import { cl, getGuildPermissionSpecMap, getSortedRolesForMember, sortUserRoles } from "@plugins/permissionsViewer/utils"; import { getIntlMessage } from "@utils/discord"; import { classes } from "@utils/misc"; -import type { Guild, GuildMember } from "@vencord/discord-types"; +import type { Guild, GuildMember, RoleOrUserPermission } from "@vencord/discord-types"; +import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { findCssClassesLazy } from "@webpack"; import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common"; import { PermissionsSortOrder, settings } from ".."; -import openRolesAndUsersPermissionsModal, { PermissionType, type RoleOrUserPermission } from "./RolesAndUsersPermissions"; +import openRolesAndUsersPermissionsModal from "./RolesAndUsersPermissions"; interface UserPermission { permission: string; @@ -91,13 +92,13 @@ function UserPermissionsComponent({ guild, guildMember, closePopout }: { guild: const userRoles = getSortedRolesForMember(guild, guildMember); const rolePermissions: Array = userRoles.map(role => ({ - type: PermissionType.Role, + type: PermissionOverwriteType.ROLE, ...role })); if (guild.ownerId === guildMember.userId) { rolePermissions.push({ - type: PermissionType.Owner, + type: PermissionOverwriteType.OWNER, permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n) }); From 37d8f96e08e46fb711ac078c33ce8b420e38b500 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 14 Mar 2026 23:05:27 -0400 Subject: [PATCH 05/14] Update utils.ts --- src/plugins/permissionsViewer/utils.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/permissionsViewer/utils.ts b/src/plugins/permissionsViewer/utils.ts index c9280b1b45..3e07e82d68 100644 --- a/src/plugins/permissionsViewer/utils.ts +++ b/src/plugins/permissionsViewer/utils.ts @@ -18,12 +18,11 @@ import { classNameFactory } from "@utils/css"; import { Guild, GuildMember, Role } from "@vencord/discord-types"; +import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { findByPropsLazy } from "@webpack"; import { GuildRoleStore } from "@webpack/common"; import { PermissionsSortOrder, settings } from "."; -import { PermissionType } from "./components/RolesAndUsersPermissions"; - export const { getGuildPermissionSpecMap } = findByPropsLazy("getGuildPermissionSpecMap"); export const cl = classNameFactory("vc-permviewer-"); @@ -50,7 +49,7 @@ export function sortPermissionOverwrites { - if (a.type !== PermissionType.Role || b.type !== PermissionType.Role) return 0; + if (a.type !== PermissionOverwriteType.ROLE || b.type !== PermissionOverwriteType.ROLE) return 0; const roleA = roles[a.id]; const roleB = roles[b.id]; From f8993ad3ab2599c3d0dc304de5c9358c729db925 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:33:01 -0400 Subject: [PATCH 06/14] biggerstreampreview move stores --- .../stores/ApplicationStreamPreviewStore.d.ts | 7 ++++ .../src/stores/ApplicationStreamingStore.d.ts | 40 +------------------ packages/discord-types/src/stores/index.d.ts | 2 + src/plugins/biggerStreamPreview/index.tsx | 7 +--- .../biggerStreamPreview/webpack/stores.ts | 24 ----------- src/webpack/common/stores.ts | 4 ++ 6 files changed, 16 insertions(+), 68 deletions(-) create mode 100644 packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts rename src/plugins/biggerStreamPreview/webpack/types/stores.ts => packages/discord-types/src/stores/ApplicationStreamingStore.d.ts (51%) delete mode 100644 src/plugins/biggerStreamPreview/webpack/stores.ts diff --git a/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts b/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts new file mode 100644 index 0000000000..cddb63f9cd --- /dev/null +++ b/packages/discord-types/src/stores/ApplicationStreamPreviewStore.d.ts @@ -0,0 +1,7 @@ +import { FluxStore } from ".."; + +export interface ApplicationStreamPreviewStore extends FluxStore { + getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean; + getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise; + getPreviewURLForStreamKey: (streamKey: string) => ReturnType; +} diff --git a/src/plugins/biggerStreamPreview/webpack/types/stores.ts b/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts similarity index 51% rename from src/plugins/biggerStreamPreview/webpack/types/stores.ts rename to packages/discord-types/src/stores/ApplicationStreamingStore.d.ts index e11ede5040..a764d1467d 100644 --- a/src/plugins/biggerStreamPreview/webpack/types/stores.ts +++ b/packages/discord-types/src/stores/ApplicationStreamingStore.d.ts @@ -1,39 +1,4 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2023 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { FluxStore } from "@vencord/discord-types"; - -export interface ApplicationStreamPreviewStore extends FluxStore { - getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean; - getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise; - getPreviewURLForStreamKey: (streamKey: string) => ReturnType; -} - -export interface ApplicationStream { - streamType: string; - guildId: string | null; - channelId: string; - ownerId: string; -} - -export interface Stream extends ApplicationStream { - state: string; -} +import { ApplicationStream, FluxStore, Stream } from ".."; export interface RTCStream { region: string, @@ -54,9 +19,6 @@ export interface StreamingStoreState { streamsByUserAndGuild: { [key: string]: { [key: string]: ApplicationStream; }; }; } -/** - * example how a stream key could look like: `call(type of connection):1116549917987192913(channelId):305238513941667851(ownerId)` - */ export interface ApplicationStreamingStore extends FluxStore { getActiveStreamForApplicationStream: (stream: ApplicationStream) => Stream | null; getActiveStreamForStreamKey: (streamKey: string) => Stream | null; diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts index ba6c0aa5c0..77c14eef06 100644 --- a/packages/discord-types/src/stores/index.d.ts +++ b/packages/discord-types/src/stores/index.d.ts @@ -3,6 +3,8 @@ export * from "./AccessibilityStore"; export * from "./ActiveJoinedThreadsStore"; export * from "./ApplicationCommandIndexStore"; export * from "./ApplicationStore"; +export * from "./ApplicationStreamingStore"; +export * from "./ApplicationStreamPreviewStore"; export * from "./AuthenticationStore"; export * from "./CallStore"; export * from "./ChannelRTCStore"; diff --git a/src/plugins/biggerStreamPreview/index.tsx b/src/plugins/biggerStreamPreview/index.tsx index e77e3a02bb..2e8beb86a1 100644 --- a/src/plugins/biggerStreamPreview/index.tsx +++ b/src/plugins/biggerStreamPreview/index.tsx @@ -21,11 +21,8 @@ import { ScreenshareIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { openImageModal } from "@utils/discord"; import definePlugin from "@utils/types"; -import { Channel, User } from "@vencord/discord-types"; -import { Menu } from "@webpack/common"; - -import { ApplicationStreamingStore, ApplicationStreamPreviewStore } from "./webpack/stores"; -import { ApplicationStream, Stream } from "./webpack/types/stores"; +import { ApplicationStream, Channel, Stream, User } from "@vencord/discord-types"; +import { ApplicationStreamingStore, ApplicationStreamPreviewStore, Menu } from "@webpack/common"; export interface UserContextProps { channel: Channel, diff --git a/src/plugins/biggerStreamPreview/webpack/stores.ts b/src/plugins/biggerStreamPreview/webpack/stores.ts deleted file mode 100644 index ba5227baae..0000000000 --- a/src/plugins/biggerStreamPreview/webpack/stores.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2023 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { findStoreLazy } from "@webpack"; - -import * as t from "./types/stores"; - -export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore"); -export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore"); diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 9750f2800e..f3deac53b0 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -85,6 +85,8 @@ export let EditMessageStore: t.EditMessageStore; export let QuestStore: t.QuestStore; export let ExperimentStore: t.ExperimentStore; export let UserAffinitiesStore: t.UserAffinitiesStore; +export let ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore; +export let ApplicationStreamingStore: t.ApplicationStreamingStore; /** * @see jsdoc of {@link t.useStateFromStores} @@ -142,6 +144,8 @@ waitForStore("EditMessageStore", m => EditMessageStore = m); waitForStore("ExperimentStore", m => ExperimentStore = m); waitForStore("QuestStore", m => QuestStore = m); waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m); +waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m); +waitForStore("ApplicationStreamingStore", m => ApplicationStreamingStore = m); waitForStore("ThemeStore", m => { ThemeStore = m; // Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies. From 287eea50339f00c4447eb4e1d46db4070eaa47e1 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:34:28 -0400 Subject: [PATCH 07/14] move a store down --- src/webpack/common/stores.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index f3deac53b0..f1c66bdee6 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -144,8 +144,8 @@ waitForStore("EditMessageStore", m => EditMessageStore = m); waitForStore("ExperimentStore", m => ExperimentStore = m); waitForStore("QuestStore", m => QuestStore = m); waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m); -waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m); waitForStore("ApplicationStreamingStore", m => ApplicationStreamingStore = m); +waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m); waitForStore("ThemeStore", m => { ThemeStore = m; // Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies. From fe51caf21a5f280ff3feb59bdab650752a4f89a5 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:34:46 -0400 Subject: [PATCH 08/14] Update stores.ts --- src/webpack/common/stores.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index f1c66bdee6..0716a3a2d7 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -85,8 +85,8 @@ export let EditMessageStore: t.EditMessageStore; export let QuestStore: t.QuestStore; export let ExperimentStore: t.ExperimentStore; export let UserAffinitiesStore: t.UserAffinitiesStore; -export let ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore; export let ApplicationStreamingStore: t.ApplicationStreamingStore; +export let ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore; /** * @see jsdoc of {@link t.useStateFromStores} From 567637c737935e264ff3d7b1a3046bc833a58ba0 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Thu, 19 Mar 2026 09:32:30 +0100 Subject: [PATCH 09/14] ci: fix resource exhaustion errors --- package.json | 1 + pnpm-lock.yaml | 20 +++++++++++++++++++- src/debug/loadLazyChunks.ts | 20 +++++++++++++------- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 0061e54ae7..6722df7889 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "highlight.js": "11.11.1", "html-minifier-terser": "^7.2.0", "moment": "^2.22.2", + "p-limit": "^7.3.0", "puppeteer-core": "^24.30.0", "standalone-electron-types": "^34.2.0", "stylelint": "^16.25.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a09059550..baca9c2294 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,6 +98,9 @@ importers: moment: specifier: ^2.22.2 version: 2.30.1 + p-limit: + specifier: ^7.3.0 + version: 7.3.0 puppeteer-core: specifier: ^24.30.0 version: 24.30.0 @@ -966,6 +969,7 @@ packages: basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} + deprecated: Security vulnerability fixed in 5.2.0, please upgrade boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2154,6 +2158,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@7.3.0: + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} + engines: {node: '>=20'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -2814,6 +2822,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + zip-local@0.3.5: resolution: {integrity: sha512-GRV3D5TJY+/PqyeRm5CYBs7xVrKTKzljBoEXvocZu0HJ7tPEcgpSOYa2zFIsCZWgKWMuc4U3yMFgFkERGFIB9w==} @@ -3193,7 +3205,7 @@ snapshots: '@types/react-dom@18.3.1': dependencies: - '@types/react': 18.3.1 + '@types/react': 19.0.12 '@types/react-dom@19.0.4(@types/react@19.0.12)': dependencies: @@ -4899,6 +4911,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@7.3.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 @@ -5726,6 +5742,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + zip-local@0.3.5: dependencies: async: 1.5.2 diff --git a/src/debug/loadLazyChunks.ts b/src/debug/loadLazyChunks.ts index 94a9f6a3e8..cf094f5740 100644 --- a/src/debug/loadLazyChunks.ts +++ b/src/debug/loadLazyChunks.ts @@ -9,6 +9,7 @@ import { canonicalizeMatch } from "@utils/patches"; import { ModuleFactory } from "@vencord/discord-types/webpack"; import * as Webpack from "@webpack"; import { wreq } from "@webpack"; +import pLimit from "p-limit"; import { AnyModuleFactory } from "webpack"; function getWebpackChunkMap() { @@ -31,6 +32,7 @@ function getWebpackChunkMap() { export async function loadLazyChunks() { const LazyChunkLoaderLogger = new Logger("LazyChunkLoader"); + const queue = pLimit(50); try { LazyChunkLoaderLogger.log("Loading all chunks..."); @@ -59,11 +61,15 @@ export async function loadLazyChunks() { const shouldForceDefer = false; - await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => { - const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => { - const numChunkId = Number(m[1]); - return Number.isNaN(numChunkId) ? m[1] : numChunkId; - }) : []; + await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => queue(async () => { + const chunkIds = rawChunkIds + ?.matchAll(Webpack.ChunkIdsRegex) + .map(m => { + const numChunkId = Number(m[1]); + return Number.isNaN(numChunkId) ? m[1] : numChunkId; + }) + .toArray() + ?? []; if (chunkIds.length === 0) { return; @@ -101,13 +107,13 @@ export async function loadLazyChunks() { const numEntryPoint = Number(entryPoint); validChunkGroups.add([chunkIds, Number.isNaN(numEntryPoint) ? entryPoint : numEntryPoint]); } - })); + }))); // Loads all found valid chunk groups await Promise.all( Array.from(validChunkGroups) .map(([chunkIds]) => - Promise.all(chunkIds.map(id => wreq.e(id))) + Promise.all(chunkIds.map(id => queue(() => wreq.e(id)))) ) ); From cdf933120401c06d347ee3d37cd9dadc904480e3 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Thu, 19 Mar 2026 09:34:57 +0100 Subject: [PATCH 10/14] Revert "ci: fix resource exhaustion errors" doesnt solve issue guh --- package.json | 1 - pnpm-lock.yaml | 20 +------------------- src/debug/loadLazyChunks.ts | 20 +++++++------------- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 6722df7889..0061e54ae7 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "highlight.js": "11.11.1", "html-minifier-terser": "^7.2.0", "moment": "^2.22.2", - "p-limit": "^7.3.0", "puppeteer-core": "^24.30.0", "standalone-electron-types": "^34.2.0", "stylelint": "^16.25.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index baca9c2294..0a09059550 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,9 +98,6 @@ importers: moment: specifier: ^2.22.2 version: 2.30.1 - p-limit: - specifier: ^7.3.0 - version: 7.3.0 puppeteer-core: specifier: ^24.30.0 version: 24.30.0 @@ -969,7 +966,6 @@ packages: basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.0, please upgrade boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2158,10 +2154,6 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@7.3.0: - resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} - engines: {node: '>=20'} - p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -2822,10 +2814,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} - zip-local@0.3.5: resolution: {integrity: sha512-GRV3D5TJY+/PqyeRm5CYBs7xVrKTKzljBoEXvocZu0HJ7tPEcgpSOYa2zFIsCZWgKWMuc4U3yMFgFkERGFIB9w==} @@ -3205,7 +3193,7 @@ snapshots: '@types/react-dom@18.3.1': dependencies: - '@types/react': 19.0.12 + '@types/react': 18.3.1 '@types/react-dom@19.0.4(@types/react@19.0.12)': dependencies: @@ -4911,10 +4899,6 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@7.3.0: - dependencies: - yocto-queue: 1.2.2 - p-locate@5.0.0: dependencies: p-limit: 3.1.0 @@ -5742,8 +5726,6 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.2.2: {} - zip-local@0.3.5: dependencies: async: 1.5.2 diff --git a/src/debug/loadLazyChunks.ts b/src/debug/loadLazyChunks.ts index cf094f5740..94a9f6a3e8 100644 --- a/src/debug/loadLazyChunks.ts +++ b/src/debug/loadLazyChunks.ts @@ -9,7 +9,6 @@ import { canonicalizeMatch } from "@utils/patches"; import { ModuleFactory } from "@vencord/discord-types/webpack"; import * as Webpack from "@webpack"; import { wreq } from "@webpack"; -import pLimit from "p-limit"; import { AnyModuleFactory } from "webpack"; function getWebpackChunkMap() { @@ -32,7 +31,6 @@ function getWebpackChunkMap() { export async function loadLazyChunks() { const LazyChunkLoaderLogger = new Logger("LazyChunkLoader"); - const queue = pLimit(50); try { LazyChunkLoaderLogger.log("Loading all chunks..."); @@ -61,15 +59,11 @@ export async function loadLazyChunks() { const shouldForceDefer = false; - await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => queue(async () => { - const chunkIds = rawChunkIds - ?.matchAll(Webpack.ChunkIdsRegex) - .map(m => { - const numChunkId = Number(m[1]); - return Number.isNaN(numChunkId) ? m[1] : numChunkId; - }) - .toArray() - ?? []; + await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => { + const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => { + const numChunkId = Number(m[1]); + return Number.isNaN(numChunkId) ? m[1] : numChunkId; + }) : []; if (chunkIds.length === 0) { return; @@ -107,13 +101,13 @@ export async function loadLazyChunks() { const numEntryPoint = Number(entryPoint); validChunkGroups.add([chunkIds, Number.isNaN(numEntryPoint) ? entryPoint : numEntryPoint]); } - }))); + })); // Loads all found valid chunk groups await Promise.all( Array.from(validChunkGroups) .map(([chunkIds]) => - Promise.all(chunkIds.map(id => queue(() => wreq.e(id)))) + Promise.all(chunkIds.map(id => wreq.e(id))) ) ); From a8b89df0f6cdf8820a2642539f2db1430135157b Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Thu, 19 Mar 2026 07:48:42 -0400 Subject: [PATCH 11/14] remove queststore fix flags --- packages/discord-types/enums/application.ts | 40 +- packages/discord-types/enums/user.ts | 46 +- .../discord-types/src/stores/QuestStore.d.ts | 738 ------------------ packages/discord-types/src/stores/index.d.ts | 1 - src/webpack/common/stores.ts | 2 - 5 files changed, 43 insertions(+), 784 deletions(-) delete mode 100644 packages/discord-types/src/stores/QuestStore.d.ts diff --git a/packages/discord-types/enums/application.ts b/packages/discord-types/enums/application.ts index b032a2a8ff..99a9e1b647 100644 --- a/packages/discord-types/enums/application.ts +++ b/packages/discord-types/enums/application.ts @@ -19,25 +19,23 @@ export const enum CarouselItemType { } export const enum ApplicationFlags { - EMBEDDED_RELEASED = 2, - EMBEDDED_IAP = 8, - APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 64, - GAME_PROFILE_DISABLED = 128, - CONTEXTLESS_ACTIVITY = 512, - SOCIAL_LAYER_INTEGRATION_LIMITED = 1024, - CLOUD_GAMING_DEMO = 2048, - GATEWAY_PRESENCE = 4096, - GATEWAY_PRESENCE_LIMITED = 8192, - GATEWAY_GUILD_MEMBERS = 16384, - GATEWAY_GUILD_MEMBERS_LIMITED = 32768, - EMBEDDED = 131072, - GATEWAY_MESSAGE_CONTENT = 262144, - GATEWAY_MESSAGE_CONTENT_LIMITED = 524288, - EMBEDDED_FIRST_PARTY = 1048576, - APPLICATION_COMMAND_BADGE = 8388608, - SOCIAL_LAYER_INTEGRATION = 134217728, - PROMOTED = 536870912, - PARTNER = 1073741824, - PARENT = 8589934592, - DISABLE_RELATIONSHIPS_ACCESS = 17179869184, + EMBEDDED_RELEASED = 1 << 1, + EMBEDDED_IAP = 1 << 3, + APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 1 << 6, + GAME_PROFILE_DISABLED = 1 << 7, + CONTEXTLESS_ACTIVITY = 1 << 9, + SOCIAL_LAYER_INTEGRATION_LIMITED = 1 << 10, + CLOUD_GAMING_DEMO = 1 << 11, + GATEWAY_PRESENCE = 1 << 12, + GATEWAY_PRESENCE_LIMITED = 1 << 13, + GATEWAY_GUILD_MEMBERS = 1 << 14, + GATEWAY_GUILD_MEMBERS_LIMITED = 1 << 15, + EMBEDDED = 1 << 17, + GATEWAY_MESSAGE_CONTENT = 1 << 18, + GATEWAY_MESSAGE_CONTENT_LIMITED = 1 << 19, + EMBEDDED_FIRST_PARTY = 1 << 20, + APPLICATION_COMMAND_BADGE = 1 << 23, + SOCIAL_LAYER_INTEGRATION = 1 << 27, + PROMOTED = 1 << 29, + PARTNER = 1 << 30, } diff --git a/packages/discord-types/enums/user.ts b/packages/discord-types/enums/user.ts index 0ad2ec6d61..cf9852f6e0 100644 --- a/packages/discord-types/enums/user.ts +++ b/packages/discord-types/enums/user.ts @@ -28,28 +28,30 @@ export const enum ReadStateType { } export const enum UserFlags { - STAFF = 1, - PARTNER = 2, - HYPESQUAD = 4, - BUG_HUNTER_LEVEL_1 = 8, - MFA_SMS = 16, - PREMIUM_PROMO_DISMISSED = 32, - HYPESQUAD_ONLINE_HOUSE_1 = 64, - HYPESQUAD_ONLINE_HOUSE_2 = 128, - HYPESQUAD_ONLINE_HOUSE_3 = 256, - PREMIUM_EARLY_SUPPORTER = 512, - HAS_UNREAD_URGENT_MESSAGES = 8192, - BUG_HUNTER_LEVEL_2 = 16384, - VERIFIED_BOT = 65536, - VERIFIED_DEVELOPER = 131072, - CERTIFIED_MODERATOR = 262144, - BOT_HTTP_INTERACTIONS = 524288, - SPAMMER = 1048576, - DISABLE_PREMIUM = 2097152, - PROVISIONAL_ACCOUNT = 8388608, - QUARANTINED = 17592186044416, - COLLABORATOR = 1125899906842624, - RESTRICTED_COLLABORATOR = 2251799813685248, + STAFF = 1 << 0, + PARTNER = 1 << 1, + HYPESQUAD = 1 << 2, + BUG_HUNTER_LEVEL_1 = 1 << 3, + MFA_SMS = 1 << 4, + PREMIUM_PROMO_DISMISSED = 1 << 5, + HYPESQUAD_ONLINE_HOUSE_1 = 1 << 6, + HYPESQUAD_ONLINE_HOUSE_2 = 1 << 7, + HYPESQUAD_ONLINE_HOUSE_3 = 1 << 8, + PREMIUM_EARLY_SUPPORTER = 1 << 9, + TEAM_PSEUDO_USER = 1 << 10, + IS_HUBSPOT_CONTACT = 1 << 11, + SYSTEM = 1 << 12, + HAS_UNREAD_URGENT_MESSAGES = 1 << 13, + BUG_HUNTER_LEVEL_2 = 1 << 14, + UNDERAGE_DELETED = 1 << 15, + VERIFIED_BOT = 1 << 16, + VERIFIED_DEVELOPER = 1 << 17, + CERTIFIED_MODERATOR = 1 << 18, + BOT_HTTP_INTERACTIONS = 1 << 19, + SPAMMER = 1 << 20, + DISABLE_PREMIUM = 1 << 21, + ACTIVE_DEVELOPER = 1 << 22, + PROVISIONAL_ACCOUNT = 1 << 23, } export const enum StandingState { diff --git a/packages/discord-types/src/stores/QuestStore.d.ts b/packages/discord-types/src/stores/QuestStore.d.ts deleted file mode 100644 index 54ce89e78c..0000000000 --- a/packages/discord-types/src/stores/QuestStore.d.ts +++ /dev/null @@ -1,738 +0,0 @@ -import { - QuestDismissibleContentFlags, - QuestFeature, - QuestPlatform, - QuestPlacement, - QuestRewardAssignmentMethod, - QuestRewardExpirationMode, - QuestRewardType, - QuestTargetedContent, - QuestTaskType, - QuestHomePlacement, - QuestTranscriptFetchStatus, - QuestErrorType, - QuestSharePolicy, - QuestTaskJoinOperator, - QuestPlatformMode, -} from "../../enums"; -import { FluxStore } from "./FluxStore"; - -/** Video asset for quest tasks. */ -export interface QuestVideoAsset { - /** Video URL path relative to CDN. */ - url: string; - /** Width in pixels. */ - width: number; - /** Height in pixels. */ - height: number; - /** Thumbnail image URL. */ - thumbnail: string; - /** VTT caption file URL. */ - caption?: string; - /** Transcript file URL. */ - transcript?: string; -} - -/** Video assets for video-based quest tasks. */ -export interface QuestTaskVideoAssets { - /** Full resolution video (1080p). */ - video: QuestVideoAsset; - /** Low resolution video (720p). */ - videoLowRes?: QuestVideoAsset; - /** HLS streaming video (.m3u8). */ - videoHls?: QuestVideoAsset; -} - -/** Display messages for video-based quest tasks. */ -export interface QuestTaskVideoMessages { - videoTitle: string; -} - -/** Display messages for achievement-based quest tasks. */ -export interface QuestTaskAchievementMessages { - taskTitle: string; - taskDescription: string; -} - -/** Application reference in quest tasks. */ -export interface QuestTaskApplication { - /** Discord application ID. */ - id: string; -} - -/** Base properties shared by all quest task types. */ -interface QuestTaskBase { - /** Target value to complete (seconds for play tasks, seconds for video tasks). */ - target: number; -} - -/** Play on desktop quest task. */ -export interface QuestTaskPlayOnDesktop extends QuestTaskBase { - type: QuestTaskType.PLAY_ON_DESKTOP; - /** Applications that qualify for completion. */ - applications: QuestTaskApplication[]; -} - -/** Play on desktop v2 quest task with enhanced tracking. */ -export interface QuestTaskPlayOnDesktopV2 extends QuestTaskBase { - type: QuestTaskType.PLAY_ON_DESKTOP_V2; - applications: QuestTaskApplication[]; -} - -/** Stream on desktop quest task. */ -export interface QuestTaskStreamOnDesktop extends QuestTaskBase { - type: QuestTaskType.STREAM_ON_DESKTOP; - applications: QuestTaskApplication[]; -} - -/** Play Discord activity quest task. */ -export interface QuestTaskPlayActivity extends QuestTaskBase { - type: QuestTaskType.PLAY_ACTIVITY; - applications: QuestTaskApplication[]; -} - -/** Play on Xbox quest task. */ -export interface QuestTaskPlayOnXbox extends QuestTaskBase { - type: QuestTaskType.PLAY_ON_XBOX; - /** Xbox title IDs. */ - externalIds: string[]; - applications: QuestTaskApplication[]; -} - -/** Play on PlayStation quest task. */ -export interface QuestTaskPlayOnPlayStation extends QuestTaskBase { - type: QuestTaskType.PLAY_ON_PLAYSTATION; - /** PlayStation title IDs (e.g., "PPSA09016_00"). */ - externalIds: string[]; - applications: QuestTaskApplication[]; -} - -/** Watch video quest task for desktop. */ -export interface QuestTaskWatchVideo extends QuestTaskBase { - type: QuestTaskType.WATCH_VIDEO; - assets: QuestTaskVideoAssets; - messages: QuestTaskVideoMessages; -} - -/** Watch video quest task for mobile. */ -export interface QuestTaskWatchVideoOnMobile extends QuestTaskBase { - type: QuestTaskType.WATCH_VIDEO_ON_MOBILE; - assets: QuestTaskVideoAssets; - messages: QuestTaskVideoMessages; -} - -/** Achievement in game quest task. */ -export interface QuestTaskAchievementInGame extends QuestTaskBase { - type: QuestTaskType.ACHIEVEMENT_IN_GAME; - /** Event name dispatched when achievement is unlocked. */ - eventName: string; - messages: QuestTaskAchievementMessages; - applications: QuestTaskApplication[]; -} - -/** Achievement in Discord activity quest task. */ -export interface QuestTaskAchievementInActivity extends QuestTaskBase { - type: QuestTaskType.ACHIEVEMENT_IN_ACTIVITY; - eventName: string; - messages: QuestTaskAchievementMessages; - applications: QuestTaskApplication[]; -} - -/** Union of all quest task types. */ -export type QuestTask = - | QuestTaskPlayOnDesktop - | QuestTaskPlayOnDesktopV2 - | QuestTaskStreamOnDesktop - | QuestTaskPlayActivity - | QuestTaskPlayOnXbox - | QuestTaskPlayOnPlayStation - | QuestTaskWatchVideo - | QuestTaskWatchVideoOnMobile - | QuestTaskAchievementInGame - | QuestTaskAchievementInActivity; - -/** Task configuration for a quest. */ -export interface QuestTaskConfig { - /** Map of task type to task configuration. */ - tasks: Partial>; - /** How tasks are combined. Default is "or" (any task completes the quest). */ - joinOperator: QuestTaskJoinOperator; -} - -/** Display messages for quest rewards. */ -export interface QuestRewardMessages { - /** Redemption instructions keyed by {@link QuestPlatform}. */ - redemptionInstructionsByPlatform: Partial>; - /** Reward display name (e.g., "700 Orbs"). */ - name: string; - /** Name with article (e.g., "700 Orbs"). */ - nameWithArticle: string; -} - -/** Base properties shared by all quest reward types. */ -interface QuestRewardBase { - /** SKU ID for the reward entitlement. */ - skuId: string; - messages: QuestRewardMessages; -} - -/** Reward code reward type. */ -export interface QuestRewardCode extends QuestRewardBase { - type: QuestRewardType.REWARD_CODE; - /** Reward image URL. */ - asset?: string; - /** Reward video URL. */ - assetVideo?: string | null; - /** Approximate codes remaining, null if unlimited. */ - approximateCount?: number | null; - /** External URL to redeem the code. */ - redemptionLink?: string | null; -} - -/** In-game reward type. */ -export interface QuestRewardInGame extends QuestRewardBase { - type: QuestRewardType.IN_GAME; - asset?: string; - assetVideo?: string | null; -} - -/** Collectible avatar decoration reward type. */ -export interface QuestRewardCollectible extends QuestRewardBase { - type: QuestRewardType.COLLECTIBLE; - asset?: string; - assetVideo?: string | null; - /** ISO timestamp when collectible expires. */ - expiresAt?: string; - /** Expiration behavior. */ - expirationMode?: QuestRewardExpirationMode; - /** Extended expiration for Nitro users. */ - expiresAtPremium?: string | null; -} - -/** Virtual currency (Orbs) reward type. */ -export interface QuestRewardVirtualCurrency extends QuestRewardBase { - type: QuestRewardType.VIRTUAL_CURRENCY; - /** Number of orbs awarded. */ - orbQuantity: number; -} - -/** Fractional Nitro premium time reward type. */ -export interface QuestRewardFractionalPremium extends QuestRewardBase { - type: QuestRewardType.FRACTIONAL_PREMIUM; - asset?: string; - assetVideo?: string | null; - /** Premium time quantity. */ - quantity: number; -} - -/** Union of all quest reward types. */ -export type QuestReward = - | QuestRewardCode - | QuestRewardInGame - | QuestRewardCollectible - | QuestRewardVirtualCurrency - | QuestRewardFractionalPremium; - -/** Rewards configuration for a quest. */ -export interface QuestRewardsConfig { - /** How rewards are distributed to users. */ - assignmentMethod: QuestRewardAssignmentMethod; - /** Available reward options. */ - rewards: QuestReward[]; - /** ISO timestamp when rewards can no longer be claimed. */ - rewardsExpireAt: string; - /** Platforms where rewards can be claimed. */ - platforms: QuestPlatform[]; -} - -/** Visual assets for quest display. */ -export interface QuestAssets { - /** Hero banner image URL. */ - hero: string; - /** Hero banner video URL. */ - heroVideo: string | null; - /** Quest bar hero image URL. */ - questBarHero: string; - /** Quest bar hero video URL. */ - questBarHeroVideo: string | null; - /** Game tile image URL. */ - gameTile: string; - /** Game logotype image URL. */ - logotype: string; - /** Light theme game tile URL. */ - gameTileLight: string; - /** Dark theme game tile URL. */ - gameTileDark: string; - /** Light theme logotype URL. */ - logotypeLight: string; - /** Dark theme logotype URL. */ - logotypeDark: string; -} - -/** Color scheme for quest UI theming. */ -export interface QuestColors { - /** Primary hex color (e.g., "#4752C4"). */ - primary: string; - /** Secondary hex color. */ - secondary: string; -} - -/** Display messages for quest UI. */ -export interface QuestMessages { - /** Quest display name. */ - questName: string; - /** Game title. */ - gameTitle: string; - /** Game publisher name. */ - gamePublisher: string; -} - -/** Application reference in quest configuration. */ -export interface QuestApplication { - /** Discord application ID. */ - id: string; - /** Application display name. */ - name: string; -} - -/** Platform-specific app store configuration. */ -export interface QuestCtaPlatformConfig { - /** Android package name. */ - androidAppId?: string; - /** iOS App Store ID. */ - iosAppId?: string; -} - -/** Call-to-action button configuration. */ -export interface QuestCtaConfig { - /** CTA destination URL. */ - link: string; - /** Button label text. */ - buttonLabel: string; - /** Optional subtitle text. */ - subtitle?: string; - /** Android-specific configuration. */ - android?: QuestCtaPlatformConfig; - /** iOS-specific configuration. */ - ios?: QuestCtaPlatformConfig; -} - -/** Co-sponsor branding metadata for partnered quests. */ -export interface QuestCosponsorMetadata { - /** Co-sponsor company name. */ - name: string; - /** Logotype image URL. */ - logotype: string; - /** Redemption instructions text. */ - redemptionInstructions: string; - /** Light theme logotype URL. */ - logotypeLight: string; - /** Dark theme logotype URL. */ - logotypeDark: string; -} - -/** Complete quest configuration. */ -export interface QuestConfig { - /** Quest ID (snowflake). */ - id: string; - /** Configuration version number. */ - configVersion: number; - /** ISO timestamp when quest becomes available. */ - startsAt: string; - /** ISO timestamp when quest expires. */ - expiresAt: string; - /** Enabled feature flags for this quest. */ - features: QuestFeature[]; - /** Associated Discord application. */ - application: QuestApplication; - /** Visual assets. */ - assets: QuestAssets; - /** Color scheme. */ - colors: QuestColors; - /** Display messages. */ - messages: QuestMessages; - /** Task requirements configuration. */ - taskConfigV2: QuestTaskConfig; - /** Rewards configuration. */ - rewardsConfig: QuestRewardsConfig; - /** Optional co-sponsor branding. */ - cosponsorMetadata?: QuestCosponsorMetadata; - /** Sharing policy. */ - sharePolicy: QuestSharePolicy; - /** Call-to-action configuration. */ - ctaConfig: QuestCtaConfig; -} - -/** Heartbeat tracking for quest progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */ -export interface QuestProgressHeartbeat { - /** ISO timestamp of last heartbeat. */ - lastBeatAt: string; - /** ISO timestamp when heartbeat tracking expires. */ - expiresAt: string | null; -} - -/** Progress tracking for a single quest task. Updated via QUESTS_USER_STATUS_UPDATE. */ -export interface QuestTaskProgress { - /** Task event name matching {@link QuestTaskType}. */ - eventName: string; - /** Current progress value (seconds played/watched). */ - value: number; - /** ISO timestamp of last progress update. */ - updatedAt: string; - /** ISO timestamp when task was completed, null if incomplete. */ - completedAt: string | null; - /** Heartbeat tracking for active progress. */ - heartbeat: QuestProgressHeartbeat | null; -} - -/** User's status for a specific quest. Updated via QUESTS_USER_STATUS_UPDATE. */ -export interface QuestUserStatus { - /** User ID (snowflake). */ - userId: string; - /** Quest ID (snowflake). */ - questId: string; - /** ISO timestamp when user enrolled. */ - enrolledAt: string; - /** ISO timestamp when quest was completed, null if incomplete. */ - completedAt: string | null; - /** ISO timestamp when reward was claimed, null if unclaimed. */ - claimedAt: string | null; - /** Claimed reward tier for tiered rewards, null otherwise. */ - claimedTier: number | null; - /** ISO timestamp of last stream heartbeat. */ - lastStreamHeartbeatAt: string | null; - /** Total stream progress in seconds. */ - streamProgressSeconds: number; - /** Bitmask of dismissed UI content. */ - dismissedQuestContent: QuestDismissibleContentFlags; - /** Progress by task event name. */ - progress: Record; -} - -/** Quest object with configuration and user status. */ -export interface Quest { - /** Quest ID (snowflake). */ - id: string; - /** Whether this is a preview/test quest. */ - preview: boolean; - /** Quest configuration. */ - config: QuestConfig; - /** User's status, null if not enrolled. */ - userStatus: QuestUserStatus | null; - /** UI placements where this quest should appear. */ - targetedContent: QuestTargetedContent[]; -} - -/** Reference to an excluded quest. */ -export interface ExcludedQuest { - /** Excluded quest ID. */ - id: string; - /** Replacement quest ID to show instead. */ - replacementId: string; -} - -/** Ad tracking identifiers for quest delivery. */ -export interface QuestAdIdentifiers { - ad_id?: string; - adset_id?: string; - ad_set_id?: string; - campaign_id?: string; - creative_id?: string; - creative_type?: string; - /** Request ID from ad decision. */ - decision_id?: string; - /** Whether quest was served via targeting. */ - is_targeted: boolean; -} - -/** Quest delivery information for a placement. */ -export interface QuestDeliveryInfo { - /** Quest to deliver. */ - quest: Quest; - /** Ad tracking data. */ - adDecisionData: QuestAdIdentifiers; - /** Ad context for analytics. */ - adContext: string | null; - /** Raw metadata for ad attribution. */ - metadataRaw: string | null; - /** Sealed metadata for verification. */ - metadataSealed: string | null; -} - -/** Ad decision cache entry for quest delivery. */ -export interface QuestAdDecision { - /** Quest ID or null if no quest to deliver. */ - questId: string | null; - /** Unix timestamp when decision was fetched. */ - fetchedAt: number; - /** Cache TTL in milliseconds. Default 6 hours. */ - ttlMillis: number; - /** Ad tracking data. */ - adDecisionData: QuestAdIdentifiers; - adContext: string | null; - metadataRaw: string | null; - metadataSealed: string | null; -} - -/** Stream heartbeat failure tracking. Updated via QUESTS_SEND_HEARTBEAT_FAILURE. */ -export interface StreamHeartbeatFailure { - /** Quest ID. */ - questId: string; - /** Stream identifier. */ - streamKey: string; - /** Unix timestamp of first failure. */ - firstFailedAt: number; -} - -/** Asset for quest home takeover display. */ -export interface QuestHomeTakeoverAsset { - /** Accessibility text. */ - altText: string; - /** Asset type identifier. */ - assetType: string; - /** Asset URL. */ - url: string; -} - -/** Sponsor CTA for quest home takeover. */ -export interface QuestHomeTakeoverCtaSponsor { - ctaType: string; - title: string; - /** Sponsor destination URL. */ - url: string; -} - -/** Quest CTA for quest home takeover. */ -export interface QuestHomeTakeoverCtaQuest { - ctaType: string; - title: string; - /** Quest ID to navigate to. */ - questId: string; -} - -/** Quest home takeover banner configuration. */ -export interface QuestHomeTakeoverConfig { - placementType: QuestHomePlacement; - /** Campaign identifier. */ - campaignId: string; - labelTitle: string; - labelSubtitle: string; - /** Hero banner asset. */ - assetHeroImage: QuestHomeTakeoverAsset; - /** Sponsor logo asset. */ - assetSponsorImage: QuestHomeTakeoverAsset; - /** Sponsor link CTA. */ - ctaSponsorUrl: QuestHomeTakeoverCtaSponsor; - /** Quest navigation CTAs. */ - ctaQuests: QuestHomeTakeoverCtaQuest[]; - /** ISO timestamp when takeover starts. */ - startsAt: string; - /** ISO timestamp when takeover expires. */ - expiresAt: string; -} - -/** Claimed reward code details. Returned by QUESTS_FETCH_REWARD_CODE_SUCCESS. */ -export interface QuestClaimedRewardCode { - userId: string; - questId: string; - /** The reward code string. */ - code: string; - /** Platform the code is for. */ - platform: QuestPlatform; - /** ISO timestamp when claimed. */ - claimedAt: string; - /** Reward tier if applicable. */ - tier: number | null; -} - -/** Entitlement item from reward claim. */ -export interface QuestEntitlementItem { - /** SKU ID. */ - skuId: string; - /** Metadata containing reward details. */ - tenantMetadata: { - questRewards?: { - reward: { - tag: QuestRewardType; - rewardCode?: QuestClaimedRewardCode; - }; - }; - } | null; - /** Whether entitlement has been consumed. */ - consumed: boolean; -} - -/** Error from reward claim operation. */ -export interface QuestEntitlementError { - code?: string; - message?: string; -} - -/** Response from claiming quest rewards. Returned by QUESTS_CLAIM_REWARD_SUCCESS. */ -export interface QuestEntitlements { - /** ISO timestamp when claimed. */ - claimedAt: string; - /** Entitlement items received. */ - items: QuestEntitlementItem[]; - /** Errors encountered during claim. */ - errors: QuestEntitlementError[]; -} - -/** Video progress tracking state. */ -export interface QuestVideoProgress { - /** Current playback position in seconds. */ - timestampSec: number; - /** Total video duration in seconds. */ - duration: number; - /** Maximum position reached in seconds. */ - maxTimestampSec: number; -} - -/** Transcript asset for quest videos. */ -export interface QuestTranscriptAsset { - questId: string; - fetchStatus: QuestTranscriptFetchStatus; - /** Transcript text content when loaded. */ - text?: string; - /** Transcript file URL. */ - url?: string; -} - -/** Error hint from console quest operations. */ -export interface QuestConsoleErrorHint { - type: QuestErrorType; - /** User-facing error message. */ - message: string; - /** Connected account ID that caused the error. */ - connected_account_id: string; - /** Account type (e.g., "xbox", "playstation"). */ - connected_account_type: string; -} - -/** Computed task details for display. */ -export interface QuestTaskDetails { - taskType: QuestTaskType; - /** Target completion time in minutes. */ - targetMinutes: number; - /** Progress as decimal (0.0 to 1.0). */ - percentComplete: number; - /** Applications for this task. */ - applications?: QuestTaskApplication[]; -} - -/** Third-party task details for external quests. */ -export interface QuestThirdPartyTaskDetails { - description: string; - /** Current progress value. */ - progress: number; - /** Target completion value. */ - target: number; - /** Progress as decimal (0.0 to 1.0). */ - percentComplete: number; - title?: string; -} - -/** Store for Discord Quests data. Manages quest configs, user progress, rewards, and delivery. */ -export class QuestStore extends FluxStore { - /** All quests keyed by quest ID. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */ - get quests(): Map; - - /** Quests the user is excluded from. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */ - get excludedQuests(): Map; - - /** Quests with claimed rewards. Updated via QUESTS_FETCH_CLAIMED_QUESTS_SUCCESS. */ - get claimedQuests(): Map; - - /** Whether fetching current quests. Set via QUESTS_FETCH_CURRENT_QUESTS_BEGIN. */ - get isFetchingCurrentQuests(): boolean; - - /** Whether fetching claimed quests. Set via QUESTS_FETCH_CLAIMED_QUESTS_BEGIN. */ - get isFetchingClaimedQuests(): boolean; - - /** Unix timestamp of last current quests fetch. Default 0. */ - get lastFetchedCurrentQuests(): number; - - /** Unix timestamp of last quest-to-deliver fetch. Default 0. */ - get lastFetchedQuestToDeliver(): number; - - /** Whether fetching quest to deliver. Set via QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN. */ - get isFetchingQuestToDeliver(): boolean; - - /** Override quest for delivery testing. Set via QUESTS_DELIVERY_OVERRIDE. */ - get questDeliveryOverride(): Quest | undefined; - - /** Quest delivery info keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */ - get questToDeliverForPlacement(): Map; - - /** Date until enrollment is blocked, null if not blocked. Set via QUESTS_ENROLL_FAILURE. */ - get questEnrollmentBlockedUntil(): Date | null; - - /** Ad decision cache keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */ - get questAdDecisionByPlacement(): Map; - - /** Quest configs keyed by quest ID. */ - get questConfigs(): Map; - - /** Whether fetching preview for a quest. */ - isFetchingQuestPreview(questId: string): boolean; - - /** Whether fetching quest to deliver for a placement. */ - isFetchingQuestToDeliverByPlacement(placement: QuestPlacement): boolean; - - /** Gets preview fetch error for a quest. */ - getFetchQuestPreviewError(questId: string): QuestErrorType | undefined; - - /** Whether user is currently enrolling in a quest. Set via QUESTS_ENROLL_BEGIN. */ - isEnrolling(questId: string): boolean; - - /** Whether user is currently claiming reward for a quest. Set via QUESTS_CLAIM_REWARD_BEGIN. */ - isClaimingReward(questId: string): boolean; - - /** Whether fetching reward code for a quest. Set via QUESTS_FETCH_REWARD_CODE_BEGIN. */ - isFetchingRewardCode(questId: string): boolean; - - /** Whether dismissing content for a quest. Set via QUESTS_DISMISS_CONTENT_BEGIN. */ - isDismissingContent(questId: string): boolean; - - /** Gets claimed reward code for a quest. Updated via QUESTS_FETCH_REWARD_CODE_SUCCESS. */ - getRewardCode(questId: string): QuestClaimedRewardCode | undefined; - - /** Gets entitlement items for a quest. Updated via QUESTS_CLAIM_REWARD_SUCCESS. */ - getRewards(questId: string): QuestEntitlementItem[] | undefined; - - /** Gets stream heartbeat failure info. Cleared via STREAM_CLOSE. */ - getStreamHeartbeatFailure(streamKey: string): StreamHeartbeatFailure | undefined; - - /** Gets a quest by ID. */ - getQuest(questId: string): Quest | undefined; - - /** Gets quest config by ID. */ - getQuestConfig(questId: string): QuestConfig | undefined; - - /** Whether quest has active desktop progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */ - isProgressingOnDesktop(questId: string): boolean; - - /** Gets selected task platform for a quest. Set via QUESTS_SELECT_TASK_PLATFORM. */ - selectedTaskPlatform(questId: string): QuestPlatformMode | null; - - /** Gets optimistic progress for a task. Set via QUESTS_UPDATE_OPTIMISTIC_PROGRESS, cleared via QUESTS_RESET_OPTIMISTIC_PROGRESS. */ - getOptimisticProgress(questId: string, taskEventName: string): number | undefined; - - /** Gets map of quest IDs to expired status. Computed from quest config expiresAt. */ - getExpiredQuestsMap(): Map; - - /** Whether a quest has expired. Computed from quest config expiresAt. */ - isQuestExpired(questId: string): boolean; - - /** Gets quest loaded via preview tool. Updated via QUESTS_FETCH_PREVIEW_SUCCESS. */ - getQuestLoadedViaPreview(questId: string): Quest | undefined; - - /** Whether fetching quest home takeover config. Set via QUESTS_FETCH_QUEST_HOME_TAKEOVER_BEGIN. */ - isFetchingQuestHomeTakeover(): boolean; - - /** Gets quest home takeover config. Updated via QUESTS_FETCH_QUEST_HOME_TAKEOVER_SUCCESS. */ - getQuestHomeTakeoverConfig(): QuestHomeTakeoverConfig | null; - - /** Gets Unix timestamp of last takeover fetch, null if never fetched. */ - getLastFetchedQuestHomeTakeover(): number | null; -} diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts index 77c14eef06..387a00c7c3 100644 --- a/packages/discord-types/src/stores/index.d.ts +++ b/packages/discord-types/src/stores/index.d.ts @@ -32,7 +32,6 @@ export * from "./PendingReplyStore"; export * from "./PermissionStore"; export * from "./PopoutWindowStore"; export * from "./PresenceStore"; -export * from "./QuestStore"; export * from "./ReadStateStore"; export * from "./RelationshipStore"; export * from "./RTCConnectionStore"; diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index 0716a3a2d7..86d7a8a56b 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -82,7 +82,6 @@ export let SoundboardStore: t.SoundboardStore; export let PopoutWindowStore: t.PopoutWindowStore; export let ApplicationCommandIndexStore: t.ApplicationCommandIndexStore; export let EditMessageStore: t.EditMessageStore; -export let QuestStore: t.QuestStore; export let ExperimentStore: t.ExperimentStore; export let UserAffinitiesStore: t.UserAffinitiesStore; export let ApplicationStreamingStore: t.ApplicationStreamingStore; @@ -142,7 +141,6 @@ waitForStore("PendingReplyStore", m => PendingReplyStore = m); waitForStore("ApplicationCommandIndexStore", m => ApplicationCommandIndexStore = m); waitForStore("EditMessageStore", m => EditMessageStore = m); waitForStore("ExperimentStore", m => ExperimentStore = m); -waitForStore("QuestStore", m => QuestStore = m); waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m); waitForStore("ApplicationStreamingStore", m => ApplicationStreamingStore = m); waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m); From a8a7a3ac8a4584646b01fc7f2ef54abb0028b684 Mon Sep 17 00:00:00 2001 From: V Date: Tue, 7 Apr 2026 02:45:19 +0200 Subject: [PATCH 12/14] Delete packages/discord-types/enums/quests.ts --- packages/discord-types/enums/quests.ts | 390 ------------------------- 1 file changed, 390 deletions(-) delete mode 100644 packages/discord-types/enums/quests.ts diff --git a/packages/discord-types/enums/quests.ts b/packages/discord-types/enums/quests.ts deleted file mode 100644 index 04915f6a6c..0000000000 --- a/packages/discord-types/enums/quests.ts +++ /dev/null @@ -1,390 +0,0 @@ -export const enum QuestRewardType { - REWARD_CODE = 1, - IN_GAME = 2, - COLLECTIBLE = 3, - VIRTUAL_CURRENCY = 4, - FRACTIONAL_PREMIUM = 5, -} - -export const enum QuestPlatform { - CROSS_PLATFORM = 0, - XBOX = 1, - PLAYSTATION = 2, - SWITCH = 3, - PC = 4, -} - -export const enum QuestTargetedContent { - GIFT_INVENTORY_SETTINGS_BADGE = 0, - QUEST_BAR = 1, - QUEST_INVENTORY_CARD = 2, - QUESTS_EMBED = 3, - ACTIVITY_PANEL = 4, - QUEST_LIVE_STREAM = 5, - MEMBERS_LIST = 6, - QUEST_BADGE = 7, - GIFT_INVENTORY_FOR_YOU = 8, - GIFT_INVENTORY_OTHER = 9, - QUEST_BAR_V2 = 10, - QUEST_HOME_DESKTOP = 11, - QUEST_HOME_MOBILE = 12, - QUEST_BAR_MOBILE = 13, - THIRD_PARTY_APP = 14, - QUEST_BOTTOM_SHEET = 15, - QUEST_EMBED_MOBILE = 16, - QUEST_HOME_MOVE_CALLOUT = 17, - DISCOVERY_SIDEBAR = 18, - QUEST_SHARE_LINK = 19, - CONNECTIONS_MODAL = 20, - DISCOVERY_COMPASS = 21, - TROPHY_CASE_CARD = 22, - VIDEO_MODAL = 23, - VIDEO_MODAL_END_CARD = 24, - REWARD_MODAL = 25, - EXCLUDED_QUEST_EMBED = 26, - VIDEO_MODAL_MOBILE = 27, - ORBS_ANNOUNCEMENT_MODAL = 28, - ORBS_BALANCE_MENU = 29, - QUEST_ENROLLMENT_BLOCKED_BOTTOM_SHEET = 30, - ORBS_SHOP_HERO_CTA = 31, - QUEST_ENROLLMENT_BLOCKED_MODAL = 32, - INTERNAL_PREVIEW_TOOL = 33, - ORBS_REHEAT_COACHMARK_CTA = 34, - INVALID_QUEST_EMBED = 35, - NOT_SHAREABLE_QUEST_EMBED = 36, - QUEST_HOME_MOVE_CALLOUT_DISCOVER = 37, - SPONSORED_QUEST_SHEET = 38, - MOBILE_ORBS_ONBOARDING_DC = 39, - RUNNING_ACTIVITY = 40, - VIDEO_MODAL_PRIMARY_CTA = 41, - QUEST_HOME_TAKEOVER = 42, - USER_PROFILE_ACTIVITY = 43, -} - -export const enum QuestPlacement { - INVALID_PLACEMENT = 0, - DESKTOP_ACCOUNT_PANEL_AREA = 1, - MOBILE_HOME_DOCK_AREA = 2, -} - -export const enum QuestRewardAssignmentMethod { - ALL = 1, - TIERED = 2, -} - -export const enum QuestRewardExpirationMode { - NORMAL = 1, - PREMIUM_EXTENSION = 2, - PREMIUM_PERMANENT = 3, -} - -export const enum QuestFeature { - POST_ENROLLMENT_CTA = 1, - QUEST_BAR_V2 = 3, - EXCLUDE_RUSSIA = 5, - IN_HOUSE_CONSOLE_QUEST = 6, - MOBILE_CONSOLE_QUEST = 7, - START_QUEST_CTA = 8, - REWARD_HIGHLIGHTING = 9, - FRACTIONS_QUEST = 10, - ADDITIONAL_REDEMPTION_INSTRUCTIONS = 11, - PACING_V2 = 12, - DISMISSAL_SURVEY = 13, - MOBILE_QUEST_DOCK = 14, - QUESTS_CDN = 15, - PACING_CONTROLLER = 16, - QUEST_HOME_FORCE_STATIC_IMAGE = 17, - VIDEO_QUEST_FORCE_HLS_VIDEO = 18, - VIDEO_QUEST_FORCE_END_CARD_CTA_SWAP = 19, - EXPERIMENTAL_TARGETING_TRAITS = 20, - DO_NOT_DISPLAY = 21, - EXTERNAL_DIALOG = 22, - MOBILE_ONLY_QUEST_PUSH_TO_MOBILE = 23, - MANUAL_HEARTBEAT_INITIALIZATION = 24, - CLOUD_GAMING_ACTIVITY = 25, - NON_GAMING_PLAY_QUEST = 26, - ACTIVITY_QUEST_AUTO_ENROLLMENT = 27, - PACKAGE_ACTION_ADVENTURE = 28, - PACKAGE_RPG_MMO = 29, - PACKAGE_RACING_SPORTS = 30, - PACKAGE_SANDBOX_CREATIVE = 31, - PACKAGE_FAMILY_FRIENDLY = 32, - PACKAGE_HOLIDAY_SEASON = 33, - PACKAGE_NEW_YEARS = 34, -} - -export const enum QuestDismissibleContentFlags { - GIFT_INVENTORY_SETTINGS_BADGE = 1, - QUEST_BAR = 2, - ACTIVITY_PANEL = 4, - QUEST_LIVE_STREAM = 8, -} - -export const enum QuestUserQuestStatus { - UNACCEPTED = 0, - ACCEPTED = 1, - IN_PROGRESS = 2, - COMPLETED = 3, - CLAIMED = 4, -} - -/** Task types for quest completion requirements. */ -export const enum QuestTaskType { - STREAM_ON_DESKTOP = "STREAM_ON_DESKTOP", - PLAY_ON_DESKTOP = "PLAY_ON_DESKTOP", - PLAY_ON_XBOX = "PLAY_ON_XBOX", - PLAY_ON_PLAYSTATION = "PLAY_ON_PLAYSTATION", - PLAY_ON_DESKTOP_V2 = "PLAY_ON_DESKTOP_V2", - WATCH_VIDEO = "WATCH_VIDEO", - WATCH_VIDEO_ON_MOBILE = "WATCH_VIDEO_ON_MOBILE", - PLAY_ACTIVITY = "PLAY_ACTIVITY", - ACHIEVEMENT_IN_GAME = "ACHIEVEMENT_IN_GAME", - ACHIEVEMENT_IN_ACTIVITY = "ACHIEVEMENT_IN_ACTIVITY", -} - -/** Operator for combining multiple quest tasks. */ -export const enum QuestTaskJoinOperator { - /** All tasks must be completed. */ - AND = "and", - /** Any one task must be completed. */ - OR = "or", -} - -/** Error types returned from quest API operations. */ -export const enum QuestErrorType { - GENERIC = "generic", - RATE_LIMITED = "rate_limited", -} - -/** Platform mode for quest task selection. */ -export const enum QuestPlatformMode { - DESKTOP = "desktop", - CONSOLE = "console", - /** User must select a platform. */ - SELECT = "select", -} - -/** Reasons for pausing quest video playback. */ -export const enum QuestVideoPauseReason { - PAUSE_BUTTON = "PAUSE_BUTTON", - LOST_FOCUS = "LOST_FOCUS", - MODAL_CLOSED = "MODAL_CLOSED", -} - -/** Placement types for quest home takeover. */ -export const enum QuestHomePlacement { - QUEST_HOME_BANNER = "quest_home_banner", -} - -/** Client platforms for quest targeting. */ -export const enum QuestClientPlatform { - IOS = "ios", - ANDROID = "android", - DESKTOP = "desktop", - WEB = "web", - WEB_MOBILE = "web_mobile", - WEB_TABLET = "web_tablet", -} - -/** Quest sharing policy. */ -export const enum QuestSharePolicy { - SHAREABLE_EVERYWHERE = "shareable_everywhere", - NOT_SHAREABLE = "not_shareable", -} - -/** Quest bar UI states. */ -export const enum QuestBarState { - COLLAPSED = "collapsed", - EXPANDED = "expanded", - CLOSED = "closed", - SOFT_DISMISSED = "soft-dismissed", - RESET_TO_PREVIOUS = "reset-to-previous", -} - -/** Reasons for quest embed fallback display. */ -export const enum QuestEmbedFallbackReason { - EXCLUDED_QUEST = "excluded_quest", - UNKNOWN_QUEST = "unknown_quest", - NOT_SHAREABLE_QUEST = "not_shareable_quest", -} - -/** Console platform selection for quest tasks. */ -export const enum QuestConsolePlatformSelection { - CONSOLE = "CONSOLE", - DESKTOP = "DESKTOP", -} - -/** Call-to-action types for quest UI interactions. */ -export const enum QuestContentCTA { - LEARN_MORE = "LEARN_MORE", - SHOW_REWARD = "SHOW_REWARD", - CLAIM_REWARD = "CLAIM_REWARD", - GET_REWARD_CODE = "GET_REWARD_CODE", - COPY_REWARD_CODE = "COPY_REWARD_CODE", - ACCEPT_QUEST = "ACCEPT_QUEST", - COPY_QUEST_URL = "COPY_QUEST_URL", - MOBILE_SHARESHEET = "MOBILE_SHARESHEET", - TRACK_PROGRESS = "TRACK_PROGRESS", - CONNECT_CONSOLE = "CONNECT_CONSOLE", - CONNECT_CONSOLE_LINK = "CONNECT_CONSOLE_LINK", - VIEW_CONSOLE_CONNECTIONS = "VIEW_CONSOLE_CONNECTION", - VIEW_CONSOLE_CONNECTIONS_LINK = "VIEW_CONSOLE_CONNECTIONS_LINK", - VIEW_REQUIREMENTS = "VIEW_REQUIREMENTS", - SELECT_CONSOLE_PLATFORM = "SELECT_CONSOLE_PLATFORM", - SELECT_DESKTOP_PLATFORM = "SELECT_DESKTOP_PLATFORM", - DESELECT_PLATFORM = "DESELECT_PLATFORM", - DEFIBRILLATOR = "DEFIBRILLATOR", - DEFIBRILLATOR_RECONNECT_CONSOLE = "DEFIBRILLATOR_RECONNECT_CONSOLE", - OPEN_DISCLOSURE = "OPEN_DISCLOSURE", - WATCH_STREAM = "WATCH_STREAM", - WATCH_STREAM_CONFIRM = "WATCH_STREAM_CONFIRM", - REWARD_LEARN_MORE = "REWARD_LEARN_MORE", - OPEN_GAME_LINK = "OPEN_GAME_LINK", - OPEN_CONTEXT_MENU = "OPEN_CONTEXT_MENU", - OPEN_QUEST_HOME = "OPEN_QUEST_HOME", - QUEST_BAR_COPY_LINK = "QUEST_BAR.COPY_LINK", - CONTEXT_MENU_COPY_LINK = "CONTEXT_MENU.COPY_LINK", - REWARD_MODAL_COPY_LINK = "REWARD_MODAL.COPY_LINK", - CONTEXT_MENU_HIDE_CONTENT = "CONTEXT_MENU.HIDE_CONTENT", - CONTEXT_MENU_OPEN_GAME_LINK = "CONTEXT_MENU.OPEN_GAME_LINK", - CONTEXT_MENU_OPEN_DISCLOSURE = "CONTEXT_MENU.OPEN_DISCLOSURE", - CONTEXT_MENU_LEARN_MORE = "CONTEXT_MENU.LEARN_MORE", - HOW_TO_HELP_ARTICLE_XBOX = "HOW_TO_HELP_ARTICLE_XBOX", - HOW_TO_HELP_ARTICLE_PLAYSTATION = "HOW_TO_HELP_ARTICLE_PLAYSTATION", - VIEW_QUESTS = "VIEW_QUESTS", - EXPAND = "EXPAND", - COLLAPSE = "COLLAPSE", - START_QUEST = "START_QUEST", - TRANSCRIPT_ENABLE = "TRANSCRIPT_ENABLE", - TRANSCRIPT_DISABLE = "TRANSCRIPT_DISABLE", - CLOSED_CAPTIONING_ENABLE = "CLOSED_CAPTIONING_ENABLE", - CLOSED_CAPTIONING_DISABLE = "CLOSED_CAPTIONING_DISABLE", - SEEK_BACKWARD = "SEEK_BACKWARD", - SEEK_FORWARD = "SEEK_FORWARD", - WATCH_VIDEO = "WATCH_VIDEO", - QUEST_BAR_VIDEO_QUEST_PREVIEW = "QUEST_BAR_VIDEO_QUEST_PREVIEW", - QUEST_HOME_TILE_HEADER_WATCH_VIDEO = "QUEST_HOME_TILE_HEADER_WATCH_VIDEO", - REDEEM_REWARD = "REDEEM_REWARD", - VISIT_REDEMPTION_LINK = "VISIT_REDEMPTION_LINK", - SPONSORED_QUEST_SHEET = "SPONSORED_QUEST_SHEET", - GAME_PROFILE_OPEN = "GAME_PROFILE_OPEN", - GAME_STORE_OPEN_GAME_LINK = "GAME_STORE_OPEN_GAME_LINK", - MOBILE_ORBS_ONBOARDING_DC = "MOBILE_ORBS_ONBOARDING_DC", -} - -/** Sort methods for quest list display. */ -export const enum QuestSortMethod { - /** Default sorting by relevance. */ - SUGGESTED = "suggested", - MOST_RECENT = "most_recent", - EXPIRING_SOON = "expiring_soon", - RECENTLY_ENROLLED = "recently_enrolled", -} - -/** Filter types for quest tasks. */ -export const enum QuestTaskFilter { - VIDEO = "task_video", - PLAY = "task_play", -} - -/** Filter types for quest rewards. */ -export const enum QuestRewardFilter { - VIRTUAL_CURRENCY = "reward_virtual_currency", - COLLECTIBLE = "reward_collectible", - IN_GAME = "reward_in_game", -} - -/** Video playback progress states. */ -export const enum QuestVideoProgressState { - UNKNOWN = "UNKNOWN", - NOT_STARTED = "NOT_STARTED", - IN_PROGRESS = "IN_PROGRESS", - COMPLETED = "COMPLETED", -} - -/** Transcript fetch operation states. */ -export const enum QuestTranscriptFetchStatus { - NONE = "NONE", - FETCHING = "FETCHING", - SUCCESS = "SUCCESS", - FAILURE = "FAILURE", -} - -/** Result types from quest enrollment attempts. */ -export const enum QuestEnrollmentResult { - SUCCESS = "success", - CAPTCHA_FAILED = "captcha_failed", - UNKNOWN_ERROR = "unknown_error", - /** Enrollment already in progress. */ - PREVIOUS_IN_FLIGHT_REQUEST = "previous_in_flight_request", -} - -/** Reasons why a quest embed was not found. */ -export const enum QuestEmbedNotFoundReason { - NOT_FOUND = "not_found", - MOBILE_ONLY = "mobile_only", -} - -/** Tab filter types for quest list. */ -export const enum QuestFilterTab { - ALL = "all", - CLAIMED = "claimed", - /** Internal preview tool only. */ - PREVIEW_TOOL = "preview_tool", -} - -/** URL parameter types for quest filtering. */ -export const enum QuestFilterParamType { - TAB = "tab", - QUEST_ID = "quest_id", - SORT = "sort", - FILTER = "filter", -} - -/** Location identifiers for quest-related UI and tracking. */ -export const enum QuestLocation { - ACTIVITY_PANEL = "quests_bar_activity_panel", - QUESTS_MANAGER = "quests_manager", - QUESTS_CONSOLE_OPTIMISTIC_UPDATES_MANAGER = "quests_console_optimistic_updates_manager", - USER_SETTINGS_GIFT_INVENTORY = "user_settings_gift_inventory", - USER_SETTINGS_SEARCH_GIFT_INVENTORY = "user_settings_search_gift_inventory", - USE_QUESTS = "use_quests", - STREAM_SOURCE_SELECT = "stream_source_select", - MEMBERS_LIST = "members_list", - QUESTS_BAR = "quests_bar", - QUESTS_BAR_MOBILE = "quests_bar_mobile", - REWARD_CODE_MODAL = "reward_code_modal", - INGAME_REWARD_MODAL = "ingame_reward_modal", - COLLECTIBLE_REWARD_MODAL = "collectible_reward_modal", - ORBS_REWARD_MODAL = "orbs_reward_modal", - QUEST_PREVIEW_TOOL = "quest_preview_tool", - QUEST_PREVIEW_TOOL_2 = "quest_preview_tool_2", - QUESTS_MINOR_REWARD_CAPPING_CONFIG = "QUESTS_MINOR_REWARD_CAPPING_CONFIG", - QUESTS_CARD = "quests_card", - QUESTS_STORE = "quests_store", - QUEST_CHANNEL_CALL_HEADER = "quests_channel_call_header", - QUEST_HOME_DESKTOP = "quest_home_desktop", - QUEST_HOME_MOBILE = "quest_home_mobile", - QUEST_PROGRESS_BAR = "quest_progress_bar", - EMBED_MOBILE = "embed_mobile", - EMBED_DESKTOP = "embed_desktop", - QUEST_CONTEXT_MENU = "context_menu", - CODED_LINK = "coded_link", - QUEST_DISCLOSURE_MODAL = "quest_disclosure_modal", - DISCOVERY_SIDEBAR = "discovery_sidebar", - DISCOVERY_COMPASS = "discovery_compass", - BADGE = "badge", - COLLECTIBLES_SHOP_HEADER_BAR = "collectibles_shop_header_bar", - ORBS_ANNOUNCEMENT_MODAL = "orbs_announcement_modal", - CONFLICT_CHECKS = "conflict_checks", - VIDEO_MODAL = "video_modal", - VIDEO_MODAL_MOBILE = "video_modal_mobile", - GAME_WIDGETS_POPOVER = "game_widgets_popover", - PRIVATE_CHANNELS_LIST = "private_channels_list", - INTERNAL_TOOLING = "internal_tooling", - QUEST_HOME_MOVED_CALLOUT = "quest_home_moved_callout", - IN_APP_NAVIGATION = "in_app_navigation", - NAVIGATE_TO_QUEST_HOME_UTIL = "navigate_to_quest_home_util", - QUEST_DEEP_LINK_UTIL = "quest_deep_link_util", - YOU_TAB_PROFILE_HEADER = "you_tab_profile_header", -} From 61ece212253ae63e91341cb91244cae1113536cb Mon Sep 17 00:00:00 2001 From: Vendicated Date: Tue, 7 Apr 2026 02:46:11 +0200 Subject: [PATCH 13/14] bump version --- packages/discord-types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord-types/package.json b/packages/discord-types/package.json index 8c95d67492..fc602cd9e2 100644 --- a/packages/discord-types/package.json +++ b/packages/discord-types/package.json @@ -3,7 +3,7 @@ "author": "Vencord Contributors", "private": false, "description": "Typescript definitions for the webpack modules of the Discord Web app", - "version": "1.0.0", + "version": "1.0.1", "license": "LGPL-3.0-or-later", "types": "src/index.d.ts", "type": "module", From dc2162471667a6dbf1771d9922b07b18bf55d66a Mon Sep 17 00:00:00 2001 From: Vendicated Date: Tue, 7 Apr 2026 02:47:09 +0200 Subject: [PATCH 14/14] fix lint --- packages/discord-types/enums/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/discord-types/enums/index.ts b/packages/discord-types/enums/index.ts index 6a1b60c4a5..efa3f03e9d 100644 --- a/packages/discord-types/enums/index.ts +++ b/packages/discord-types/enums/index.ts @@ -5,7 +5,6 @@ export * from "./commands"; export * from "./guild"; export * from "./messages"; export * from "./misc"; -export * from "./quests"; export * from "./settings"; export * from "./user"; export * from "./voice";