You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
There are many issues that arise from mutating option objects, for example, they can mutate data in unexpected ways, see #5261 (comment). Furthermore, we do not document in which cases we mutate the options, and when we don't, which causes unconsistent behaviour.
We have been mutating options for a very long time, so the pattern is repeated and used across the entire library, which can take a lot of time to switch, and a single PR would probably be too big to test and review. However, it's also not consistent.
Describe the ideal solution
In fact, we also avoid mutating some options, which is the case for Guild#edit:
For all intents and purposes, there are simpler alternatives which not only reduce code clutter, but also optimise very well with V8. My favourite is to create a request object using the following pattern:
edit(options,reason){constdata={name: options.name,region: options.region,afk_timeout: data.afkTimeout,// ...};// Do something with data}
This pattern is a huge simplification of the previous, which works flawlessly as undefined fields are not serialized into JSON:
If we desire to future-proof and let users pass raw options (while we're at it), which can also work for properties that translate 1:1 with Discord's (in both key names and value types), the following pattern is also available, from a project I used to work on:
asyncedit({ icon, splash, banner, ...options},reason){constdata={icon: icon ? awaitresolveImageToBase64(icon) : icon,splash: splash ? awaitresolveImageToBase64(splash) : splash,banner: banner ? awaitresolveImageToBase64(banner) : banner,// More properties that need translating
...options};// Use data}
This way, if Discord were to add a new property we can patch, all we'd need to do, is to pass the raw property, at least, until we support it officially, this way users can have the option to use bleeding edge features while using stable code, not requiring client.api to bypass the data limitations (which is the other use-case for developers besides bypassing cache, which we're slowly fixing in the latest PRs).
This pattern also has the advantage that translating the code to strict TypeScript would be a lot easier, for example in the last case, we can do const data: RESTPatchAPIGuildJSONBody = { /* ... */ } to have it typed with Discord API's types.
Describe alternatives you've considered
I am open to more alternatives, please do not hesitate to come up with a better idea!
Note: I made this an issue and not a discussion because it's a discussion about a bug, which once resolved (via PRs), this issue will then be "resolved" automatically, something we lack with the discussions feature.
Additional context
Supersedes #5261 and extends its scope to the entire library.
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem? Please describe.
There are many issues that arise from mutating option objects, for example, they can mutate data in unexpected ways, see #5261 (comment). Furthermore, we do not document in which cases we mutate the options, and when we don't, which causes unconsistent behaviour.
We have been mutating options for a very long time, so the pattern is repeated and used across the entire library, which can take a lot of time to switch, and a single PR would probably be too big to test and review. However, it's also not consistent.
Describe the ideal solution
In fact, we also avoid mutating some options, which is the case for
Guild#edit
:discord.js/src/structures/Guild.js
Lines 1032 to 1080 in 9ffcd83
For all intents and purposes, there are simpler alternatives which not only reduce code clutter, but also optimise very well with V8. My favourite is to create a request object using the following pattern:
This pattern is a huge simplification of the previous, which works flawlessly as undefined fields are not serialized into JSON:
Another pattern is to use object destructure, which is used in other places:
discord.js/src/structures/GuildChannel.js
Lines 476 to 489 in 9ffcd83
If we desire to future-proof and let users pass raw options (while we're at it), which can also work for properties that translate 1:1 with Discord's (in both key names and value types), the following pattern is also available, from a project I used to work on:
This way, if Discord were to add a new property we can patch, all we'd need to do, is to pass the raw property, at least, until we support it officially, this way users can have the option to use bleeding edge features while using stable code, not requiring
client.api
to bypass the data limitations (which is the other use-case for developers besides bypassing cache, which we're slowly fixing in the latest PRs).This pattern also has the advantage that translating the code to strict TypeScript would be a lot easier, for example in the last case, we can do
const data: RESTPatchAPIGuildJSONBody = { /* ... */ }
to have it typed with Discord API's types.Describe alternatives you've considered
I am open to more alternatives, please do not hesitate to come up with a better idea!
Additional context
Supersedes #5261 and extends its scope to the entire library.
The text was updated successfully, but these errors were encountered: