@ovencord/builders 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +92 -0
  3. package/package.json +70 -0
  4. package/src/Assertions.ts +15 -0
  5. package/src/components/ActionRow.ts +346 -0
  6. package/src/components/Assertions.ts +190 -0
  7. package/src/components/Component.ts +47 -0
  8. package/src/components/Components.ts +275 -0
  9. package/src/components/button/Button.ts +34 -0
  10. package/src/components/button/CustomIdButton.ts +74 -0
  11. package/src/components/button/LinkButton.ts +39 -0
  12. package/src/components/button/PremiumButton.ts +26 -0
  13. package/src/components/button/mixins/EmojiOrLabelButtonMixin.ts +52 -0
  14. package/src/components/fileUpload/Assertions.ts +12 -0
  15. package/src/components/fileUpload/FileUpload.ts +109 -0
  16. package/src/components/label/Assertions.ts +28 -0
  17. package/src/components/label/Label.ts +215 -0
  18. package/src/components/selectMenu/BaseSelectMenu.ts +89 -0
  19. package/src/components/selectMenu/ChannelSelectMenu.ts +115 -0
  20. package/src/components/selectMenu/MentionableSelectMenu.ts +126 -0
  21. package/src/components/selectMenu/RoleSelectMenu.ts +89 -0
  22. package/src/components/selectMenu/StringSelectMenu.ts +165 -0
  23. package/src/components/selectMenu/StringSelectMenuOption.ts +113 -0
  24. package/src/components/selectMenu/UserSelectMenu.ts +89 -0
  25. package/src/components/textInput/Assertions.ts +15 -0
  26. package/src/components/textInput/TextInput.ts +154 -0
  27. package/src/components/v2/Assertions.ts +82 -0
  28. package/src/components/v2/Container.ts +254 -0
  29. package/src/components/v2/File.ts +81 -0
  30. package/src/components/v2/MediaGallery.ts +128 -0
  31. package/src/components/v2/MediaGalleryItem.ts +85 -0
  32. package/src/components/v2/Section.ts +266 -0
  33. package/src/components/v2/Separator.ts +82 -0
  34. package/src/components/v2/TextDisplay.ts +63 -0
  35. package/src/components/v2/Thumbnail.ts +100 -0
  36. package/src/index.ts +109 -0
  37. package/src/interactions/commands/Command.ts +87 -0
  38. package/src/interactions/commands/SharedName.ts +68 -0
  39. package/src/interactions/commands/SharedNameAndDescription.ts +69 -0
  40. package/src/interactions/commands/chatInput/Assertions.ts +180 -0
  41. package/src/interactions/commands/chatInput/ChatInputCommand.ts +40 -0
  42. package/src/interactions/commands/chatInput/ChatInputCommandSubcommands.ts +117 -0
  43. package/src/interactions/commands/chatInput/mixins/ApplicationCommandNumericOptionMinMaxValueMixin.ts +52 -0
  44. package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionChannelTypesMixin.ts +57 -0
  45. package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionWithAutocompleteMixin.ts +32 -0
  46. package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionWithChoicesMixin.ts +43 -0
  47. package/src/interactions/commands/chatInput/mixins/SharedChatInputCommandOptions.ts +204 -0
  48. package/src/interactions/commands/chatInput/mixins/SharedSubcommands.ts +61 -0
  49. package/src/interactions/commands/chatInput/options/ApplicationCommandOptionBase.ts +66 -0
  50. package/src/interactions/commands/chatInput/options/attachment.ts +20 -0
  51. package/src/interactions/commands/chatInput/options/boolean.ts +20 -0
  52. package/src/interactions/commands/chatInput/options/channel.ts +28 -0
  53. package/src/interactions/commands/chatInput/options/integer.ts +34 -0
  54. package/src/interactions/commands/chatInput/options/mentionable.ts +20 -0
  55. package/src/interactions/commands/chatInput/options/number.ts +34 -0
  56. package/src/interactions/commands/chatInput/options/role.ts +20 -0
  57. package/src/interactions/commands/chatInput/options/string.ts +71 -0
  58. package/src/interactions/commands/chatInput/options/user.ts +20 -0
  59. package/src/interactions/commands/contextMenu/Assertions.ts +31 -0
  60. package/src/interactions/commands/contextMenu/ContextMenuCommand.ts +42 -0
  61. package/src/interactions/commands/contextMenu/MessageCommand.ts +19 -0
  62. package/src/interactions/commands/contextMenu/UserCommand.ts +19 -0
  63. package/src/interactions/modals/Assertions.ts +27 -0
  64. package/src/interactions/modals/Modal.ts +158 -0
  65. package/src/messages/AllowedMentions.ts +193 -0
  66. package/src/messages/Assertions.ts +148 -0
  67. package/src/messages/Attachment.ts +209 -0
  68. package/src/messages/Message.ts +692 -0
  69. package/src/messages/MessageReference.ts +111 -0
  70. package/src/messages/embed/Assertions.ts +53 -0
  71. package/src/messages/embed/Embed.ts +352 -0
  72. package/src/messages/embed/EmbedAuthor.ts +83 -0
  73. package/src/messages/embed/EmbedField.ts +67 -0
  74. package/src/messages/embed/EmbedFooter.ts +65 -0
  75. package/src/messages/poll/Assertions.ts +20 -0
  76. package/src/messages/poll/Poll.ts +243 -0
  77. package/src/messages/poll/PollAnswer.ts +77 -0
  78. package/src/messages/poll/PollAnswerMedia.ts +38 -0
  79. package/src/messages/poll/PollMedia.ts +41 -0
  80. package/src/messages/poll/PollQuestion.ts +20 -0
  81. package/src/util/ValidationError.ts +21 -0
  82. package/src/util/normalizeArray.ts +19 -0
  83. package/src/util/resolveBuilder.ts +40 -0
  84. package/src/util/validation.ts +58 -0
@@ -0,0 +1,215 @@
1
+ import type {
2
+ APIChannelSelectComponent,
3
+ APIFileUploadComponent,
4
+ APILabelComponent,
5
+ APIMentionableSelectComponent,
6
+ APIRoleSelectComponent,
7
+ APIStringSelectComponent,
8
+ APITextInputComponent,
9
+ APIUserSelectComponent,
10
+ } from 'discord-api-types/v10';
11
+ import { ComponentType } from 'discord-api-types/v10';
12
+ import { resolveBuilder } from '../../util/resolveBuilder.js';
13
+ import { validate } from '../../util/validation.js';
14
+ import { ComponentBuilder } from '../Component.js';
15
+ import { createComponentBuilder } from '../Components.js';
16
+ import { FileUploadBuilder } from '../fileUpload/FileUpload.js';
17
+ import { ChannelSelectMenuBuilder } from '../selectMenu/ChannelSelectMenu.js';
18
+ import { MentionableSelectMenuBuilder } from '../selectMenu/MentionableSelectMenu.js';
19
+ import { RoleSelectMenuBuilder } from '../selectMenu/RoleSelectMenu.js';
20
+ import { StringSelectMenuBuilder } from '../selectMenu/StringSelectMenu.js';
21
+ import { UserSelectMenuBuilder } from '../selectMenu/UserSelectMenu.js';
22
+ import { TextInputBuilder } from '../textInput/TextInput.js';
23
+ import { labelPredicate } from './Assertions.js';
24
+
25
+ export interface LabelBuilderData extends Partial<Omit<APILabelComponent, 'component'>> {
26
+ component?:
27
+ | ChannelSelectMenuBuilder
28
+ | FileUploadBuilder
29
+ | MentionableSelectMenuBuilder
30
+ | RoleSelectMenuBuilder
31
+ | StringSelectMenuBuilder
32
+ | TextInputBuilder
33
+ | UserSelectMenuBuilder;
34
+ }
35
+
36
+ /**
37
+ * A builder that creates API-compatible JSON data for labels.
38
+ */
39
+ export class LabelBuilder extends ComponentBuilder<APILabelComponent> {
40
+ /**
41
+ * @internal
42
+ */
43
+ protected readonly data: LabelBuilderData;
44
+
45
+ /**
46
+ * Creates a new label.
47
+ *
48
+ * @param data - The API data to create this label with
49
+ * @example
50
+ * Creating a label from an API data object:
51
+ * ```ts
52
+ * const label = new LabelBuilder({
53
+ * label: "label",
54
+ * component,
55
+ * });
56
+ * ```
57
+ * @example
58
+ * Creating a label using setters and API data:
59
+ * ```ts
60
+ * const label = new LabelBuilder({
61
+ * label: 'label',
62
+ * component,
63
+ * }).setContent('new text');
64
+ * ```
65
+ */
66
+ public constructor(data: Partial<APILabelComponent> = {}) {
67
+ super();
68
+
69
+ const { component, ...rest } = data;
70
+
71
+ this.data = {
72
+ ...structuredClone(rest),
73
+ component: component ? (createComponentBuilder(component as any) as any) : undefined,
74
+ type: ComponentType.Label,
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Sets the label for this label.
80
+ *
81
+ * @param label - The label to use
82
+ */
83
+ public setLabel(label: string) {
84
+ this.data.label = label;
85
+ return this;
86
+ }
87
+
88
+ /**
89
+ * Sets the description for this label.
90
+ *
91
+ * @param description - The description to use
92
+ */
93
+ public setDescription(description: string) {
94
+ this.data.description = description;
95
+ return this;
96
+ }
97
+
98
+ /**
99
+ * Clears the description for this label.
100
+ */
101
+ public clearDescription() {
102
+ this.data.description = undefined;
103
+ return this;
104
+ }
105
+
106
+ /**
107
+ * Sets a string select menu component to this label.
108
+ *
109
+ * @param input - A function that returns a component builder or an already built builder
110
+ */
111
+ public setStringSelectMenuComponent(
112
+ input:
113
+ | APIStringSelectComponent
114
+ | StringSelectMenuBuilder
115
+ | ((builder: StringSelectMenuBuilder) => StringSelectMenuBuilder),
116
+ ): this {
117
+ this.data.component = resolveBuilder(input, StringSelectMenuBuilder);
118
+ return this;
119
+ }
120
+
121
+ /**
122
+ * Sets a user select menu component to this label.
123
+ *
124
+ * @param input - A function that returns a component builder or an already built builder
125
+ */
126
+ public setUserSelectMenuComponent(
127
+ input: APIUserSelectComponent | UserSelectMenuBuilder | ((builder: UserSelectMenuBuilder) => UserSelectMenuBuilder),
128
+ ): this {
129
+ this.data.component = resolveBuilder(input, UserSelectMenuBuilder);
130
+ return this;
131
+ }
132
+
133
+ /**
134
+ * Sets a role select menu component to this label.
135
+ *
136
+ * @param input - A function that returns a component builder or an already built builder
137
+ */
138
+ public setRoleSelectMenuComponent(
139
+ input: APIRoleSelectComponent | RoleSelectMenuBuilder | ((builder: RoleSelectMenuBuilder) => RoleSelectMenuBuilder),
140
+ ): this {
141
+ this.data.component = resolveBuilder(input, RoleSelectMenuBuilder);
142
+ return this;
143
+ }
144
+
145
+ /**
146
+ * Sets a mentionable select menu component to this label.
147
+ *
148
+ * @param input - A function that returns a component builder or an already built builder
149
+ */
150
+ public setMentionableSelectMenuComponent(
151
+ input:
152
+ | APIMentionableSelectComponent
153
+ | MentionableSelectMenuBuilder
154
+ | ((builder: MentionableSelectMenuBuilder) => MentionableSelectMenuBuilder),
155
+ ): this {
156
+ this.data.component = resolveBuilder(input, MentionableSelectMenuBuilder);
157
+ return this;
158
+ }
159
+
160
+ /**
161
+ * Sets a channel select menu component to this label.
162
+ *
163
+ * @param input - A function that returns a component builder or an already built builder
164
+ */
165
+ public setChannelSelectMenuComponent(
166
+ input:
167
+ | APIChannelSelectComponent
168
+ | ChannelSelectMenuBuilder
169
+ | ((builder: ChannelSelectMenuBuilder) => ChannelSelectMenuBuilder),
170
+ ): this {
171
+ this.data.component = resolveBuilder(input, ChannelSelectMenuBuilder);
172
+ return this;
173
+ }
174
+
175
+ /**
176
+ * Sets a text input component to this label.
177
+ *
178
+ * @param input - A function that returns a component builder or an already built builder
179
+ */
180
+ public setTextInputComponent(
181
+ input: APITextInputComponent | TextInputBuilder | ((builder: TextInputBuilder) => TextInputBuilder),
182
+ ): this {
183
+ this.data.component = resolveBuilder(input, TextInputBuilder);
184
+ return this;
185
+ }
186
+
187
+ /**
188
+ * Sets a file upload component to this label.
189
+ *
190
+ * @param input - A function that returns a component builder or an already built builder
191
+ */
192
+ public setFileUploadComponent(
193
+ input: APIFileUploadComponent | FileUploadBuilder | ((builder: FileUploadBuilder) => FileUploadBuilder),
194
+ ): this {
195
+ this.data.component = resolveBuilder(input, FileUploadBuilder);
196
+ return this;
197
+ }
198
+
199
+ /**
200
+ * {@inheritDoc ComponentBuilder.toJSON}
201
+ */
202
+ public override toJSON(validationOverride?: boolean): APILabelComponent {
203
+ const { component, ...rest } = this.data;
204
+
205
+ const data = {
206
+ ...structuredClone(rest),
207
+ // The label predicate validates the component.
208
+ component: component?.toJSON(false),
209
+ };
210
+
211
+ validate(labelPredicate, data, validationOverride);
212
+
213
+ return data as APILabelComponent;
214
+ }
215
+ }
@@ -0,0 +1,89 @@
1
+ import type { JSONEncodable } from '@ovencord/util';
2
+ import type { APISelectMenuComponent } from 'discord-api-types/v10';
3
+ import { ComponentBuilder } from '../Component.js';
4
+
5
+ /**
6
+ * The base select menu builder that contains common symbols for select menu builders.
7
+ *
8
+ * @typeParam Data - The type of API data that is stored within the builder
9
+ */
10
+ export abstract class BaseSelectMenuBuilder<Data extends APISelectMenuComponent>
11
+ extends ComponentBuilder<Data>
12
+ implements JSONEncodable<APISelectMenuComponent>
13
+ {
14
+ /**
15
+ * @internal
16
+ */
17
+ protected abstract override readonly data: Partial<
18
+ Pick<Data, 'custom_id' | 'disabled' | 'id' | 'max_values' | 'min_values' | 'placeholder' | 'required'>
19
+ >;
20
+
21
+ /**
22
+ * Sets the placeholder for this select menu.
23
+ *
24
+ * @param placeholder - The placeholder to use
25
+ */
26
+ public setPlaceholder(placeholder: string) {
27
+ this.data.placeholder = placeholder;
28
+ return this;
29
+ }
30
+
31
+ /**
32
+ * Clears the placeholder for this select menu.
33
+ */
34
+ public clearPlaceholder() {
35
+ this.data.placeholder = undefined;
36
+ return this;
37
+ }
38
+
39
+ /**
40
+ * Sets the minimum values that must be selected in the select menu.
41
+ *
42
+ * @param minValues - The minimum values that must be selected
43
+ */
44
+ public setMinValues(minValues: number) {
45
+ this.data.min_values = minValues;
46
+ return this;
47
+ }
48
+
49
+ /**
50
+ * Sets the maximum values that can be selected in the select menu.
51
+ *
52
+ * @param maxValues - The maximum values that can be selected
53
+ */
54
+ public setMaxValues(maxValues: number) {
55
+ this.data.max_values = maxValues;
56
+ return this;
57
+ }
58
+
59
+ /**
60
+ * Sets the custom id for this select menu.
61
+ *
62
+ * @param customId - The custom id to use
63
+ */
64
+ public setCustomId(customId: string) {
65
+ this.data.custom_id = customId;
66
+ return this;
67
+ }
68
+
69
+ /**
70
+ * Sets whether this select menu is disabled.
71
+ *
72
+ * @param disabled - Whether this select menu is disabled
73
+ */
74
+ public setDisabled(disabled = true) {
75
+ this.data.disabled = disabled;
76
+ return this;
77
+ }
78
+
79
+ /**
80
+ * Sets whether this select menu is required.
81
+ *
82
+ * @remarks Only for use in modals.
83
+ * @param required - Whether this string select menu is required
84
+ */
85
+ public setRequired(required = true) {
86
+ this.data.required = required;
87
+ return this;
88
+ }
89
+ }
@@ -0,0 +1,115 @@
1
+ import {
2
+ type APIChannelSelectComponent,
3
+ type ChannelType,
4
+ type Snowflake,
5
+ ComponentType,
6
+ SelectMenuDefaultValueType,
7
+ } from 'discord-api-types/v10';
8
+ import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js';
9
+ import { validate } from '../../util/validation.js';
10
+ import { selectMenuChannelPredicate } from '../Assertions.js';
11
+ import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
12
+
13
+ /**
14
+ * A builder that creates API-compatible JSON data for channel select menus.
15
+ */
16
+ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSelectComponent> {
17
+ protected override readonly data: Partial<APIChannelSelectComponent>;
18
+
19
+ /**
20
+ * Creates a new channel select menu.
21
+ *
22
+ * @param data - The API data to create this channel select menu with
23
+ * @example
24
+ * Creating a select menu from an API data object:
25
+ * ```ts
26
+ * const selectMenu = new ChannelSelectMenuBuilder({
27
+ * custom_id: 'a cool select menu',
28
+ * placeholder: 'select an option',
29
+ * max_values: 2,
30
+ * });
31
+ * ```
32
+ * @example
33
+ * Creating a select menu using setters and API data:
34
+ * ```ts
35
+ * const selectMenu = new ChannelSelectMenuBuilder({
36
+ * custom_id: 'a cool select menu',
37
+ * })
38
+ * .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
39
+ * .setMinValues(2);
40
+ * ```
41
+ */
42
+ public constructor(data: Partial<APIChannelSelectComponent> = {}) {
43
+ super();
44
+ this.data = { ...structuredClone(data), type: ComponentType.ChannelSelect };
45
+ }
46
+
47
+ /**
48
+ * Adds channel types to this select menu.
49
+ *
50
+ * @param types - The channel types to use
51
+ */
52
+ public addChannelTypes(...types: RestOrArray<ChannelType>) {
53
+ const normalizedTypes = normalizeArray(types);
54
+ this.data.channel_types ??= [];
55
+ this.data.channel_types.push(...normalizedTypes);
56
+ return this;
57
+ }
58
+
59
+ /**
60
+ * Sets channel types for this select menu.
61
+ *
62
+ * @param types - The channel types to use
63
+ */
64
+ public setChannelTypes(...types: RestOrArray<ChannelType>) {
65
+ const normalizedTypes = normalizeArray(types);
66
+ this.data.channel_types ??= [];
67
+ this.data.channel_types.splice(0, this.data.channel_types.length, ...normalizedTypes);
68
+ return this;
69
+ }
70
+
71
+ /**
72
+ * Adds default channels to this auto populated select menu.
73
+ *
74
+ * @param channels - The channels to add
75
+ */
76
+ public addDefaultChannels(...channels: RestOrArray<Snowflake>) {
77
+ const normalizedValues = normalizeArray(channels);
78
+ this.data.default_values ??= [];
79
+
80
+ this.data.default_values.push(
81
+ ...normalizedValues.map((id) => ({
82
+ id,
83
+ type: SelectMenuDefaultValueType.Channel as const,
84
+ })),
85
+ );
86
+
87
+ return this;
88
+ }
89
+
90
+ /**
91
+ * Sets default channels for this auto populated select menu.
92
+ *
93
+ * @param channels - The channels to set
94
+ */
95
+ public setDefaultChannels(...channels: RestOrArray<Snowflake>) {
96
+ const normalizedValues = normalizeArray(channels);
97
+
98
+ this.data.default_values = normalizedValues.map((id) => ({
99
+ id,
100
+ type: SelectMenuDefaultValueType.Channel as const,
101
+ }));
102
+
103
+ return this;
104
+ }
105
+
106
+ /**
107
+ * {@inheritDoc ComponentBuilder.toJSON}
108
+ */
109
+ public override toJSON(validationOverride?: boolean): APIChannelSelectComponent {
110
+ const clone = structuredClone(this.data);
111
+ validate(selectMenuChannelPredicate, clone, validationOverride);
112
+
113
+ return clone as APIChannelSelectComponent;
114
+ }
115
+ }
@@ -0,0 +1,126 @@
1
+ import {
2
+ type APIMentionableSelectComponent,
3
+ type APISelectMenuDefaultValue,
4
+ type Snowflake,
5
+ ComponentType,
6
+ SelectMenuDefaultValueType,
7
+ } from 'discord-api-types/v10';
8
+ import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js';
9
+ import { validate } from '../../util/validation.js';
10
+ import { selectMenuMentionablePredicate } from '../Assertions.js';
11
+ import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
12
+
13
+ /**
14
+ * A builder that creates API-compatible JSON data for mentionable select menus.
15
+ */
16
+ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMentionableSelectComponent> {
17
+ protected override readonly data: Partial<APIMentionableSelectComponent>;
18
+
19
+ /**
20
+ * Creates a new mentionable select menu.
21
+ *
22
+ * @param data - The API data to create this mentionable select menu with
23
+ * @example
24
+ * Creating a select menu from an API data object:
25
+ * ```ts
26
+ * const selectMenu = new MentionableSelectMenuBuilder({
27
+ * custom_id: 'a cool select menu',
28
+ * placeholder: 'select an option',
29
+ * max_values: 2,
30
+ * });
31
+ * ```
32
+ * @example
33
+ * Creating a select menu using setters and API data:
34
+ * ```ts
35
+ * const selectMenu = new MentionableSelectMenuBuilder({
36
+ * custom_id: 'a cool select menu',
37
+ * })
38
+ * .setMinValues(1);
39
+ * ```
40
+ */
41
+ public constructor(data: Partial<APIMentionableSelectComponent> = {}) {
42
+ super();
43
+ this.data = { ...structuredClone(data), type: ComponentType.MentionableSelect };
44
+ }
45
+
46
+ /**
47
+ * Adds default roles to this auto populated select menu.
48
+ *
49
+ * @param roles - The roles to add
50
+ */
51
+ public addDefaultRoles(...roles: RestOrArray<Snowflake>) {
52
+ const normalizedValues = normalizeArray(roles);
53
+ this.data.default_values ??= [];
54
+
55
+ this.data.default_values.push(
56
+ ...normalizedValues.map((id) => ({
57
+ id,
58
+ type: SelectMenuDefaultValueType.Role as const,
59
+ })),
60
+ );
61
+
62
+ return this;
63
+ }
64
+
65
+ /**
66
+ * Adds default users to this auto populated select menu.
67
+ *
68
+ * @param users - The users to add
69
+ */
70
+ public addDefaultUsers(...users: RestOrArray<Snowflake>) {
71
+ const normalizedValues = normalizeArray(users);
72
+ this.data.default_values ??= [];
73
+
74
+ this.data.default_values.push(
75
+ ...normalizedValues.map((id) => ({
76
+ id,
77
+ type: SelectMenuDefaultValueType.User as const,
78
+ })),
79
+ );
80
+
81
+ return this;
82
+ }
83
+
84
+ /**
85
+ * Adds default values to this auto populated select menu.
86
+ *
87
+ * @param values - The values to add
88
+ */
89
+ public addDefaultValues(
90
+ ...values: RestOrArray<
91
+ | APISelectMenuDefaultValue<SelectMenuDefaultValueType.Role>
92
+ | APISelectMenuDefaultValue<SelectMenuDefaultValueType.User>
93
+ >
94
+ ) {
95
+ const normalizedValues = normalizeArray(values);
96
+ this.data.default_values ??= [];
97
+ this.data.default_values.push(...normalizedValues);
98
+ return this;
99
+ }
100
+
101
+ /**
102
+ * Sets default values for this auto populated select menu.
103
+ *
104
+ * @param values - The values to set
105
+ */
106
+ public setDefaultValues(
107
+ ...values: RestOrArray<
108
+ | APISelectMenuDefaultValue<SelectMenuDefaultValueType.Role>
109
+ | APISelectMenuDefaultValue<SelectMenuDefaultValueType.User>
110
+ >
111
+ ) {
112
+ const normalizedValues = normalizeArray(values);
113
+ this.data.default_values = normalizedValues;
114
+ return this;
115
+ }
116
+
117
+ /**
118
+ * {@inheritDoc ComponentBuilder.toJSON}
119
+ */
120
+ public override toJSON(validationOverride?: boolean): APIMentionableSelectComponent {
121
+ const clone = structuredClone(this.data);
122
+ validate(selectMenuMentionablePredicate, clone, validationOverride);
123
+
124
+ return clone as APIMentionableSelectComponent;
125
+ }
126
+ }
@@ -0,0 +1,89 @@
1
+ import {
2
+ type APIRoleSelectComponent,
3
+ type Snowflake,
4
+ ComponentType,
5
+ SelectMenuDefaultValueType,
6
+ } from 'discord-api-types/v10';
7
+ import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js';
8
+ import { validate } from '../../util/validation.js';
9
+ import { selectMenuRolePredicate } from '../Assertions.js';
10
+ import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
11
+
12
+ /**
13
+ * A builder that creates API-compatible JSON data for role select menus.
14
+ */
15
+ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectComponent> {
16
+ protected override readonly data: Partial<APIRoleSelectComponent>;
17
+
18
+ /**
19
+ * Creates a new role select menu.
20
+ *
21
+ * @param data - The API data to create this role select menu with
22
+ * @example
23
+ * Creating a select menu from an API data object:
24
+ * ```ts
25
+ * const selectMenu = new RoleSelectMenuBuilder({
26
+ * custom_id: 'a cool select menu',
27
+ * placeholder: 'select an option',
28
+ * max_values: 2,
29
+ * });
30
+ * ```
31
+ * @example
32
+ * Creating a select menu using setters and API data:
33
+ * ```ts
34
+ * const selectMenu = new RoleSelectMenuBuilder({
35
+ * custom_id: 'a cool select menu',
36
+ * })
37
+ * .setMinValues(1);
38
+ * ```
39
+ */
40
+ public constructor(data: Partial<APIRoleSelectComponent> = {}) {
41
+ super();
42
+ this.data = { ...structuredClone(data), type: ComponentType.RoleSelect };
43
+ }
44
+
45
+ /**
46
+ * Adds default roles to this auto populated select menu.
47
+ *
48
+ * @param roles - The roles to add
49
+ */
50
+ public addDefaultRoles(...roles: RestOrArray<Snowflake>) {
51
+ const normalizedValues = normalizeArray(roles);
52
+ this.data.default_values ??= [];
53
+
54
+ this.data.default_values.push(
55
+ ...normalizedValues.map((id) => ({
56
+ id,
57
+ type: SelectMenuDefaultValueType.Role as const,
58
+ })),
59
+ );
60
+
61
+ return this;
62
+ }
63
+
64
+ /**
65
+ * Sets default roles for this auto populated select menu.
66
+ *
67
+ * @param roles - The roles to set
68
+ */
69
+ public setDefaultRoles(...roles: RestOrArray<Snowflake>) {
70
+ const normalizedValues = normalizeArray(roles);
71
+
72
+ this.data.default_values = normalizedValues.map((id) => ({
73
+ id,
74
+ type: SelectMenuDefaultValueType.Role as const,
75
+ }));
76
+
77
+ return this;
78
+ }
79
+
80
+ /**
81
+ * {@inheritDoc ComponentBuilder.toJSON}
82
+ */
83
+ public override toJSON(validationOverride?: boolean): APIRoleSelectComponent {
84
+ const clone = structuredClone(this.data);
85
+ validate(selectMenuRolePredicate, clone, validationOverride);
86
+
87
+ return clone as APIRoleSelectComponent;
88
+ }
89
+ }