feat(structures): add Presences structures #11411
feat(structures): add Presences structures #11411AsadHumayun wants to merge 39 commits intodiscordjs:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #11411 +/- ##
==========================================
+ Coverage 31.56% 32.39% +0.83%
==========================================
Files 386 395 +9
Lines 13944 14042 +98
Branches 1098 1104 +6
==========================================
+ Hits 4401 4549 +148
+ Misses 9409 9355 -54
- Partials 134 138 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Note to self: PR CI failed due to missing dependent files. This should be fixed when the PR is in a finished/ready to review state. |
|
Note / CI for latest commit here was cancelled due to GitHub Actions not being picked up by a runner.
|
|
Don't worry about that. |
|
I've gone ahead and added the tests for these structures. While adding the tests, they uncovered a mistake that I had previously made with one of the structures (and corrected it) [acad472]. For I did consider adding this as a remark on the class, but these are undocumented fields so I decided not to in the end. As we are already deciding not to expose deprecated API fields, I figured it made sense to also not expose these (IIRC discord.js as a library do not encourage use of undocumented API fields). One additional note I'd like to highlight: In case it doesn't embed, the I will also append this comment to the topmost comment on this PR so that it does not get missed. Apologies for this taking a while to get through, not been feeling great as of late. |
📝 WalkthroughWalkthroughThis PR introduces a comprehensive gateway presence structures implementation, adding multiple TypeScript classes for handling Discord gateway presence data. Classes include Activity-related substructures (Assets, Button, Emoji, Party, Secrets, Timestamps), GatewayPresenceUpdate, GatewayPresenceClientStatus, and a new ActivityFlagsBitField. All follow a consistent pattern extending the Structure base class with generic Omitted parameters and providing type-safe property accessors. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@packages/structures/__tests__/gatewayPresences.test.ts`:
- Around line 228-231: The test 'correct value for all getters' contains a
tautological assertion using expect(instance.url).toBe(instance.url); replace it
so the getter is compared against the source fixture: change to
expect(instance.url).toBe(data.url) (and similarly ensure other getters in the
same test compare to the corresponding properties on data, e.g., instance.label
-> data.label).
In
`@packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityParty.ts`:
- Around line 45-58: Remove the two invalid getters from
GatewayPresenceActivityParty: delete the createdTimestamp and createdAt
accessors (and any direct reliance on isIdSet or DiscordSnowflake.timestampFrom
in that class) because party.id is an arbitrary string, not a Snowflake; if
other code expects these properties, replace those usages with a proper source
of creation time or return undefined/null explicitly where creation time is not
available. Ensure GatewayPresenceActivityParty no longer exposes
createdTimestamp/createdAt and run/adjust any callers that referenced
GatewayPresenceActivityParty.createdTimestamp or .createdAt to avoid relying on
a fabricated timestamp.
In
`@packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityTimestamps.ts`:
- Around line 52-56: The endAt getter incorrectly casts the stored timestamp to
a string; change the cast in GatewayPresenceActivityTimestamps.endAt to use "as
number" (matching startAt) and ensure the returned Date is constructed from that
numeric timestamp or null if absent; update the endAt getter to mirror the
startAt getter's casting and null handling.
In `@packages/structures/src/gatewayPresences/GatewayPresenceUpdate.ts`:
- Around line 34-44: The TODO about the getter name can be removed and the
docblock clarified: update the JSDoc for the GatewayPresenceUpdate.get since
getter to state it returns a Date|null (e.g., "Time when the client went idle as
a Date object, or null if not idle"), remove the bracketed TODO note, and keep
the existing getter logic that reads this.sinceTimestamp and returns new
Date(timestamp) or null; reference the getter since and the raw numeric property
sinceTimestamp in your changes.
In `@packages/structures/src/gatewayPresences/index.ts`:
- Around line 6-12: Remove the inline TODO in the public barrel
(gatewayPresences index) and either open a tracked issue in the repo describing
the missing requestToSpeak[At] timestamp getter (reference the
VoiceState.requestToSpeakTimestamp pattern) or implement the getter now; ensure
the index export no longer contains the TODO comment and include the new issue
number or PR reference in the codebase or changelog so this work is actionable
outside the barrel.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (14)
packages/structures/__tests__/gatewayPresences.test.tspackages/structures/src/bitfields/GatewayPresenceActivityFlagsBitField.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivity.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityAssets.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityButton.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityEmoji.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityParty.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivitySecrets.tspackages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityTimestamps.tspackages/structures/src/gatewayPresences/Activity/index.tspackages/structures/src/gatewayPresences/GatewayPresenceClientStatus.tspackages/structures/src/gatewayPresences/GatewayPresenceUpdate.tspackages/structures/src/gatewayPresences/index.tspackages/structures/src/index.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-24T21:41:15.330Z
Learnt from: Qjuh
Repo: discordjs/discord.js PR: 11393
File: packages/structures/src/bitfields/ApplicationFlagsBitField.ts:13-15
Timestamp: 2026-01-24T21:41:15.330Z
Learning: For BitField classes, preserve numeric flags by using super.toJSON(true) when you need a numeric value. The toJSON(asNumber?: boolean) method returns a number when asNumber is true and a string otherwise, so always pass true to obtain a numeric representation for storage/comparison. This guidance applies to similar bitfield classes across the codebase (not just ApplicationFlagsBitField).
Applied to files:
packages/structures/src/bitfields/GatewayPresenceActivityFlagsBitField.ts
🧬 Code graph analysis (8)
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivitySecrets.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityButton.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/gatewayPresences/GatewayPresenceClientStatus.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/bitfields/GatewayPresenceActivityFlagsBitField.ts (1)
packages/discord.js/typings/index.d.ts (1)
BitField(663-680)
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityTimestamps.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/gatewayPresences/GatewayPresenceUpdate.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityAssets.ts (1)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivity.ts (3)
packages/structures/src/utils/symbols.ts (1)
kData(1-1)packages/structures/src/utils/type-guards.ts (1)
isFieldSet(25-32)packages/structures/src/bitfields/GatewayPresenceActivityFlagsBitField.ts (1)
GatewayPresenceActivityFlagsBitField(7-16)
🔇 Additional comments (12)
packages/structures/src/bitfields/GatewayPresenceActivityFlagsBitField.ts (1)
1-16: LGTM!The implementation correctly follows the BitField pattern. The
toJSON(true)override ensures numeric flags are preserved, which aligns with the established pattern for bitfield classes. Based on learnings: "For BitField classes, preserve numeric flags by using super.toJSON(true) when you need a numeric value."packages/structures/src/gatewayPresences/GatewayPresenceClientStatus.ts (1)
1-46: LGTM!The class follows the established Structure pattern consistently, with appropriate DataTemplate, constructor, and property getters for desktop, mobile, and web status fields.
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityTimestamps.ts (1)
1-40: LGTM!The imports, class structure, DataTemplate, constructor, and the
start/startAtgetters follow the established pattern correctly.packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityButton.ts (1)
1-42: LGTM!The implementation follows the established Structure pattern. The
@remarksdocumentation helpfully clarifies the API behavior difference between receiving and sending button data.packages/structures/src/gatewayPresences/GatewayPresenceUpdate.ts (1)
1-33: LGTM!The structure, DataTemplate, constructor, and remaining getters (
sinceTimestamp,status,afk) follow the established pattern correctly.Also applies to: 45-61
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityEmoji.ts (1)
1-74: LGTM!The implementation correctly handles snowflake-based timestamp derivation and CDN URL construction with appropriate null safety via
isIdSet. Theurl()method follows Discord CDN patterns properly.packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityParty.ts (1)
1-44: LGTM!The imports, class structure, DataTemplate, constructor, and
id/sizegetters follow the established pattern correctly. Thesizegetter documentation clearly explains the array structure.packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityAssets.ts (1)
27-67: LGTM — getters map cleanly to raw data.packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivity.ts (1)
33-132: LGTM — consistent accessors and safe flag handling.packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivitySecrets.ts (1)
27-46: LGTM — simple, consistent getters.packages/structures/src/gatewayPresences/Activity/index.ts (1)
1-7: LGTM — barrel exports look complete.packages/structures/src/index.ts (1)
6-6: LGTM — gatewayPresences export added.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityParty.ts
Outdated
Show resolved
Hide resolved
packages/structures/src/presences/Activity/ActivityTimestamps.ts
Outdated
Show resolved
Hide resolved
5d529bf to
eb1787a
Compare
|
Dropping a quick update on here before I forget discordjs/discord-api-types#1519 was merged to dapi-types today and the subsequent missing types have been added. However I imagine that it will still take some time for the new version of dapi-types to get released, and then additional time as the monorepo gets updated to use the new version of dapi-types once that does get released. We also need a definitive decision regarding moving away from the The changes were applied in this commit: refactor(structures)!: use xDate convention in favour of xAt |
This PR will aim to implement the
GatewayPresencestructures.Mentioning #10981 for visibility.
Feel free to leave any comments or feedback and I will address as-is but PR is in a very early draft state at the moment with only really the empty structures files laid out.
I will also be adding tests on this PR once I'm done with the structures.
Notes for when PR gets ready:
Prefer "activity secrets" or "activity's secrets"?
https://github.com/AsadHumayun/discord.js/blob/2ed8c63b71af9c388ac054eb111d41fd26c2b4e1/packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivitySecrets.ts#L10-L29
I've gone ahead and added the tests for these structures. While adding the tests, they uncovered a mistake that I had previously made with one of the structures (and corrected it) [acad472].
For
GatewayActivity, some properties were not exposed as getters as they were either not documented on the Discord API docs, or were marked@unstablein discord-api-tyes, e.g:https://github.com/discordjs/discord-api-types/blob/592503aa18a7b970bd6275ca59369b3b4c86b7be/payloads/v10/gateway.ts#L141-L146
I did consider adding this as a remark on the class, but these are undocumented fields so I decided not to in the end.
As we are already deciding not to expose deprecated API fields, I figured it made sense to also not expose these (IIRC discord.js as a library do not encourage use of undocumented API fields).
One additional note I'd like to highlight:
https://github.com/AsadHumayun/discord.js/blob/a22076a0d644443a0328212fc0f54c42f2a372ff/packages/structures/src/gatewayPresences/Activity/GatewayPresenceActivityAssets.ts#L70-L82
In case it doesn't embed, the
GatewayPresenceActivityAssetsstructure's documentation shows a fieldinvite_cover_image, which is not exposed by its corresponding discord-api-types structure; seehttps://github.com/discordjs/discord-api-types/blob/592503aa18a7b970bd6275ca59369b3b4c86b7be/payloads/v10/gateway.ts#L353-L355
I will also append this comment to the topmost comment on this PR so that it does not get missed. Apologies for this taking a while to get through, not been feeling great as of late.