74345c7 chore: types for new message builder - vladfrangu
#@discordjs/builders
1757 messages ยท Page 2 of 2 (latest)
Either needs to accept all top-level component types (ugly) or simply be removed. Neither ActionRowBuilder nor ChatInputCommandBuilder have a set method for "replacing" the existing components/options. That can already be achieved with spliceComponents() after all.
sticker_ids: z.array(z.never()).nullish(),
Any reason why this doesn't allow APIMediaGalleryComponent as input type?
embeds: z.array(z.never()).nullish(),
These can't exist as top level components, only in ActionRows or as accessory of a Section. SelectMenus can only exist in ActionRows.
Yes, I messed it up lol. Good catch with this and the ret, tyyy
Wouldn't max(0) still be needed
I could see us supporting a setComponents with all types but I feel like that's just horrible, and should probably stick to add (maybe add in a clear method so you can start with a blank slate)?
But I'd ask @didinele's thoughts too on this. I could easily implement a setComponents i think
Doubt it, you can't pass a value that satisfies never, so the predicate should insta reject on the first value passed in.
Sorry, I'm a bit lost on what the problem is here
The problem is that this is a generic "set the components array to this arbitrary list of components" when we have specific addXComponent methods for all the other ways. As already stated we don't have a set method in ActionRowBuilder or ChatInputCommandBuilder or ContainerBuilder or SectionBuilder. So why would we suddenly have one in MessageBuilder?
I see. I added it with the thought that there's only ActionRows so it sort of made sense. I'm for removing it in this case.
- Added
clearParse,clearRoles, andclearUsersmethods to theAllowedMentionsBuilder, since passing an empty array and omitting the these fields behave differently - Strictened assertions
- Removed
AttachmentBuilder#clearId, as it is a required field - Added missing
MessageBuilder#setEmbeds - Added missing
MessageReferenceBuilder#setFailIfNotExists - Improve/fix documentation
- Consistency:tm:
I tested it and while it works, I would much rather stick to explicitly overriding the array instead on relying on splicing to replicate a set operator
This (and the other changes like this) fall under the "Consistency:tm:" part of my description
Well I am against relying on splice to do a set ๐คท, would love to hear other's thoughts.
f5fb1f9 fix(textInput): value must be at least 1 in length - Jiralite
Please describe the changes this PR makes and why it should be merged:
Will throw this error otherwise: data.components[1].components[0].value[BASE_TYPE_MIN_LENGTH]: Must be 1 or more in length.
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
I don't see a problem with using the splice method, but if we're not going to, then we should update it everywhere else too.
* url: 'https://cdn.discordapp.com/embed/avatars/4.png',
This feels more idiomatic as it is not an inverse check:
return (flags & MessageFlags.IsComponentsV2) === 0
And the tsdoc.json in builders is still needed for eslint to recognize the @mixes tag. But it should simply extend the api-extractor version.
7e17995 Update packages/builders/src/messages/Assertion... - vladfrangu
2bf75d7 Update packages/builders/src/components/v2/Thum... - vladfrangu
I think this can be decided and updated in another pull request. Doesn't seem like a good reason to block merging this
On second thought this relies on the assumption that the passed function returns the same builder it gets passed. While that should normally the case we donโt actually require it anywhere yet. If you create a new Builder inside the callback and return that it should work as intended, but wouldnโt with this change.
Same applies to all the other places this was done
That doesnโt really change the underlying issue, youโre now restricting people from returning stuff from the callback. Why? This seems to me like a classic example of โbreaking change just because we canโ. Whatโs the benefit?
Especially since itโs not consistent with the rest of the builders anymore
components: components.map((component) => component.toJSON(false)),
accessory is correct since sectionPredicate's accessory only validates the type
components: components.map((component) => component.toJSON(false)),
items: items.map((item) => item.toJSON(false)),
Whenever sub-items are defined in the root predicate, we pass false
9291c6b Apply suggestions from code review - vladfrangu
abc5d99 feat: components v2 in builders (#10788) - vladfrangu
Please resolve conflicts!
youโre now restricting people from returning stuff from the callback. Why?
It's an update function. If you want to create a new builder, use set
Whatโs the benefit?
Consistency
This seems to me like a classic example of โbreaking change just because we canโ
This is not released.
Especially since itโs not consistent with the rest of the builders anymore
Every single update* function:
https://github.com/discordjs/discord.js/blob/abc5d99ce89bad64d0ad0d7d68310e61...
[discordjs/discord.js] New branch created: docs/builders
Please describe the changes this PR makes and why it should be merged:
Status and versioning classification:
This would document the wrong parameters, as data now only refers to the rest withoutcomponents. For documentation purposes it would be better to name the full parameter data and destructure first thing in the body. Similar to how it was in other constructors before this change.
messed up docs, see other comment
Please describe the changes this PR makes and why it should be merged:
Adds a missed export for the Container component in the builders package
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
891fe27 fix(builders): export container component (#10844) - SammyWhamy
0903e6d chore(builders): release @discordjs/builders@1.... - vladfrangu
[discordjs/discord.js] New tag created: @discordjs/[email protected]
[discordjs/discord.js] New tag created: @discordjs/[email protected]
27871c7 chore(builders): forward-port release metadata ... - vladfrangu
* Creates a new boolean option.
* Creates a new user option.
* Creates a new integer option.
* Creates a new channel option.
* Creates a new string option builder.
* Creates a new attachment option.
Please describe the changes this PR makes and why it should be merged:
Removes the assertion limiting amount of components in a container
Status and versioning classification:
93cf772 chore(builders): release @discordjs/builders@1.... - vladfrangu
[discordjs/discord.js] New tag created: @discordjs/[email protected]
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandOptionWithAutocompleteMixin}
* @mixes {@link ApplicationCommandOptionWithChoicesMixin}\<{@link string}\>
* @mixes {@link CommandBuilder}\<{@link discord-api-types/v10#(RESTPostAPIContextMenuApplicationCommandsJSONBody:interface)}\>
* @mixes SharedName
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandNumericOptionMinMaxValueMixin}
* @mixes {@link ApplicationCommandOptionWithAutocompleteMixin}
* @mixes {@link ApplicationCommandOptionWithChoicesMixin}\<{@link number}\>
Updated builders to use zod v4 which is actually v3.25
Replaced zod-validation-error with z.prettifyError()
Haven't upgraded it to the latest version since it has type errors (on the library itself) https://github.com/colinhacks/zod/issues/4624
flags are ints, idk how we didn't catch this before
Do we really need the cast or can we just cast the returned array as const and achieve the same thing?
This is absolutely not true, you CAN set the flag and not use components v2 (aka send a message with just components: [actionRowsHere])
Those errors are fixed, upgrade to 3.25.56 ๐
This is a fine solution but there is first-party regex-based hostname & protocol validation if you want it:
Yes, we do need the cast. This is because the return type of Object.fromEntries() disregards the type of the keys.
https://github.com/microsoft/TypeScript/blob/51dcd9001d9dceb98d248f574f39f57497a44968/src/lib/es2019.object.d.ts#L8
This is great, thanks for bringing it up!
But then the cv2 predicate would be true in the union below and this error wouldn't propagate. If it does propagate there was more than just components set.
b2356eb fix: remove maximum limit - Jiralite
Please describe the changes this PR makes and why it should be merged:
-
https://github.com/discord/discord-api-docs/pull/7534
Status and versioning classification: -
Code changes have been tested against the Discord API, or there are no code changes
-
I know how to update typings and have done so, or typings don't need updating
@discordjs/builders
5ad4dc6 fix: remove regex validation - Jiralite
Please describe the changes this PR makes and why it should be merged:
According to #internals message, validation should not be done for context menu commands.
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
c33cd33 test: remove incorrect test - Jiralite
39568d7 fix: remove name check for context menu commands - Jiralite
.regex(/\S/)
it suffices to match one character, the context is irrelevant
Please describe the changes this PR makes and why it should be merged:
Using discord-api-types v10 for imports instead of being mixed.
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
c696769 feat: enforce limit of URLs for link buttons - Jiralite
Please describe the changes this PR makes and why it should be merged:
-
https://github.com/discord/discord-api-docs/pull/7301
Status and versioning classification: -
Code changes have been tested against the Discord API, or there are no code changes
-
I know how to update typings and have done so, or typings don't need updating
Which application or package is this feature request for?
builders
Feature
Adding a .isEmpty() method to container builders would be a nice addition.
Ideal solution or implementation
it would check if the container does not have any child components at all.
Alternative solutions or implementations
No response
Other context
No response
In what context would you not know what you have added? Can we see an example of where this would be useful?
In what context would you not know what you have added? Can we see an example of where this would be useful?
i have this paginator which accepts an array of container snippets (functions which adds components to a container) if somehow, all of these would just leave the container blank after being assembled, it would not go too well for me.
also this shouldn't be that hard to implement, it just checks if the data.components array is empty.
i honestly might make a little pull request for this
Please describe the changes this PR makes and why it should be merged:
Adds an isEmpty method to the ContainerBuilder class, which checks if the container has no child components.
This provides a simple way for developers to verify container state without manually inspecting its contents.
Status and versioning classification:
- This PR changes the library's interface (methods or parameters added)
Considering this doesn't even serve as a type-guard of some sort, may I ask why you can't just access <ContainerBuilder>.components.length yourself? I see no need for this method considering it exposes no new information and doesn't do anything actually complex.
I see your point โ the method doesnโt expose new functionality beyond checking .components.length.
My intention was to provide a convenience/QoL helper for readability and to make the intent clearer in code (e.g., if (container.isEmpty()) reads more naturally than if (container.components.length === 0)).
That said, I understand if this doesnโt fit the libraryโs design philosophy, and Iโm fine with closing the PR if you decide its unnecessary.
This and the splice don't make sense this way. The current {set/splice}ActionRows should be renamed to just {set/splice}Components and accept both types.
splice in its current form makes no sense, because it claims to do something it doesn't. The implementation replaces whatever components are at the indices, not necessarily labels.
760009a fix(Label): Set instead of adding - Jiralite
28be8ad chore: update label max length - Jiralite
44a5fb2 fix(Modal): remove deprecated behaviour - Jiralite
aab7e3a docs(Label): update constructor - Jiralite
9ce9e66 chore(builders): release @discordjs/builders@1.... - vladfrangu
[discordjs/discord.js] New tag created: @discordjs/[email protected]
Thank you for your efforts, however, we will not be moving forward with this change.
Which application or package is this feature request for?
builders
Feature
When creating message content, code can look very messy and possibly unclear. For example:
// this is a VERY simple example, code may be far larger than this with complex logic
interaction.reply(`${heading("Here is a list:")}\n${unorderedList(["something 1", "something 2"])}`);
Note: technically you could make a content variable and use += to make it easier to read (useful for conditiona...
this omit looks wrong, while I understand action rows are deprecated we shouldn't juggle types like this
f615f79 fix: text inputs no longer have a label - Jiralite
const resolved = labels.map((label) => resolveBuilder(label, LabelBuilder));
...labels: (APILabelComponent | LabelBuilder | ((builder: LabelBuilder) => LabelBuilder))[]
* @param labels - The replacing label objects
[discord.js] Branch feat/more-labels-in-builders was force-pushed to `ce7cc13`
de3a9fc docs: fix bad reference - Jiralite
[discord.js] Branch feat/more-labels-in-builders was force-pushed to `b722b62`
82f211b fix: update files - Jiralite
b8ebdd7 feat: add support - Jiralite
[discord.js] Branch feat/builders-modal-label-file was force-pushed to `fe6a58d`
e0d7915 docs: correct examples - Jiralite
58374c7 fix(MappedComponentTypes): fix description - Jiralite
There was no predicate for ids. The lone test I have added is expected to fail, and would otherwise succeed without this change.
All predicates are exported (part of the public API), and these were missing type.
Got the idea from a random convo I saw, I'd say it's a valuable addition. Method name inspired from zod, we can change if anyone has a better idea
This should take a number, unless this is showcasing something?
I'd say it's a valuable addition.
Maybe add a test case of a simple & useful scenario? That could be nice to see! Reason I ask is because the documentation given for refining doesn't seem to solve a problem?
oh yeah. I hit tab on that completion without thinking about it.
Maybe add a test case of a simple & useful scenario? That could be nice to see! Reason I ask is because the documentation given for refining doesn't seem to solve a problem?
Will do. But the idea is that when you have a large block of logic that does a lot of conditional work on a builder, it can feel a bit "disconnected" and other logic can sneak in the middle, you also can end up introducing a lot of variables.
With refine you can get rid of a lot of that:
<TextBasedChanne...
I proposed this idea originally in the "random convo", (and I think I first saw the idea somewhere else). The main reason is I just otherwise find it pretty inconvenient when I'm working with a long chain of builder method calls.
In my experience, it's sometimes annoying to conditionally modify the builder with external if statements and all that, rather than being able to put everything in one long expression. Especially when dealing with components nested inside other components/objects...
I'd say it's a valuable addition.
Maybe add a test case of a simple & useful scenario? That could be nice to see! Reason I ask is because the documentation given for refining doesn't seem to solve a problem?
I proposed this idea originally in that "random convo", (and I think I first saw the idea somewhere else). The main reason is I just otherwise find it pretty inconvenient when I'm working with a long chain of builder method calls.
In my experience, it's sometimes annoying...
There's no difference between class X extends Refineable and class X extends Mixin(Refineable)... it's applied as a mixin where multi-inheritance is needed.
adebc70 feat(builders): modal select menus - vladfrangu
[discordjs/discord.js] Pull request opened: #11138 feat(builders): modal select menus in builders v1
Please describe the changes this PR makes and why it should be merged:
Status and versioning classification:
b314218 chore: fix test - vladfrangu
3d0fe3e fix(builders): correct assertion for select men... - vladfrangu
Please describe the changes this PR makes and why it should be merged:
Small mistake, happens to the best of us
Status and versioning classification:
96e0f05 fix: actually fix the logic - vladfrangu
517f58e fix: move setRequired up - vladfrangu
e99f57b chore: forwardport https://github.com/discordjs... - vladfrangu
* Sets whether this select menu is required.
* @param required - Whether this select menu is required
I would say to use the label builder, not a placeholder.
Feel free to suggest a better message then! I just defaulted to the new thing
The placeholder is something different. The label is what appears on the top of the text input. That's why I suggested to use the label component as that's where that text area will be from now onwards:
* @deprecated Use a label builder to create a label (and optionally a description) instead.
7375637 fix: id validator being required - vladfrangu
cb96cef fix: validators 2 - vladfrangu
94877bf Apply suggestion from @Jiralite - Jiralite
0b179c3 Apply suggestion from @Jiralite - Jiralite
966a14e Apply suggestion from @Jiralite - Jiralite
11199cc Apply suggestion from @Copilot - Jiralite
6906fec Apply suggestion from @Copilot - Jiralite
9a60e40 chore(builders): release @discordjs/builders@1.... - Jiralite
[discordjs/discord.js] New tag created: @discordjs/[email protected]
282209d fix(builders): text display component support f... - vladfrangu
Please describe the changes this PR makes and why it should be merged:
Woopsy XD, forgot to add support for text displays in modal builder
Status and versioning classification:
99b8436 fix(builders): text display component support f... - vladfrangu
8b9bb25 chore(builders): release @discordjs/builders@1.... - vladfrangu
[discordjs/discord.js] New tag created: @discordjs/[email protected]
dd1e3c9 chore(builders): release @discordjs/builders@1.... - Jiralite
[discordjs/discord.js] New tag created: @discordjs/[email protected]
Got any example of those "other mixins" we do that with? Because to me that is wrong too. Calling a base class a mixin I mean
[discord.js] Branch feat/builders-modal-label-file was force-pushed to `d0c485b`
341719d chore: remove errors - Jiralite
Please describe the changes this PR makes and why it should be merged:
An empty value may be set when not constrained by min_length.
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
I cannot reproduce this on v14. Furthermore, your code example is incorrect also: text input builders must have a style. Ergo, I believe you are not actually supplying what you are doing.
Can you provide what you are actually doing? My testing (copied and pasted your code sample with style):
import {
ModalBuilder,
LabelBuilder,
TextInputBuilder,
TextInputStyle,
} from "discord.js";
const modal = new ModalBuilder()
.setCustomId("some_custom_id")
.setTitle("some tit...
@Jiralite i simplified my code sample. The code that I'm actually using looks like this:
export function getEvalModal(locale: string, depth: string | number, code?: string) {
return new ModalBuilder()
.setCustomId('eval')
.setTitle(t('eval.modal.title', { lng: locale }))
.addLabelComponents(
new LabelBuilder().setLabel(t('eval.modal.code', { lng: locale })).setTextInputComponent(
new TextInputBuilder()
.setCustomId('code')
.setPlaceholder...
Can you provide your full error? You also only supplied the first line. Can you send the whole stack trace?
Can you provide your full error? You also only supplied the first line. Can you send the whole stack trace (and never omit it)?
โ Too small: expected string to have >=1 characters
โ at component.value
err: {
"type": "ValidationError",
"message": "โ Too small: expected string to have >=1 characters\n โ at component.value: [\n {\n \"origin\": \"string\",\n \"code\": \"too_small\",\n \"minimum\": 1,\n \"inclusive\": true,\n \"path\": [\n \"component\...
I am curious if you are actually using v14 now.
Can you log import version from discord.js and log in?
import { version } from "discord.js";
console.log(version);
I am curious if you are actually using v14 now.
Can you import
versionfrom discord.js and log it?import { version } from "discord.js";
console.log(version);
I'm currently using the latest dev version
Please review the context of my reply: https://github.com/discordjs/discord.js/issues/11181#issuecomment-3410049253
I said I was unable to reproduce this on v14 and this issue states it is reproducible on v14. You need to prove it is reproducible on v14โnot any other version.
Please review the context of my reply: #11181 (comment)
I said I was unable to reproduce this on v14 and this issue states it is reproducible on v14. You need to prove it is reproducible on v14โnot any other version.
my bad. anyways, it doesn't work on the dev version. i can't test this in v14 using my current codebase.
Okay, it does work using v14.23.2
it only seems to be the dev version that has this issue
The issue is right here, min length of 1
See the linked pull request, that is already addressed. These comments were because you opened the issue as reproducible in v14.
Basically, you should not open issues guessing, as this conversation was entirely pointless.
This is still a valid issue, there should not be a min length of 1.
Apart from my comments LGTM
Ditto here. We also don't do this on SelectMenuBuilders.
I don't think this should be here. If you want to revert your change to minValues it's simply setMinValues(1) and should be explicit.
We have clear methods in other builders for similar things, no?
See my other comment:
We also don't do this on SelectMenuBuilders.
so no, we don't
Text inputs can be used in modals and they may clear their minimum and maximum length. Should that be removed then?
No, we should add clear methods to everything that can be undefined ๐คท
4be5196 refactor: use idPredicate - Jiralite
Please describe the changes this PR makes and why it should be merged:
Using changes made in #11109.
Status and versioning classification:
- Code changes have been tested against the Discord API, or there are no code changes
- I know how to update typings and have done so, or typings don't need updating
83ec0fd refactor: Use idPredicate for file uploads (#... - Jiralite
e132914 feat: support file uploads - Jiralite
aeef894 style: sort imports - Jiralite
Missing setFileUploadComponent
444f415 feat(Label): add method - Jiralite
1417c49 feat: v1 builders file uploads support (#11196) - Jiralite
fe7f91d chore(builders): release @discordjs/builders@1.... - Jiralite
[discordjs/discord.js] New tag created: @discordjs/[email protected]
4da0c03 chore: add guide issue template (#11247) - almostSouji
3122da4 ci(deprecate-tag): Remove comment (#11246) - Jiralite
dafdc78 chore: upgrade actions/setup-node to v6 and nod... - almeidx
3cb3eca docs(BaseSelectMenu): Adjust maximum wording (#... - Jiralite
868fe04 Merge branch 'main' into issuetemplate/guide - almostSouji
Will the builders/1.x branch redundant.
d96e2b5 refactor: proper key management - didinele
67f7050 chore: add missing remarks - didinele
Which package is this bug report for?
builders
Issue description
One of many examples
Code sample
Versions
Current main branch of builders
Issue priority
Medium (should be fixed soon)
Which partials do you have configured?
Not applicable
Which gateway intents are you subscribing to?
Not applicable
...
close #11289
Please describe the changes this PR makes and why it should be merged:
This PR adds proper Snowflake validation to the builders package. Previously, multiple instances were using plain z.string() for Snowflake IDs, which didn't validate that the values are numeric strings as required by Discord's Snowflake format.
Changes:
- Added
snowflakePredicate(z.string().regex(/^\d{17,20}$/)) to validate Snowflake format - Replaced
z.string()with `snowflakePredica...
Fixed the incorrect Zod usage in the component predicates. Replaced the invalid
z.literal([...]) patterns with proper unions, switched to z.nativeEnum for
runtime enums, and moved the old .check() logic to superRefine().
This cleans up the schemas and fixes the issue with select menu default values.
- fixes:#11289
Iโve opened a PR #11291 with a fix for this. The incorrect Zod literals and enum
handling have been updated, and the select menu default value checks should now
work properly.
This seems like a mix of v3>v4 and v4>v3 changes somehow, what made you do these changes?
The literal([...]) syntax is fine and encouraged in zod 4.
nativeEnum() is deprecated in zod v4, enum() was correct here, as it is overloaded to also do this in v4.
Also was fine with literal([...]) before
Thank you for the clarification @Qjuh
-
I actually see now that z.literal([...]) and z.enum() were already working correctly in v4. I've reverted those changes.
-
I've kept the .strictObject() fixes (which was the original bug) and the snowflakePredicate usage for proper Discord ID validation. Is my current applied approach correct now?
-
Fixes:#11289
Which package is this bug report for?
builders
Issue description
https://discord.js.org/docs/packages/builders/1.13.0/ContainerBuilder:Class#constructor,
Here .addComponents is shown which doesn't exist
I didn't check if there are any other instances of this elsewhere too
Code sample
Versions
Not applicable
Issue priority
Low (slightly annoying)
Which partials do you have configured?
Not applicable
Which gateway intents are you subsc...
Updated documentation comments for the ContainerBuilder class, including examples and clarifications.
Please describe the changes this PR makes and why it should be merged:
Status and versioning classification:
Please keep your low quality AI slop out of PRs on this repository, thank you.
I believe this should accept a snowflake too:
@rie03p looks like something is not quite right because tests are failing, may need to update them?
@Jiralite You're right! The validation is now working correctly and rejecting invalid IDs like 'hi!' and '0'. I've updated the existing tests to use valid IDs (numbers or proper snowflakes) so they pass with the new validation.
46f8f3c fix: allow subcommand with groups - Jiralite
Subcommands may be mixed with subcommand groups at the top level. This pull request allows this and adds a test for it.
f4fcc4f refactor: move full validation to ChatInputComm... - almeidx
Supersedes #11303
Made the chatInputCommandPredicate validate the full structure, including options, so users that may be using this predicate can actually validate Chat Input Commands
Which application or package is this feature request for?
builders
Feature
In light of #11304, it's probably worth checking if we can easily similarly address all other places where the package behaves this way for the sake of consistency. It's OK if the outcome is that we leave some of them as-is, but internal sentiment is we should be moving to always toJSON(false)
Relevant investigation sites:
- [ ] ActionRow
https://github.com/discordjs/discord.js/blob/02fc101069aed994f7ee45...
Investigate whether the validation override can be changed to false.
Investigate whether the validation override can be changed to false.
Investigate whether the validation override can be changed to false.
Investigate whether the validation override can be changed to false.
Investigate whether the validation override can be changed to false.
Investigate whether the validation override can be changed to false.
2f710d4 refactor: use strictObject and add missing type - almeidx
[discord.js] Branch refactor/validation-on-chatinputcommand was force-pushed to `18c8ae9`
[discord.js] Branch refactor/validation-on-chatinputcommand was force-pushed to `4772957`
Iโve fixed the tests that were failing.
export const snowflakePredicate = z.string().regex(/^[0-9]\d{16,20}$/);
0 is perfectly valid in a snowflake
0 is perfectly valid at the start?
Also, disagree on increasing the limit. The API doesn't even accept snowflakes that large
0 is perfectly valid at the start?
I do not like that we have that at the start, I completely missed that its two parts... But also why not? technically even 0 is a valid snowflake (and can be used in pagination to use as a starting point)
This is builders though. Snowflakes here are not used for pagination. They're used for emoji ids, select menus (role ids, channel ids, and user ids)... I'd argue someone is building something not at the start of Discord's time, so realistically, 0 is invalid.
๐คท, my two cents is that this should've been \d{17,20} and not overly complex but w/e (plus for attachments it can literally be just \d+ when creating)...
Creating attachments will satisfy 0:
When you edit attachments, you include the attachment id to keep, which again, can't be 0.
This PR alters that too, soo maybe that needs to be undone? Also you miss the point, the string "0" will work too
It alters it because we're being strict on input: snowflakes for editing and numbers for uploading, which is the documented way.
Also you miss the point, the string "0" will work too
0 or "0", it's all stringified anyway:
Someone shouldn't be passing "0" though, right? That seems like a mistake...
Someone shouldn't be passing "0" though, right? That seems like a mistake...
yup. IMO the meaning of the ID is either snowflake (as in, literal, actual snowflake when editing, already uploaded attachment) or index, as in "im uploading this now, its the nth file"
Opened #11314 to track that.
- Resolvesย #11316
- Resolves custom id buttons being enforced to have labels. They may have either an emoji or a label
This also needs the refine treatment no?
21faf03 fix: also add refinement to link buttons - Jiralite
Done with 21faf03b6de6be968055ff074b176f0c33685a5d.
Backports #11317.
Buttons are correctly validated in this version.
Example:
This should fail as there are no options. However, it passes because .toJSON() is not called. This test is not working as expected.
We should investigate the tests to ensure they are being correctly tested.
Resolves #11319. I believe everything has been caught.
@vladfrangu If you are fine with the above, mind applying one of these?
export const snowflakePredicate = z.string().regex(/^(0|[1-9][0-9]*)$/);
export const snowflakePredicate = z.string().regex(/^(0|[1-9]\d{16,18})$/);
It has been brought up that we should be using strictObject() for validation instead of just object().
0 is perfectly valid in a snowflake, and could increase the limit too
d59857e fix(builders): add proper snowflake validation ... - rie03p
ace834b fix: Adjust label predicates and fix buttons em... - Jiralite
jsonOptionValidator is not used anywhere anymore, but since we export it it would be breaking to remove it. deprecate maybe?
Shouldn't this be defined as a const on top too, for the case the limit changes this might otherwise easily be missed.
I noticed this to, but also no other validators have documentation on it. I'm sure there's more instances... just didn't think it's worth to do it. But if we really want to, we can?
Done with 5b8d5265e8bd56507ce0cab1995a34a17c9b666b.
what's the reason for not using extend() here and in the following predicates?
b94c5fc docs(jsonOptionValidator): deprecate - Jiralite
Just did it anyway: b94c5fc03e68a06abf84af224133cba46da7d72c
8162ae8 test: Add toJSON() to tests (#11321) - Jiralite
a57b4d4 fix: Allow mixing subcommands with subcommand g... - Jiralite
While testing this out I found we don't export the SelectMenuAssertions at all, so this replacement can't be used unless we add that export.
6c25884 fix: export selectMenuStringOptionPredicate - Jiralite
export * as SelectMenuAssertions from './components/selectMenu/Assertions.js';
* @deprecated Replaced with {@link SelectMenuAssertions.selectMenuStringOptionPredicate}.
This doesn't show up in the documentation and this doesn't show a link in VSCode, so what's the point of this?
I wasn't able to check whether IDEs would show this correctly. If VSCode doesn't then I guess it's pointless indeed.
4476fad chore(builders): release @discordjs/builders@1.... - Jiralite
[discordjs/discord.js] New tag created: @discordjs/[email protected]
Description
Fixes #11314
AttachmentBuilder.getRawFile() was using a falsy check (this.data.id ? ...) to determine whether the attachment ID existed.
Because 0 is a valid ID but is falsy in JavaScript, the method incorrectly treated it as missing, producing an invalid file reference.
This PR updates the condition to properly detect the presence of the id property, allowing 0 to be handled correctly.
Changes
- Replaced the falsy check
this.data.id? ...with a pro...
Almeida approved but I insist on their proposed diff.
Almeida approved but I insist on their proposed diff.
5e77368 feat: allow empty allowed mentions - Jiralite
[discord.js] Branch feat/allow-empty-allowed-mentions was force-pushed to `18be381`
Per the documentation, all keys are optional.[^1] This means {} should be an allowed value (and does work to prevent everything). To achieve this, you would have to do this:
const message = new MessageBuilder()
.setContent('test')
.setAllowedMentions((allowedMentions) => allowedMentions);
With this pull request, supplying nothing will default to {}:
const message = new MessageBuilder()
.setContent('test')
.setAllowedMentions();
[...
From https://zod.dev/api?id=extend
This approach has a few advantages:
- It uses language-level features (spread syntax) instead of library-specific APIs
- The same syntax works in Zod and Zod Mini
- It's more tsc-efficient โ the .extend() method can be expensive on large schemas, and due to a TypeScript limitation it gets qua...
[discord.js] Branch refactor/validation-on-chatinputcommand was force-pushed to `3f449bc`
[discord.js] Branch refactor/validation-on-chatinputcommand was force-pushed to `273547b`
My feelings are very mixed on this... I feel like this is a bit confusing, I'd def prefer empty object in my own code, but I suppose I'm not super against it.
I like it better honestly, probably makes sense to use it in some other places too
fa43c40 fix(builders): handle 0 as valid attachment ID ... - Exodo0
d90a86a fix(Message): Optional parameter for setting al... - Jiralite
Which package is this bug report for?
builders
Issue description
Currently minimal length for emoji name is 2 (https://github.com/discordjs/discord.js/blob/427636ee7555a92fa9780cd78f28cc0037b9241c/packages/builders/src/components/Assertions.ts#L8), but some emoji, like โ
have 1 length, so if you try to use this emoji in buttons or other components, a validation error will appear.
Code sample
Versions
- discord.js - 15.0.0-dev.1766016119-427...
5dacf1a fix: minimum 2 characters for custom emojis - Jiralite
Fixes a regression introduced with #11371 that allowed custom emojis to have a name of length 1.
d762763 fix: reintroduce min(1) - Jiralite
For custom emojis, does discord actually validate their name? Because when sending a message, we can still do <:_:[id]> no?
They don't validate, but (some) clients viewing the emote will grab the name from cache.
Still, they are documented as 2-32 long in name, you cannot name them as single chars, and our previous hacky workaround of ignoring this and using _ would break markdown in places.
FYI the name field doesn't seem to be validated at all by the API for custom emojis. You can send numbers, booleans, empty strings, very large strings, or null. Seemingly anything but an object or an array
Did you try uploading an emoji?
{
"message": "Invalid Form Body",
"code": 50035,
"errors": {
"name": {
"_errors": [
{
"code": "BASE_TYPE_BAD_LENGTH",
"message": "Must be between 2 and 32 in length."
}
]
}
}
}
I sent a button component with a custom emoji, which is one of the predicates this pull request is modifying
Right, and how did you get that custom emoji? It was uploaded somewhere.
@Jiralite i think they're referring to the API validating the emoji name when creating the message, not the emoji structure itself...
then lets mark this as optional please, in case some class forgets to define it
When is this fix getting pushed?
The PR has been merged and released since Nov 30: https://github.com/discordjs/discord.js/releases/tag/%40discordjs%2Fbuilders%401.13.1 make sure you've updated your local version
Does this mean i have to use the builders package? since i normally always just use discord.js package
No, since discord.js already installs the latest /builders v1 for you, you most likely just have an outdated version of it locally. Reinstalling (deleting node_modules) should download the new latest version
57d9ae7 fix: disable per option validation on chat inpu... - almeidx
Change misssed from:
- #11304
Supercedes #11312
Resolves #11309
these Discord features are (as of writing this) still in early access
As far as I can see the main aspect of this PR has been done and merged by #11290 already. The change from check() to superRefine() is merely syntactical sugar (since superRefine calls check internally to do the exact same thing). So the only thing this really changes are the strictObject assertions, but I don't see what issue they fix, as that would only make it throw instead of stripping extraneous properties.
This shouldn't validate on addOptions call already, because then it'll throw as soon as you add options one by one, because having only one options is invalid. Same applies to checkbox group but less severe. But even there a builder should be allowed to be in a state where it has more or less options than allowed, as long as that changes before the builder gets turned into JSON.
throw new RangeError('There can be at most one default option in a radio group');
There doesn't have to be a default set.
Is there any ETA for this one?
DJS never provides ETAs. Feature PRs usually sit for about two weeks to a month after release before maintainers decide to merge them.
Why are radio components in here? Seems the filename is misleading?
I kinda refer to the whole set as "checkbox components", even if technically only two of them are actually checkboxes. I'm not really sure what else to call this group of components as a whole. I similarly have the five classes (3 components and 2 option types) in src/components/checkbox/, so the test file is named consistently with that folder. Should I rename the file/maybe split it up into 2-3 more precisely-named files?
Actually on second though, since it's v14, I'm not too worried about it.
ID should be lowercase everywhere!
Everywhere else too:
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice()}.
I copied that from the StringSelectMenuBuilder, though now that I look at it, that links to slice, not splice, shouldn't it be splice? if so then its also wrong in StringSelectMenuBuilder
Yeah, looks like a documentation issue. Seems to be present on main too...
Should I fix that now for StringSelectMenuBuilder too or is that outside of the scope of a checkbox components PR? Im still learning OSS contribution etiquette
Main pull request to fix it there, then it's backported into v14.
In this pull request, you can fix it for radios/checkboxes.
StringSelectMenuBuilder.splice()'s docs incorrectly linked to slice instead of splice in MDN docs, fixed that
Aren't you supposed to return Result.err? https://github.com/sapphiredev/shapeshift#reshapervalue-t--resultr-error--iconstraint-nopvalidatorr-adds-a-constraint-able-to-both-validate
Oh yea that makes sense
ngl I couldn't find the docs for this, I kept googling sapphire instead of shapeshift and thought that the bot framework I saw was completely unrelated, and then I misread some of the other builders code that i was half copying from
d20e103 chore(builders): release @discordjs/builders@1.... - vladfrangu
[discordjs/discord.js] New tag created: @discordjs/[email protected]
6e45ddc fix: actually accept rest in RadioGroup/CheckBo... - ducktrshessami
2eaec32 chore(builders): release @discordjs/builders@1.... - Jiralite
6a0cd82 chore(builders): increase @discordjs/builders v... - Jiralite
[discordjs/discord.js] New tag created: @discordjs/[email protected]
Summary
- Adds a small
resolveColorhelper to@discordjs/buildersthat accepts a raw integer, a#rrggbbhex string, or an[r, g, b]tuple. The semantics mirrorresolveColorin the maindiscord.jspackage (both accept the same shapes and use the same range check). ContainerBuilder#setAccentColornow routes through it, so users can do.setAccentColor('#00af89')or.setAccentColor([0, 175, 137])in addition to raw integers.
Why
ContainerBuilder#setAccentColor previ...
Good catch, this was a real bug. Verified all four cases in a REPL against the previous logic:
| input | previous result | status |
|---|---|---|
[0, 0, 300] |
300 (0x12C) |
passed, wrong |
[0, 256, 0] |
65536 (0x10000) |
passed, wrong |
[-1, 0, 0] |
-65536 |
caught by range check, but incidentally |
[1.9, 0, 0] |
65536 (1 << 16, truncated via <<) |
passed, wrong |
[300, 0, 0] |
19660800 |
caught by range check, but incidentally |
Pushed a fix that vali...
Valid catch. Pushed 6d68ee667 earlier that validates each channel is an integer in [0, 255] before composing. Table of the previously silently-accepted inputs is in the thread comment.
Covered in the same follow-up commit. The new GIVEN out-of-range RGB components THEN throws block exercises [0,0,300], [0,256,0], [300,0,0] (so the incidental overflow-masking path no longer covers for us), [-1,0,0], [1.9,0,0], and a [0,0] tuple-length case. Also added an uppercase-hex assertion to the existing hex string or RGB tuple test in 820a993a1.
Intentionally matching the existing style of the surrounding util/* imports in this file:
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray';
import { resolveBuilder } from '../../util/resolveBuilder';
import { validate } from '../../util/validation';
Adding the .js extension here would make the new import the odd one out. Happy to switch if the maintainers want a separate pass normalizing every util import to .js, but that feels out of scope for this...
Intentionally scoped. The Colors enum, 'Random', and 'Default' all live in the main discord.js package (alongside the Colors map and DiscordjsError instances), which @discordjs/builders doesn't depend on. Pulling them in here would widen the builders package surface. The linked issue (#11496) specifically asks for hex-string / tuple parity, so the resolver targets that and leaves the richer alias set to the main package's own resolveColor. Happy to follow up with a doc note po...
For full consistency, you'd probably want to make EmbedBuilder.setColor() support ColorResolvable too. Otherwise, the inconsistency remains for users who use builders with core instead of main lib.
The inconcistency is intentional, refer to https://github.com/discordjs/discord.js/issues/11496#issuecomment-4276061772 for reasoning.
I'm not really sold on this. There's maybe an argument to be made about RGB tuples, since they're somewhat common in other graphics processing contexts, but I see pretty much absolutely no use in accepting #${string} - 0x prefix on number literals accomplishes the same thing, doesn't ask for parsing base 16 numbers, is as readable, and allows math out of the box in your own code for basic color transformations you might run on your own color constants/
Already checks in the loop. No need for double checking
if (color.length !== 3) {
throw new TypeError('Invalid color tuple: expected [red, green, blue] with numeric components.');
}
Already checks in the loop. No need for double checking
Right, Number.isInteger already rejects non-numbers. Dropped in ab27583fa, length check stays.
Summary
ContainerBuilder#setAccentColor and EmbedBuilder#setColor now accept ColorResolvable (number, hex string, RGB tuple, 'Random', 'Default') instead of only number, bringing consistency with the rest of the API.
Related Issue
Closes #11496
Changes
packages/builders/src/util/colors.tsโ new module exportingColorResolvabletype andresolveColor()utilitypackages/builders/src/components/v2/Container.tsโsetAccentColornow acceptsColorResolvableand resolv...