@ovencord/builders 1.12.8 → 1.13.0
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.
- package/package.json +2 -3
- package/src/components/ActionRow.ts +14 -13
- package/src/components/Assertions.ts +38 -27
- package/src/components/Component.ts +3 -3
- package/src/components/Components.ts +35 -27
- package/src/components/button/Button.ts +1 -1
- package/src/components/button/ButtonBuilder.ts +7 -6
- package/src/components/button/CustomIdButton.ts +4 -2
- package/src/components/button/LinkButton.ts +3 -2
- package/src/components/button/mixins/EmojiOrLabelButtonMixin.ts +3 -5
- package/src/components/label/Label.ts +4 -1
- package/src/components/selectMenu/ChannelSelectMenu.ts +2 -2
- package/src/components/selectMenu/MentionableSelectMenu.ts +2 -2
- package/src/components/selectMenu/RoleSelectMenu.ts +2 -2
- package/src/components/selectMenu/StringSelectMenu.ts +1 -1
- package/src/components/selectMenu/UserSelectMenu.ts +2 -2
- package/src/components/textInput/TextInput.ts +1 -1
- package/src/components/v2/Assertions.ts +11 -6
- package/src/components/v2/Container.ts +12 -7
- package/src/components/v2/File.ts +1 -1
- package/src/components/v2/MediaGallery.ts +1 -1
- package/src/components/v2/Section.ts +7 -20
- package/src/components/v2/Separator.ts +1 -1
- package/src/components/v2/TextDisplay.ts +2 -2
- package/src/components/v2/Thumbnail.ts +8 -8
- package/src/index.ts +29 -42
- package/src/interactions/commands/Command.ts +11 -7
- package/src/interactions/commands/SharedName.ts +2 -3
- package/src/interactions/commands/SharedNameAndDescription.ts +2 -1
- package/src/interactions/commands/chatInput/Assertions.ts +17 -5
- package/src/interactions/commands/chatInput/ChatInputCommandSubcommands.ts +5 -4
- package/src/interactions/commands/chatInput/mixins/ApplicationCommandNumericOptionMinMaxValueMixin.ts +3 -5
- package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionChannelTypesMixin.ts +4 -6
- package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionWithAutocompleteMixin.ts +1 -1
- package/src/interactions/commands/chatInput/mixins/ApplicationCommandOptionWithChoicesMixin.ts +1 -1
- package/src/interactions/commands/chatInput/mixins/SharedChatInputCommandOptions.ts +34 -11
- package/src/interactions/commands/chatInput/mixins/SharedSubcommands.ts +2 -2
- package/src/interactions/commands/chatInput/options/ApplicationCommandOptionBase.ts +1 -1
- package/src/interactions/commands/chatInput/options/string.ts +3 -3
- package/src/interactions/modals/Modal.ts +3 -9
- package/src/messages/Assertions.ts +6 -3
- package/src/messages/Attachment.ts +1 -1
- package/src/messages/Message.ts +30 -21
- package/src/messages/embed/Assertions.ts +16 -3
- package/src/messages/embed/Embed.ts +4 -2
- package/src/messages/poll/Poll.ts +1 -1
- package/src/util/componentUtil.ts +4 -4
- package/src/util/resolveBuilder.ts +5 -2
- package/src/util/validation.ts +4 -2
|
@@ -110,14 +110,10 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|
|
110
110
|
* @param components - The action rows to add
|
|
111
111
|
*/
|
|
112
112
|
public addActionRowComponents(
|
|
113
|
-
...components: RestOrArray<
|
|
114
|
-
ActionRowBuilder | APIActionRowComponent<APIComponentInActionRow>
|
|
115
|
-
>
|
|
113
|
+
...components: RestOrArray<ActionRowBuilder | APIActionRowComponent<APIComponentInActionRow>>
|
|
116
114
|
) {
|
|
117
115
|
const normalized = normalizeArray(components);
|
|
118
|
-
const resolved = normalized.map((row) =>
|
|
119
|
-
row instanceof ActionRowBuilder ? row : new ActionRowBuilder(row),
|
|
120
|
-
);
|
|
116
|
+
const resolved = normalized.map((row) => (row instanceof ActionRowBuilder ? row : new ActionRowBuilder(row)));
|
|
121
117
|
|
|
122
118
|
this.data.components.push(...resolved);
|
|
123
119
|
|
|
@@ -130,9 +126,7 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|
|
130
126
|
*
|
|
131
127
|
* @param components - The components to add
|
|
132
128
|
*/
|
|
133
|
-
public addComponents(
|
|
134
|
-
...components: RestOrArray<ActionRowBuilder | AnyModalComponentBuilder>
|
|
135
|
-
) {
|
|
129
|
+
public addComponents(...components: RestOrArray<ActionRowBuilder | AnyModalComponentBuilder>) {
|
|
136
130
|
const normalized = normalizeArray(components);
|
|
137
131
|
this.data.components.push(...normalized);
|
|
138
132
|
|
|
@@ -126,9 +126,12 @@ const allTopLevelComponentsPredicate = z
|
|
|
126
126
|
|
|
127
127
|
const messageComponentsV2Predicate = baseMessagePredicate.extend({
|
|
128
128
|
components: allTopLevelComponentsPredicate,
|
|
129
|
-
flags: z
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
flags: z
|
|
130
|
+
.number()
|
|
131
|
+
.int()
|
|
132
|
+
.refine((flags) => (flags & MessageFlags.IsComponentsV2) === MessageFlags.IsComponentsV2, {
|
|
133
|
+
message: 'Must set IsComponentsV2 flag to use Components V2',
|
|
134
|
+
}),
|
|
132
135
|
// These fields cannot be set
|
|
133
136
|
content: z.string().length(0).nullish(),
|
|
134
137
|
embeds: z.array(z.never()).nullish(),
|
|
@@ -109,7 +109,7 @@ export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
|
|
|
109
109
|
* @remarks Note that this data is NOT included in the {@link toJSON} output. To retrieve it, use {@link getRawFile}.
|
|
110
110
|
*/
|
|
111
111
|
public setFileData(data: Uint8Array | string): this {
|
|
112
|
-
this.fileData.data = data as
|
|
112
|
+
this.fileData.data = data as unknown as RawFile['data'];
|
|
113
113
|
return this;
|
|
114
114
|
}
|
|
115
115
|
|
package/src/messages/Message.ts
CHANGED
|
@@ -3,21 +3,21 @@ import type {
|
|
|
3
3
|
APIActionRowComponent,
|
|
4
4
|
APIAllowedMentions,
|
|
5
5
|
APIAttachment,
|
|
6
|
-
|
|
6
|
+
APIComponentInActionRow,
|
|
7
7
|
APIComponentInMessageActionRow,
|
|
8
|
-
APIMessageReference,
|
|
9
|
-
APIPoll,
|
|
10
|
-
RESTPostAPIChannelMessageJSONBody,
|
|
11
|
-
Snowflake,
|
|
12
|
-
MessageFlags,
|
|
13
8
|
APIContainerComponent,
|
|
9
|
+
APIEmbed,
|
|
14
10
|
APIFileComponent,
|
|
15
11
|
APIMediaGalleryComponent,
|
|
12
|
+
APIMessageReference,
|
|
13
|
+
APIMessageTopLevelComponent,
|
|
14
|
+
APIPoll,
|
|
16
15
|
APISectionComponent,
|
|
17
16
|
APISeparatorComponent,
|
|
18
17
|
APITextDisplayComponent,
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
MessageFlags,
|
|
19
|
+
RESTPostAPIChannelMessageJSONBody,
|
|
20
|
+
Snowflake,
|
|
21
21
|
} from 'discord-api-types/v10';
|
|
22
22
|
import { ActionRowBuilder } from '../components/ActionRow.js';
|
|
23
23
|
import { ComponentBuilder } from '../components/Component.js';
|
|
@@ -35,16 +35,17 @@ import { validate } from '../util/validation.js';
|
|
|
35
35
|
import { AllowedMentionsBuilder } from './AllowedMentions.js';
|
|
36
36
|
import { fileBodyMessagePredicate, messagePredicate } from './Assertions.js';
|
|
37
37
|
import { AttachmentBuilder } from './Attachment.js';
|
|
38
|
-
import { MessageReferenceBuilder } from './MessageReference.js';
|
|
39
38
|
import { EmbedBuilder } from './embed/Embed.js';
|
|
39
|
+
import { MessageReferenceBuilder } from './MessageReference.js';
|
|
40
40
|
import { PollBuilder } from './poll/Poll.js';
|
|
41
41
|
|
|
42
|
-
export interface MessageBuilderData
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
>
|
|
42
|
+
export interface MessageBuilderData
|
|
43
|
+
extends Partial<
|
|
44
|
+
Omit<
|
|
45
|
+
RESTPostAPIChannelMessageJSONBody,
|
|
46
|
+
'allowed_mentions' | 'attachments' | 'components' | 'embeds' | 'message_reference' | 'poll'
|
|
47
|
+
>
|
|
48
|
+
> {
|
|
48
49
|
allowed_mentions?: AllowedMentionsBuilder;
|
|
49
50
|
attachments: AttachmentBuilder[];
|
|
50
51
|
components: MessageTopLevelComponentBuilder[];
|
|
@@ -252,7 +253,8 @@ export class MessageBuilder
|
|
|
252
253
|
* @param updater - The function to update the allowed mentions with
|
|
253
254
|
*/
|
|
254
255
|
public updateAllowedMentions(updater: (builder: AllowedMentionsBuilder) => void): this {
|
|
255
|
-
|
|
256
|
+
this.data.allowed_mentions ??= new AllowedMentionsBuilder();
|
|
257
|
+
updater(this.data.allowed_mentions);
|
|
256
258
|
return this;
|
|
257
259
|
}
|
|
258
260
|
|
|
@@ -285,7 +287,8 @@ export class MessageBuilder
|
|
|
285
287
|
* @param updater - The function to update the message reference with
|
|
286
288
|
*/
|
|
287
289
|
public updateMessageReference(updater: (builder: MessageReferenceBuilder) => void): this {
|
|
288
|
-
|
|
290
|
+
this.data.message_reference ??= new MessageReferenceBuilder();
|
|
291
|
+
updater(this.data.message_reference);
|
|
289
292
|
return this;
|
|
290
293
|
}
|
|
291
294
|
|
|
@@ -311,7 +314,12 @@ export class MessageBuilder
|
|
|
311
314
|
): this {
|
|
312
315
|
this.data.components ??= [];
|
|
313
316
|
|
|
314
|
-
const resolved = normalizeArray(components).map((component) =>
|
|
317
|
+
const resolved = normalizeArray(components).map((component) =>
|
|
318
|
+
resolveBuilder<ActionRowBuilder, Partial<APIActionRowComponent<APIComponentInActionRow>>>(
|
|
319
|
+
component,
|
|
320
|
+
ActionRowBuilder,
|
|
321
|
+
),
|
|
322
|
+
);
|
|
315
323
|
this.data.components.push(...resolved);
|
|
316
324
|
|
|
317
325
|
return this;
|
|
@@ -479,7 +487,7 @@ export class MessageBuilder
|
|
|
479
487
|
*/
|
|
480
488
|
public addStickerIds(...stickerIds: RestOrArray<Snowflake>): this {
|
|
481
489
|
this.data.sticker_ids ??= [] as unknown as MessageBuilderData['sticker_ids'];
|
|
482
|
-
this.data.sticker_ids
|
|
490
|
+
this.data.sticker_ids?.push(...normalizeArray(stickerIds));
|
|
483
491
|
return this;
|
|
484
492
|
}
|
|
485
493
|
|
|
@@ -513,7 +521,7 @@ export class MessageBuilder
|
|
|
513
521
|
*/
|
|
514
522
|
public spliceStickerIds(index: number, deleteCount: number, ...stickerIds: RestOrArray<Snowflake>): this {
|
|
515
523
|
this.data.sticker_ids ??= [] as unknown as MessageBuilderData['sticker_ids'];
|
|
516
|
-
this.data.sticker_ids
|
|
524
|
+
this.data.sticker_ids?.splice(index, deleteCount, ...normalizeArray(stickerIds));
|
|
517
525
|
return this;
|
|
518
526
|
}
|
|
519
527
|
|
|
@@ -625,7 +633,8 @@ export class MessageBuilder
|
|
|
625
633
|
* @param updater - The function to update the poll with
|
|
626
634
|
*/
|
|
627
635
|
public updatePoll(updater: (builder: PollBuilder) => void): this {
|
|
628
|
-
|
|
636
|
+
this.data.poll ??= new PollBuilder();
|
|
637
|
+
updater(this.data.poll);
|
|
629
638
|
return this;
|
|
630
639
|
}
|
|
631
640
|
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { embedLength } from '@ovencord/util';
|
|
2
|
+
import type { APIEmbed } from 'discord-api-types/v10';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
|
|
4
5
|
const namePredicate = z.string().max(256);
|
|
5
6
|
|
|
6
|
-
const URLPredicate = z
|
|
7
|
+
const URLPredicate = z
|
|
8
|
+
.string()
|
|
9
|
+
.url()
|
|
10
|
+
.refine((url) => url.startsWith('http:') || url.startsWith('https:'), {
|
|
11
|
+
message: 'URL must use http or https protocol',
|
|
12
|
+
});
|
|
7
13
|
|
|
8
|
-
const URLWithAttachmentProtocolPredicate = z
|
|
14
|
+
const URLWithAttachmentProtocolPredicate = z
|
|
15
|
+
.string()
|
|
16
|
+
.url()
|
|
17
|
+
.refine((url) => url.startsWith('http:') || url.startsWith('https:') || url.startsWith('attachment:'), {
|
|
18
|
+
message: 'URL must use http, https, or attachment protocol',
|
|
19
|
+
});
|
|
9
20
|
|
|
10
21
|
export const embedFieldPredicate = z.object({
|
|
11
22
|
name: namePredicate,
|
|
@@ -50,4 +61,6 @@ export const embedPredicate = z
|
|
|
50
61
|
message: 'Embed must have at least a title, description, a field, a footer, an author, an image, OR a thumbnail.',
|
|
51
62
|
},
|
|
52
63
|
)
|
|
53
|
-
.refine((embed) => embedLength(embed as
|
|
64
|
+
.refine((embed) => embedLength(embed as unknown as APIEmbed) <= 6_000, {
|
|
65
|
+
message: 'Embeds must not exceed 6000 characters in total.',
|
|
66
|
+
});
|
|
@@ -159,7 +159,8 @@ export class EmbedBuilder implements JSONEncodable<APIEmbed> {
|
|
|
159
159
|
* @param updater - The function to update the author with
|
|
160
160
|
*/
|
|
161
161
|
public updateAuthor(updater: (builder: EmbedAuthorBuilder) => void) {
|
|
162
|
-
|
|
162
|
+
this.data.author ??= new EmbedAuthorBuilder();
|
|
163
|
+
updater(this.data.author);
|
|
163
164
|
return this;
|
|
164
165
|
}
|
|
165
166
|
|
|
@@ -225,7 +226,8 @@ export class EmbedBuilder implements JSONEncodable<APIEmbed> {
|
|
|
225
226
|
* @param updater - The function to update the footer with
|
|
226
227
|
*/
|
|
227
228
|
public updateFooter(updater: (builder: EmbedFooterBuilder) => void) {
|
|
228
|
-
|
|
229
|
+
this.data.footer ??= new EmbedFooterBuilder();
|
|
230
|
+
updater(this.data.footer);
|
|
229
231
|
return this;
|
|
230
232
|
}
|
|
231
233
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JSONEncodable } from '@ovencord/util';
|
|
2
|
-
import type {
|
|
2
|
+
import type { APIPollAnswer, APIPollMedia, PollLayoutType, RESTAPIPoll } from 'discord-api-types/v10';
|
|
3
3
|
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
|
4
4
|
import { resolveBuilder } from '../../util/resolveBuilder.js';
|
|
5
5
|
import { validate } from '../../util/validation.js';
|
|
@@ -15,10 +15,10 @@ export function parseEmoji(text: string): APIMessageComponentEmoji {
|
|
|
15
15
|
if (/^\d{17,21}$/.test(decodedText)) return { id: decodedText, name: undefined, animated: false };
|
|
16
16
|
if (!decodedText.includes(':')) return { animated: false, name: decodedText.replace(/\uFE0F/g, ''), id: undefined };
|
|
17
17
|
const match = /<?(?:(?<animated>a):)?(?<name>\w{2,32}):(?<id>\d{17,19})?>?/.exec(decodedText);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
|
|
19
|
+
if (!match || !match.groups) {
|
|
20
|
+
return { animated: false, name: decodedText, id: undefined };
|
|
21
|
+
}
|
|
22
22
|
|
|
23
23
|
return {
|
|
24
24
|
animated: Boolean(match.groups.animated),
|
|
@@ -6,7 +6,7 @@ import type { JSONEncodable } from '@ovencord/util';
|
|
|
6
6
|
* function, TS doesn't narrow out the type `Builder`, causing a type error on the last return statement.
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
|
-
function isBuilder<Builder extends JSONEncodable<
|
|
9
|
+
function isBuilder<Builder extends JSONEncodable<unknown>>(
|
|
10
10
|
builder: unknown,
|
|
11
11
|
Constructor: new () => Builder,
|
|
12
12
|
): builder is Builder {
|
|
@@ -24,7 +24,10 @@ function isBuilder<Builder extends JSONEncodable<any>>(
|
|
|
24
24
|
* @param builder - The user input, as described in the function description
|
|
25
25
|
* @param Constructor - The constructor of the builder
|
|
26
26
|
*/
|
|
27
|
-
export function resolveBuilder<
|
|
27
|
+
export function resolveBuilder<
|
|
28
|
+
Builder extends JSONEncodable<unknown>,
|
|
29
|
+
BuilderData extends Record<PropertyKey, unknown>,
|
|
30
|
+
>(
|
|
28
31
|
builder: Builder | BuilderData | ((builder: Builder) => Builder),
|
|
29
32
|
Constructor: new (data?: BuilderData) => Builder,
|
|
30
33
|
): Builder {
|
package/src/util/validation.ts
CHANGED
|
@@ -9,7 +9,8 @@ let validationEnabled = true;
|
|
|
9
9
|
* @returns Whether validation is occurring.
|
|
10
10
|
*/
|
|
11
11
|
export function enableValidators() {
|
|
12
|
-
|
|
12
|
+
validationEnabled = true;
|
|
13
|
+
return validationEnabled;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -18,7 +19,8 @@ export function enableValidators() {
|
|
|
18
19
|
* @returns Whether validation is occurring.
|
|
19
20
|
*/
|
|
20
21
|
export function disableValidators() {
|
|
21
|
-
|
|
22
|
+
validationEnabled = false;
|
|
23
|
+
return validationEnabled;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/**
|