mirror of
https://github.com/discordjs/discord.js.git
synced 2026-05-28 06:20:10 +00:00
Compare commits
12 Commits
refactor/c
...
feat/build
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a9c6ee7b3 | ||
|
|
ff9b2ca14b | ||
|
|
a1c4501464 | ||
|
|
1c5674d9b2 | ||
|
|
5efde1162f | ||
|
|
9201243f32 | ||
|
|
0d76f1149f | ||
|
|
b3705df547 | ||
|
|
2d740d5279 | ||
|
|
beed098bf2 | ||
|
|
7886d9b098 | ||
|
|
5247afe983 |
@@ -32,4 +32,11 @@ describe('Separator', () => {
|
||||
expect(separator.toJSON()).toEqual({ type: ComponentType.Separator });
|
||||
});
|
||||
});
|
||||
|
||||
describe('Invalid id', () => {
|
||||
test('GIVEN a separator with a set spacing and an invalid set id THEN throws error', () => {
|
||||
const separator = new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large).setId(-1);
|
||||
expect(() => separator.toJSON()).toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,11 @@ describe('TextDisplay', () => {
|
||||
expect(textDisplay.toJSON()).toEqual({ type: ComponentType.TextDisplay, content: 'foo' });
|
||||
});
|
||||
|
||||
test('GIVEN a text display with a set content with an invalid id THEN throws error', () => {
|
||||
const textDisplay = new TextDisplayBuilder().setContent('foo').setId(5.5);
|
||||
expect(() => textDisplay.toJSON()).toThrowError();
|
||||
});
|
||||
|
||||
test('GIVEN a text display with a pre-defined content THEN overwritten content THEN return valid toJSON data', () => {
|
||||
const textDisplay = new TextDisplayBuilder({ content: 'foo' });
|
||||
textDisplay.setContent('bar');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Locale } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const idPredicate = z.int().min(0).max(2_147_483_647).optional();
|
||||
export const customIdPredicate = z.string().min(1).max(100);
|
||||
|
||||
export const memberPermissionsPredicate = z.coerce.bigint();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ButtonStyle, ChannelType, ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { customIdPredicate } from '../Assertions.js';
|
||||
import { idPredicate, customIdPredicate } from '../Assertions.js';
|
||||
|
||||
const labelPredicate = z.string().min(1).max(80);
|
||||
|
||||
@@ -52,6 +52,7 @@ export const buttonPredicate = z.discriminatedUnion('style', [
|
||||
]);
|
||||
|
||||
const selectMenuBasePredicate = z.object({
|
||||
id: idPredicate,
|
||||
placeholder: z.string().max(150).optional(),
|
||||
min_values: z.number().min(0).max(25).optional(),
|
||||
max_values: z.number().min(0).max(25).optional(),
|
||||
@@ -135,6 +136,7 @@ export const selectMenuUserPredicate = selectMenuBasePredicate.extend({
|
||||
});
|
||||
|
||||
export const actionRowPredicate = z.object({
|
||||
id: idPredicate,
|
||||
type: z.literal(ComponentType.ActionRow),
|
||||
components: z.union([
|
||||
z
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIBaseComponent, ComponentType } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../mixins/Refineable.js';
|
||||
|
||||
export interface ComponentBuilderBaseData {
|
||||
id?: number | undefined;
|
||||
@@ -11,6 +12,7 @@ export interface ComponentBuilderBaseData {
|
||||
* @typeParam Component - The type of API data that is stored within the builder
|
||||
*/
|
||||
export abstract class ComponentBuilder<Component extends APIBaseComponent<ComponentType>>
|
||||
extends Refineable
|
||||
implements JSONEncodable<Component>
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { idPredicate } from '../../Assertions';
|
||||
import {
|
||||
selectMenuChannelPredicate,
|
||||
selectMenuMentionablePredicate,
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
import { textInputPredicate } from '../textInput/Assertions';
|
||||
|
||||
export const labelPredicate = z.object({
|
||||
id: idPredicate,
|
||||
type: z.literal(ComponentType.Label),
|
||||
label: z.string().min(1).max(45),
|
||||
description: z.string().min(1).max(100).optional(),
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v10';
|
||||
import type { APISelectMenuOption, APIMessageComponentEmoji } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
import { selectMenuStringOptionPredicate } from '../Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for string select menu options.
|
||||
*/
|
||||
export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
|
||||
export class StringSelectMenuOptionBuilder extends Refineable implements JSONEncodable<APISelectMenuOption> {
|
||||
private readonly data: Partial<APISelectMenuOption>;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,7 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
||||
* ```
|
||||
*/
|
||||
public constructor(data: Partial<APISelectMenuOption> = {}) {
|
||||
super();
|
||||
this.data = structuredClone(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { customIdPredicate } from '../../Assertions.js';
|
||||
import { customIdPredicate, idPredicate } from '../../Assertions.js';
|
||||
|
||||
export const textInputPredicate = z.object({
|
||||
id: idPredicate,
|
||||
type: z.literal(ComponentType.TextInput),
|
||||
custom_id: customIdPredicate,
|
||||
style: z.enum(TextInputStyle),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ComponentType, SeparatorSpacingSize } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { idPredicate } from '../../Assertions.js';
|
||||
import { actionRowPredicate } from '../Assertions.js';
|
||||
|
||||
const unfurledMediaItemPredicate = z.object({
|
||||
@@ -7,6 +8,8 @@ const unfurledMediaItemPredicate = z.object({
|
||||
});
|
||||
|
||||
export const thumbnailPredicate = z.object({
|
||||
type: z.literal(ComponentType.Thumbnail),
|
||||
id: idPredicate,
|
||||
media: unfurledMediaItemPredicate,
|
||||
description: z.string().min(1).max(1_024).nullish(),
|
||||
spoiler: z.boolean().optional(),
|
||||
@@ -17,30 +20,41 @@ const unfurledMediaItemAttachmentOnlyPredicate = z.object({
|
||||
});
|
||||
|
||||
export const filePredicate = z.object({
|
||||
type: z.literal(ComponentType.File),
|
||||
id: idPredicate,
|
||||
file: unfurledMediaItemAttachmentOnlyPredicate,
|
||||
spoiler: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const separatorPredicate = z.object({
|
||||
type: z.literal(ComponentType.Separator),
|
||||
id: idPredicate,
|
||||
divider: z.boolean().optional(),
|
||||
spacing: z.enum(SeparatorSpacingSize).optional(),
|
||||
});
|
||||
|
||||
export const textDisplayPredicate = z.object({
|
||||
type: z.literal(ComponentType.TextDisplay),
|
||||
id: idPredicate,
|
||||
content: z.string().min(1).max(4_000),
|
||||
});
|
||||
|
||||
export const mediaGalleryItemPredicate = z.object({
|
||||
id: idPredicate,
|
||||
media: unfurledMediaItemPredicate,
|
||||
description: z.string().min(1).max(1_024).nullish(),
|
||||
spoiler: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const mediaGalleryPredicate = z.object({
|
||||
type: z.literal(ComponentType.MediaGallery),
|
||||
id: idPredicate,
|
||||
items: z.array(mediaGalleryItemPredicate).min(1).max(10),
|
||||
});
|
||||
|
||||
export const sectionPredicate = z.object({
|
||||
type: z.literal(ComponentType.Section),
|
||||
id: idPredicate,
|
||||
components: z.array(textDisplayPredicate).min(1).max(3),
|
||||
accessory: z.union([
|
||||
z.object({ type: z.literal(ComponentType.Button) }),
|
||||
@@ -49,6 +63,8 @@ export const sectionPredicate = z.object({
|
||||
});
|
||||
|
||||
export const containerPredicate = z.object({
|
||||
type: z.literal(ComponentType.Container),
|
||||
id: idPredicate,
|
||||
components: z
|
||||
.array(
|
||||
z.union([
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIMediaGalleryItem } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
import { mediaGalleryItemPredicate } from './Assertions.js';
|
||||
|
||||
export class MediaGalleryItemBuilder implements JSONEncodable<APIMediaGalleryItem> {
|
||||
export class MediaGalleryItemBuilder extends Refineable implements JSONEncodable<APIMediaGalleryItem> {
|
||||
private readonly data: Partial<APIMediaGalleryItem>;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,7 @@ export class MediaGalleryItemBuilder implements JSONEncodable<APIMediaGalleryIte
|
||||
* ```
|
||||
*/
|
||||
public constructor(data: Partial<APIMediaGalleryItem> = {}) {
|
||||
super();
|
||||
this.data = structuredClone(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
Permissions,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
} from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import type { RestOrArray } from '../../util/normalizeArray.js';
|
||||
import { normalizeArray } from '../../util/normalizeArray.js';
|
||||
|
||||
@@ -20,6 +21,7 @@ export interface CommandData
|
||||
* The base class for all command builders.
|
||||
*/
|
||||
export abstract class CommandBuilder<Command extends RESTPostAPIApplicationCommandsJSONBody>
|
||||
extends Refineable
|
||||
implements JSONEncodable<Command>
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locale, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
|
||||
export interface SharedNameData
|
||||
extends Partial<Pick<RESTPostAPIApplicationCommandsJSONBody, 'name_localizations' | 'name'>> {}
|
||||
@@ -6,7 +7,7 @@ export interface SharedNameData
|
||||
/**
|
||||
* This mixin holds name and description symbols for chat input commands.
|
||||
*/
|
||||
export class SharedName {
|
||||
export class SharedName extends Refineable {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { AnyModalComponentBuilder } from '../../components/Components.js';
|
||||
import { createComponentBuilder } from '../../components/Components.js';
|
||||
import { LabelBuilder } from '../../components/label/Label.js';
|
||||
import { TextDisplayBuilder } from '../../components/v2/TextDisplay.js';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||
import { resolveBuilder } from '../../util/resolveBuilder.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
@@ -21,7 +22,7 @@ export interface ModalBuilderData extends Partial<Omit<APIModalInteractionRespon
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for modals.
|
||||
*/
|
||||
export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCallbackData> {
|
||||
export class ModalBuilder extends Refineable implements JSONEncodable<APIModalInteractionResponseCallbackData> {
|
||||
/**
|
||||
* The API data associated with this modal.
|
||||
*/
|
||||
@@ -40,6 +41,7 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
||||
* @param data - The API data to create this modal with
|
||||
*/
|
||||
public constructor(data: Partial<APIModalInteractionResponseCallbackData> = {}) {
|
||||
super();
|
||||
const { components = [], ...rest } = data;
|
||||
|
||||
this.data = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { AllowedMentionsTypes, APIAllowedMentions, Snowflake } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../mixins/Refineable.js';
|
||||
import { normalizeArray, type RestOrArray } from '../util/normalizeArray.js';
|
||||
import { validate } from '../util/validation.js';
|
||||
import { allowedMentionPredicate } from './Assertions.js';
|
||||
@@ -7,7 +8,7 @@ import { allowedMentionPredicate } from './Assertions.js';
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for allowed mentions.
|
||||
*/
|
||||
export class AllowedMentionsBuilder implements JSONEncodable<APIAllowedMentions> {
|
||||
export class AllowedMentionsBuilder extends Refineable implements JSONEncodable<APIAllowedMentions> {
|
||||
/**
|
||||
* The API data associated with these allowed mentions.
|
||||
*/
|
||||
@@ -19,7 +20,8 @@ export class AllowedMentionsBuilder implements JSONEncodable<APIAllowedMentions>
|
||||
* @param data - The API data to create this allowed mentions with
|
||||
*/
|
||||
public constructor(data: Partial<APIAllowedMentions> = {}) {
|
||||
this.data = structuredClone(data);
|
||||
super();
|
||||
this.data = { ...structuredClone(data) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { RESTAPIAttachment, Snowflake } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../mixins/Refineable.js';
|
||||
import { validate } from '../util/validation.js';
|
||||
import { attachmentPredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for attachments.
|
||||
*/
|
||||
export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
|
||||
export class AttachmentBuilder extends Refineable implements JSONEncodable<RESTAPIAttachment> {
|
||||
/**
|
||||
* The API data associated with this attachment.
|
||||
*/
|
||||
@@ -15,10 +16,11 @@ export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
|
||||
/**
|
||||
* Creates a new attachment builder.
|
||||
*
|
||||
* @param data - The API data to create this attachment with
|
||||
* @param attachment - The attachment to build from
|
||||
*/
|
||||
public constructor(data: Partial<RESTAPIAttachment> = {}) {
|
||||
this.data = structuredClone(data);
|
||||
public constructor(attachment: Partial<RESTAPIAttachment> = {}) {
|
||||
super();
|
||||
this.data = { ...structuredClone(attachment) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import { MediaGalleryBuilder } from '../components/v2/MediaGallery.js';
|
||||
import { SectionBuilder } from '../components/v2/Section.js';
|
||||
import { SeparatorBuilder } from '../components/v2/Separator.js';
|
||||
import { TextDisplayBuilder } from '../components/v2/TextDisplay.js';
|
||||
import { Refineable } from '../mixins/Refineable.js';
|
||||
import { normalizeArray, type RestOrArray } from '../util/normalizeArray.js';
|
||||
import { resolveBuilder } from '../util/resolveBuilder.js';
|
||||
import { validate } from '../util/validation.js';
|
||||
@@ -56,7 +57,7 @@ export interface MessageBuilderData
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for messages.
|
||||
*/
|
||||
export class MessageBuilder implements JSONEncodable<RESTPostAPIChannelMessageJSONBody> {
|
||||
export class MessageBuilder extends Refineable implements JSONEncodable<RESTPostAPIChannelMessageJSONBody> {
|
||||
/**
|
||||
* The API data associated with this message.
|
||||
*/
|
||||
@@ -89,6 +90,7 @@ export class MessageBuilder implements JSONEncodable<RESTPostAPIChannelMessageJS
|
||||
* @param data - The API data to create this message with
|
||||
*/
|
||||
public constructor(data: Partial<RESTPostAPIChannelMessageJSONBody> = {}) {
|
||||
super();
|
||||
const { attachments = [], embeds = [], components = [], message_reference, poll, allowed_mentions, ...rest } = data;
|
||||
|
||||
this.data = {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { MessageReferenceType, RESTAPIMessageReference, Snowflake } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../mixins/Refineable.js';
|
||||
import { validate } from '../util/validation.js';
|
||||
import { messageReferencePredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for message references.
|
||||
*/
|
||||
export class MessageReferenceBuilder implements JSONEncodable<RESTAPIMessageReference> {
|
||||
export class MessageReferenceBuilder extends Refineable implements JSONEncodable<RESTAPIMessageReference> {
|
||||
/**
|
||||
* The API data associated with this message reference.
|
||||
*/
|
||||
@@ -18,6 +19,7 @@ export class MessageReferenceBuilder implements JSONEncodable<RESTAPIMessageRefe
|
||||
* @param data - The API data to create this message reference with
|
||||
*/
|
||||
public constructor(data: Partial<RESTAPIMessageReference> = {}) {
|
||||
super();
|
||||
this.data = structuredClone(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIEmbed, APIEmbedAuthor, APIEmbedField, APIEmbedFooter } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import type { RestOrArray } from '../../util/normalizeArray.js';
|
||||
import { normalizeArray } from '../../util/normalizeArray.js';
|
||||
import { resolveBuilder } from '../../util/resolveBuilder.js';
|
||||
@@ -21,7 +22,7 @@ export interface EmbedBuilderData extends Omit<APIEmbed, 'author' | 'fields' | '
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for embeds.
|
||||
*/
|
||||
export class EmbedBuilder implements JSONEncodable<APIEmbed> {
|
||||
export class EmbedBuilder extends Refineable implements JSONEncodable<APIEmbed> {
|
||||
/**
|
||||
* The API data associated with this embed.
|
||||
*/
|
||||
@@ -40,6 +41,7 @@ export class EmbedBuilder implements JSONEncodable<APIEmbed> {
|
||||
* @param data - The API data to create this embed with
|
||||
*/
|
||||
public constructor(data: Partial<APIEmbed> = {}) {
|
||||
super();
|
||||
const { author, fields = [], footer, ...rest } = data;
|
||||
|
||||
this.data = {
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIEmbedAuthor } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
import { embedAuthorPredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for the embed author.
|
||||
* A builder that creates API-compatible JSON data for embed authors.
|
||||
*/
|
||||
export class EmbedAuthorBuilder implements JSONEncodable<APIEmbedAuthor> {
|
||||
export class EmbedAuthorBuilder extends Refineable implements JSONEncodable<APIEmbedAuthor> {
|
||||
/**
|
||||
* The API data associated with this embed author.
|
||||
*/
|
||||
private readonly data: Partial<APIEmbedAuthor>;
|
||||
|
||||
/**
|
||||
* Creates a new embed author.
|
||||
* Creates a new embed author builder.
|
||||
*
|
||||
* @param data - The API data to create this embed author with
|
||||
*/
|
||||
public constructor(data: Partial<APIEmbedAuthor> = {}) {
|
||||
this.data = structuredClone(data);
|
||||
super();
|
||||
this.data = { ...structuredClone(data) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIEmbedField } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
import { embedFieldPredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for embed fields.
|
||||
*/
|
||||
export class EmbedFieldBuilder implements JSONEncodable<APIEmbedField> {
|
||||
export class EmbedFieldBuilder extends Refineable implements JSONEncodable<APIEmbedField> {
|
||||
/**
|
||||
* The API data associated with this embed field.
|
||||
*/
|
||||
private readonly data: Partial<APIEmbedField>;
|
||||
|
||||
/**
|
||||
* Creates a new embed field.
|
||||
* Creates a new embed field builder.
|
||||
*
|
||||
* @param data - The API data to create this embed field with
|
||||
*/
|
||||
public constructor(data: Partial<APIEmbedField> = {}) {
|
||||
this.data = structuredClone(data);
|
||||
super();
|
||||
this.data = { ...structuredClone(data) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIEmbedFooter } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
import { embedFooterPredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for the embed footer.
|
||||
* A builder that creates API-compatible JSON data for embed footers.
|
||||
*/
|
||||
export class EmbedFooterBuilder implements JSONEncodable<APIEmbedFooter> {
|
||||
export class EmbedFooterBuilder extends Refineable implements JSONEncodable<APIEmbedFooter> {
|
||||
/**
|
||||
* The API data associated with this embed footer.
|
||||
*/
|
||||
private readonly data: Partial<APIEmbedFooter>;
|
||||
|
||||
/**
|
||||
* Creates a new embed footer.
|
||||
* Creates a new embed footer builder.
|
||||
*
|
||||
* @param data - The API data to create this embed footer with
|
||||
*/
|
||||
public constructor(data: Partial<APIEmbedFooter> = {}) {
|
||||
this.data = structuredClone(data);
|
||||
super();
|
||||
this.data = { ...structuredClone(data) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { RESTAPIPoll, APIPollMedia, PollLayoutType, APIPollAnswer } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||
import { resolveBuilder } from '../../util/resolveBuilder.js';
|
||||
import { validate } from '../../util/validation.js';
|
||||
@@ -15,7 +16,7 @@ export interface PollData extends Omit<RESTAPIPoll, 'answers' | 'question'> {
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for polls.
|
||||
*/
|
||||
export class PollBuilder implements JSONEncodable<RESTAPIPoll> {
|
||||
export class PollBuilder extends Refineable implements JSONEncodable<RESTAPIPoll> {
|
||||
/**
|
||||
* The API data associated with this poll.
|
||||
*/
|
||||
@@ -34,6 +35,7 @@ export class PollBuilder implements JSONEncodable<RESTAPIPoll> {
|
||||
* @param data - The API data to create this poll with
|
||||
*/
|
||||
public constructor(data: Partial<RESTAPIPoll> = {}) {
|
||||
super();
|
||||
const { question, answers = [], ...rest } = data;
|
||||
|
||||
this.data = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIPollAnswer, APIPollMedia } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
import { resolveBuilder } from '../../util/resolveBuilder';
|
||||
import { validate } from '../../util/validation';
|
||||
import { pollAnswerPredicate } from './Assertions';
|
||||
@@ -12,7 +13,7 @@ export interface PollAnswerData extends Omit<APIPollAnswer, 'answer_id' | 'poll_
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for poll answers.
|
||||
*/
|
||||
export class PollAnswerBuilder implements JSONEncodable<Omit<APIPollAnswer, 'answer_id'>> {
|
||||
export class PollAnswerBuilder extends Refineable implements JSONEncodable<Omit<APIPollAnswer, 'answer_id'>> {
|
||||
/**
|
||||
* The API data associated with this poll answer.
|
||||
*/
|
||||
@@ -24,6 +25,7 @@ export class PollAnswerBuilder implements JSONEncodable<Omit<APIPollAnswer, 'ans
|
||||
* @param data - The API data to create this poll answer with
|
||||
*/
|
||||
public constructor(data: Partial<Omit<APIPollAnswer, 'answer_id'>> = {}) {
|
||||
super();
|
||||
const { poll_media, ...rest } = data;
|
||||
|
||||
this.data = {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { APIPollMedia } from 'discord-api-types/v10';
|
||||
import { Refineable } from '../../mixins/Refineable.js';
|
||||
|
||||
/**
|
||||
* The base poll media builder that contains common symbols for poll media builders.
|
||||
*/
|
||||
export abstract class PollMediaBuilder {
|
||||
export abstract class PollMediaBuilder extends Refineable {
|
||||
/**
|
||||
* The API data associated with this poll media.
|
||||
*
|
||||
@@ -17,6 +18,7 @@ export abstract class PollMediaBuilder {
|
||||
* @param data - The API data to create this poll media with
|
||||
*/
|
||||
public constructor(data: Partial<APIPollMedia> = {}) {
|
||||
super();
|
||||
this.data = structuredClone(data);
|
||||
}
|
||||
|
||||
|
||||
28
packages/builders/src/mixins/Refineable.ts
Normal file
28
packages/builders/src/mixins/Refineable.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Mixin used to provide {@link Refineable.refine}
|
||||
*/
|
||||
export class Refineable {
|
||||
/**
|
||||
* Refines this builder by applying the provided function to itself.
|
||||
* Useful for conditionally modifying the builder without breaking the method chain, while also isolating
|
||||
* the scope of temporary variables.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const builder = new EmbedBuilder()
|
||||
* .setTitle('Hello World')
|
||||
* .setDescription('This is a description')
|
||||
* .refine((b) => {
|
||||
* const intermediateValue = computeSomething();
|
||||
* b.setFooter(`Computed value: ${intermediateValue}`);
|
||||
* if (externalVariable) {
|
||||
* b.setColor(0xff0000);
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public refine(fn: (builder: this) => void): this {
|
||||
fn(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -70,8 +70,7 @@
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"@sapphire/snowflake": "^3.5.5",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.23",
|
||||
"type-fest": "^5.0.0"
|
||||
"discord-api-types": "^0.38.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
type RESTPutAPIApplicationGuildCommandsResult,
|
||||
type Snowflake,
|
||||
} from 'discord-api-types/v10';
|
||||
import type { APIOptions } from '../util/api-options.js';
|
||||
|
||||
export class ApplicationCommandsAPI {
|
||||
public constructor(private readonly rest: REST) {}
|
||||
@@ -36,21 +35,19 @@ export class ApplicationCommandsAPI {
|
||||
* Fetches all global commands for a application
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands}
|
||||
* @param applicationId - The application id to fetch commands for
|
||||
* @param query - The query options for fetching commands
|
||||
* @param options - The options for fetching commands
|
||||
*/
|
||||
public async getGlobalCommands({
|
||||
query,
|
||||
route: { applicationId },
|
||||
options,
|
||||
}: APIOptions<
|
||||
Pick<RequestData, 'auth' | 'signal'>,
|
||||
{ applicationId: Snowflake },
|
||||
never,
|
||||
RESTGetAPIApplicationCommandsQuery
|
||||
>) {
|
||||
public async getGlobalCommands(
|
||||
applicationId: Snowflake,
|
||||
query: RESTGetAPIApplicationCommandsQuery = {},
|
||||
{ auth, signal }: Pick<RequestData, 'auth' | 'signal'> = {},
|
||||
) {
|
||||
return this.rest.get(Routes.applicationCommands(applicationId), {
|
||||
...options,
|
||||
auth,
|
||||
query: makeURLSearchParams(query),
|
||||
signal,
|
||||
}) as Promise<RESTGetAPIApplicationCommandsResult>;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
type RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody,
|
||||
type RESTPatchAPIGuildVoiceStateUserResult,
|
||||
} from 'discord-api-types/v10';
|
||||
import type { APIOptions } from '../util/api-options.js';
|
||||
|
||||
export class VoiceAPI {
|
||||
public constructor(private readonly rest: REST) {}
|
||||
@@ -23,8 +22,8 @@ export class VoiceAPI {
|
||||
* @see {@link https://discord.com/developers/docs/resources/voice#list-voice-regions}
|
||||
* @param options - The options for fetching the voice regions
|
||||
*/
|
||||
public async getVoiceRegions({ options }: APIOptions<Pick<RequestData, 'auth' | 'signal'>> = {}) {
|
||||
return this.rest.get(Routes.voiceRegions(), options) as Promise<RESTGetAPIVoiceRegionsResult>;
|
||||
public async getVoiceRegions({ auth, signal }: Pick<RequestData, 'auth' | 'signal'> = {}) {
|
||||
return this.rest.get(Routes.voiceRegions(), { auth, signal }) as Promise<RESTGetAPIVoiceRegionsResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { RequestData } from '@discordjs/rest';
|
||||
import type { If, IsNever, RequiredKeysOf } from 'type-fest';
|
||||
|
||||
/**
|
||||
* Creates the input type for an API method with optional properties based on the provided type parameters.
|
||||
*
|
||||
* @typeParam Options - Options for the request.
|
||||
* @typeParam Route - Route parameters for the endpoint.
|
||||
* @typeParam Body - Body for the request.
|
||||
* @typeParam Query - Query parameters for the endpoint.
|
||||
*/
|
||||
export type APIOptions<
|
||||
Options extends RequestData,
|
||||
Route extends object = never,
|
||||
Body extends object = never,
|
||||
Query extends object = never,
|
||||
> = If<IsNever<Body>, object, If<IsNever<RequiredKeysOf<Body>>, { body?: Body }, { body: Body }>> &
|
||||
If<IsNever<Query>, object, If<IsNever<RequiredKeysOf<Query>>, { query?: Query }, { query: Query }>> &
|
||||
If<IsNever<Route>, object, { route: Route }> & { options?: Options };
|
||||
@@ -1,2 +1 @@
|
||||
export type * from './api-options.js';
|
||||
export * from './files.js';
|
||||
|
||||
@@ -114,8 +114,10 @@
|
||||
* @property {'CommandInteractionOptionInvalidChannelType'} CommandInteractionOptionInvalidChannelType
|
||||
* @property {'AutocompleteInteractionOptionNoFocusedOption'} AutocompleteInteractionOptionNoFocusedOption
|
||||
*
|
||||
* @property {'ModalSubmitInteractionFieldNotFound'} ModalSubmitInteractionFieldNotFound
|
||||
* @property {'ModalSubmitInteractionFieldType'} ModalSubmitInteractionFieldType
|
||||
* @property {'ModalSubmitInteractionComponentNotFound'} ModalSubmitInteractionComponentNotFound
|
||||
* @property {'ModalSubmitInteractionComponentType'} ModalSubmitInteractionComponentType
|
||||
* @property {'ModalSubmitInteractionComponentEmpty'} ModalSubmitInteractionComponentEmpty
|
||||
* @property {'ModalSubmitInteractionComponentInvalidChannelType'} ModalSubmitInteractionComponentInvalidChannelType
|
||||
*
|
||||
* @property {'InvalidMissingScopes'} InvalidMissingScopes
|
||||
* @property {'InvalidScopesWithPermissions'} InvalidScopesWithPermissions
|
||||
@@ -248,8 +250,10 @@ const keys = [
|
||||
'CommandInteractionOptionInvalidChannelType',
|
||||
'AutocompleteInteractionOptionNoFocusedOption',
|
||||
|
||||
'ModalSubmitInteractionFieldNotFound',
|
||||
'ModalSubmitInteractionFieldType',
|
||||
'ModalSubmitInteractionComponentNotFound',
|
||||
'ModalSubmitInteractionComponentType',
|
||||
'ModalSubmitInteractionComponentEmpty',
|
||||
'ModalSubmitInteractionComponentInvalidChannelType',
|
||||
|
||||
'InvalidMissingScopes',
|
||||
'InvalidScopesWithPermissions',
|
||||
|
||||
@@ -127,10 +127,14 @@ const Messages = {
|
||||
`The type of channel of the option "${name}" is: ${type}; expected ${expected}.`,
|
||||
[ErrorCodes.AutocompleteInteractionOptionNoFocusedOption]: 'No focused option for autocomplete interaction.',
|
||||
|
||||
[ErrorCodes.ModalSubmitInteractionFieldNotFound]: customId =>
|
||||
`Required field with custom id "${customId}" not found.`,
|
||||
[ErrorCodes.ModalSubmitInteractionFieldType]: (customId, type, expected) =>
|
||||
`Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||
[ErrorCodes.ModalSubmitInteractionComponentNotFound]: customId =>
|
||||
`Required component with custom id "${customId}" not found.`,
|
||||
[ErrorCodes.ModalSubmitInteractionComponentType]: (customId, type, expected) =>
|
||||
`Component with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||
[ErrorCodes.ModalSubmitInteractionComponentEmpty]: (customId, type) =>
|
||||
`Required component with custom id "${customId}" is of type: ${type}; expected a non-empty value.`,
|
||||
[ErrorCodes.ModalSubmitInteractionComponentInvalidChannelType]: (customId, type, expected) =>
|
||||
`The type of channel of the component with custom id "${customId}" is: ${type}; expected ${expected}.`,
|
||||
|
||||
[ErrorCodes.InvalidMissingScopes]: 'At least one valid scope must be provided for the invite',
|
||||
[ErrorCodes.InvalidScopesWithPermissions]: 'Permissions cannot be set without the bot scope.',
|
||||
|
||||
@@ -199,7 +199,7 @@ exports.MessageContextMenuCommandInteraction =
|
||||
exports.MessageMentions = require('./structures/MessageMentions.js').MessageMentions;
|
||||
exports.MessagePayload = require('./structures/MessagePayload.js').MessagePayload;
|
||||
exports.MessageReaction = require('./structures/MessageReaction.js').MessageReaction;
|
||||
exports.ModalSubmitFields = require('./structures/ModalSubmitFields.js').ModalSubmitFields;
|
||||
exports.ModalComponentResolver = require('./structures/ModalComponentResolver.js').ModalComponentResolver;
|
||||
exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction.js').ModalSubmitInteraction;
|
||||
exports.OAuth2Guild = require('./structures/OAuth2Guild.js').OAuth2Guild;
|
||||
exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel.js').PartialGroupDMChannel;
|
||||
|
||||
@@ -9,6 +9,7 @@ const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } =
|
||||
const { BaseGuildVoiceChannel } = require('../structures/BaseGuildVoiceChannel.js');
|
||||
const { GuildMember } = require('../structures/GuildMember.js');
|
||||
const { Role } = require('../structures/Role.js');
|
||||
const { resolveImage } = require('../util/DataResolver.js');
|
||||
const { Events } = require('../util/Events.js');
|
||||
const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField.js');
|
||||
const { Partials } = require('../util/Partials.js');
|
||||
@@ -358,8 +359,7 @@ class GuildMemberManager extends CachedManager {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits a member of the guild.
|
||||
* <info>The user must be a member of the guild</info>
|
||||
* Edits a member of a guild.
|
||||
*
|
||||
* @param {UserResolvable} user The member to edit
|
||||
* @param {GuildMemberEditOptions} options The options to provide
|
||||
@@ -396,22 +396,44 @@ class GuildMemberManager extends CachedManager {
|
||||
options.flags = GuildMemberFlagsBitField.resolve(options.flags);
|
||||
}
|
||||
|
||||
let endpoint;
|
||||
if (id === this.client.user.id) {
|
||||
const keys = Object.keys(options);
|
||||
if (keys.length === 1 && keys[0] === 'nick') endpoint = Routes.guildMember(this.guild.id);
|
||||
else endpoint = Routes.guildMember(this.guild.id, id);
|
||||
} else {
|
||||
endpoint = Routes.guildMember(this.guild.id, id);
|
||||
}
|
||||
|
||||
const data = await this.client.rest.patch(endpoint, { body: options, reason });
|
||||
|
||||
const data = await this.client.rest.patch(Routes.guildMember(this.guild.id, id), { body: options, reason });
|
||||
const clone = this.cache.get(id)?._clone();
|
||||
clone?._patch(data);
|
||||
return clone ?? this._add(data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data for editing the current application's guild member.
|
||||
*
|
||||
* @typedef {Object} GuildMemberEditMeOptions
|
||||
* @property {?string} [nick] The nickname to set
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [banner] The banner to set
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [avatar] The avatar to set
|
||||
* @property {?string} [bio] The bio to set
|
||||
* @property {string} [reason] The reason to use
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits the current application's guild member in a guild.
|
||||
*
|
||||
* @param {GuildMemberEditMeOptions} options The options to provide
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
async editMe({ reason, ...options }) {
|
||||
const data = await this.client.rest.patch(Routes.guildMember(this.guild.id, '@me'), {
|
||||
body: {
|
||||
...options,
|
||||
banner: options.banner && (await resolveImage(options.banner)),
|
||||
avatar: options.avatar && (await resolveImage(options.avatar)),
|
||||
},
|
||||
reason,
|
||||
});
|
||||
|
||||
const clone = this.me?._clone();
|
||||
clone?._patch(data);
|
||||
return clone ?? this._add(data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used for pruning guild members.
|
||||
* <info>It's recommended to set {@link GuildPruneMembersOptions#count options.count}
|
||||
|
||||
@@ -83,7 +83,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* The name localizations for this command
|
||||
*
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.nameLocalizations = data.name_localizations;
|
||||
} else {
|
||||
@@ -114,7 +114,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* The description localizations for this command
|
||||
*
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.descriptionLocalizations = data.description_localizations;
|
||||
} else {
|
||||
@@ -239,11 +239,11 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandData
|
||||
* @property {string} name The name of the command, must be in all lowercase if type is
|
||||
* {@link ApplicationCommandType.ChatInput}
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
|
||||
* @property {LocalizationMap} [nameLocalizations] The localizations for the command name
|
||||
* @property {string} description The description of the command,
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {boolean} [nsfw] Whether the command is age-restricted
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description,
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The localizations for the command description,
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
|
||||
* @property {ApplicationCommandOptionData[]} [options] Options for the command
|
||||
@@ -265,9 +265,9 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandOptionData
|
||||
* @property {ApplicationCommandOptionType} type The type of the option
|
||||
* @property {string} name The name of the option
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The name localizations for the option
|
||||
* @property {LocalizationMap} [nameLocalizations] The name localizations for the option
|
||||
* @property {string} description The description of the option
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The description localizations for the option
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The description localizations for the option
|
||||
* @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
|
||||
* {@link ApplicationCommandOptionType.String}, {@link ApplicationCommandOptionType.Integer} or
|
||||
* {@link ApplicationCommandOptionType.Number} option
|
||||
@@ -289,7 +289,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* @typedef {Object} ApplicationCommandOptionChoiceData
|
||||
* @property {string} name The name of the choice
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localized names for this choice
|
||||
* @property {LocalizationMap} [nameLocalizations] The localized names for this choice
|
||||
* @property {string|number} value The value of the choice
|
||||
*/
|
||||
|
||||
@@ -323,7 +323,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* Edits the localized names of this ApplicationCommand
|
||||
*
|
||||
* @param {Object<Locale, string>} nameLocalizations The new localized names for the command
|
||||
* @param {LocalizationMap} nameLocalizations The new localized names for the command
|
||||
* @returns {Promise<ApplicationCommand>}
|
||||
* @example
|
||||
* // Edit the name localizations of this command
|
||||
@@ -351,7 +351,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* Edits the localized descriptions of this ApplicationCommand
|
||||
*
|
||||
* @param {Object<Locale, string>} descriptionLocalizations The new localized descriptions for the command
|
||||
* @param {LocalizationMap} descriptionLocalizations The new localized descriptions for the command
|
||||
* @returns {Promise<ApplicationCommand>}
|
||||
* @example
|
||||
* // Edit the description localizations of this command
|
||||
@@ -568,10 +568,10 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandOption
|
||||
* @property {ApplicationCommandOptionType} type The type of the option
|
||||
* @property {string} name The name of the option
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the option name
|
||||
* @property {LocalizationMap} [nameLocalizations] The localizations for the option name
|
||||
* @property {string} [nameLocalized] The localized name for this option
|
||||
* @property {string} description The description of the option
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the option description
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The localizations for the option description
|
||||
* @property {string} [descriptionLocalized] The localized description for this option
|
||||
* @property {boolean} [required] Whether the option is required
|
||||
* @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
|
||||
@@ -597,7 +597,7 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandOptionChoice
|
||||
* @property {string} name The name of the choice
|
||||
* @property {?string} nameLocalized The localized name of the choice in the provided locale, if any
|
||||
* @property {?Object<Locale, string>} [nameLocalizations] The localized names for this choice
|
||||
* @property {?LocalizationMap} [nameLocalizations] The localized names for this choice
|
||||
* @property {string|number} value The value of the choice
|
||||
*/
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class ApplicationRoleConnectionMetadata {
|
||||
/**
|
||||
* The name localizations for this metadata field
|
||||
*
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.nameLocalizations = data.name_localizations ?? null;
|
||||
|
||||
@@ -29,7 +29,7 @@ class ApplicationRoleConnectionMetadata {
|
||||
/**
|
||||
* The description localizations for this metadata field
|
||||
*
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.descriptionLocalizations = data.description_localizations ?? null;
|
||||
|
||||
|
||||
@@ -407,9 +407,9 @@ class ClientApplication extends Application {
|
||||
*
|
||||
* @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
|
||||
* @property {string} name The name of the metadata field
|
||||
* @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
|
||||
* @property {?LocalizationMap} [nameLocalizations] The name localizations for the metadata field
|
||||
* @property {string} description The description of the metadata field
|
||||
* @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
|
||||
* @property {?LocalizationMap} [descriptionLocalizations] The description localizations for the metadata field
|
||||
* @property {string} key The dictionary key of the metadata field
|
||||
* @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
|
||||
*/
|
||||
|
||||
@@ -91,13 +91,17 @@ class CommandInteraction extends BaseInteraction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the resolved data of a received command interaction.
|
||||
*
|
||||
* @typedef {Object} CommandInteractionResolvedData
|
||||
* @typedef {Object} BaseInteractionResolvedData
|
||||
* @property {Collection<Snowflake, User>} [users] The resolved users
|
||||
* @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
|
||||
* @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
|
||||
* @property {Collection<Snowflake, BaseChannel|APIChannel>} [channels] The resolved channels
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the resolved data of a received command interaction.
|
||||
*
|
||||
* @typedef {BaseInteractionResolvedData} CommandInteractionResolvedData
|
||||
* @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
|
||||
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
|
||||
*/
|
||||
|
||||
@@ -459,7 +459,9 @@ class GuildMember extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async setNickname(nick, reason) {
|
||||
return this.edit({ nick, reason });
|
||||
return this.user.id === this.client.user.id
|
||||
? this.guild.members.editMe({ nick, reason })
|
||||
: this.edit({ nick, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -634,7 +634,7 @@ class Message extends Base {
|
||||
* Resolves with a collection of reactions that pass the specified filter.
|
||||
*
|
||||
* @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector
|
||||
* @returns {Promise<Collection<string | Snowflake, MessageReaction>>}
|
||||
* @returns {Promise<Collection<string|Snowflake, MessageReaction>>}
|
||||
* @example
|
||||
* // Create a reaction collector
|
||||
* const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId'
|
||||
|
||||
227
packages/discord.js/src/structures/ModalComponentResolver.js
Normal file
227
packages/discord.js/src/structures/ModalComponentResolver.js
Normal file
@@ -0,0 +1,227 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { ComponentType } = require('discord-api-types/v10');
|
||||
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModalSelectedMentionables
|
||||
* @property {Collection<Snowflake, User>} users The selected users
|
||||
* @property {Collection<Snowflake, GuildMember | APIGuildMember>} members The selected members
|
||||
* @property {Collection<Snowflake, Role | APIRole>} roles The selected roles
|
||||
*/
|
||||
|
||||
/**
|
||||
* A resolver for modal submit components
|
||||
*/
|
||||
class ModalComponentResolver {
|
||||
constructor(client, components, resolved) {
|
||||
/**
|
||||
* The client that instantiated this.
|
||||
*
|
||||
* @name ModalComponentResolver#client
|
||||
* @type {Client}
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(this, 'client', { value: client });
|
||||
|
||||
/**
|
||||
* The interaction resolved data
|
||||
*
|
||||
* @name ModalComponentResolver#resolved
|
||||
* @type {?Readonly<BaseInteractionResolvedData>}
|
||||
*/
|
||||
Object.defineProperty(this, 'resolved', { value: resolved ? Object.freeze(resolved) : null });
|
||||
|
||||
/**
|
||||
* The components within the modal
|
||||
*
|
||||
* @type {Array<ActionRowModalData|LabelModalData|TextDisplayModalData>}
|
||||
*/
|
||||
this.data = components;
|
||||
|
||||
/**
|
||||
* The bottom-level components of the interaction
|
||||
*
|
||||
* @type {Collection<string, ModalData>}
|
||||
*/
|
||||
this.hoistedComponents = components.reduce((accumulator, next) => {
|
||||
// For legacy support of action rows
|
||||
if ('components' in next) {
|
||||
for (const component of next.components) accumulator.set(component.customId, component);
|
||||
}
|
||||
|
||||
// For label components
|
||||
if ('component' in next) {
|
||||
accumulator.set(next.component.customId, next.component);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}, new Collection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a component by custom id.
|
||||
*
|
||||
* @property {string} customId The custom id of the component.
|
||||
* @returns {ModalData}
|
||||
*/
|
||||
getComponent(customId) {
|
||||
const component = this.hoistedComponents.get(customId);
|
||||
|
||||
if (!component) throw new DiscordjsTypeError(ErrorCodes.ModalSubmitInteractionComponentNotFound, customId);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a component by custom id and property and checks its type.
|
||||
*
|
||||
* @param {string} customId The custom id of the component.
|
||||
* @param {ComponentType[]} allowedTypes The allowed types of the component.
|
||||
* @param {string[]} properties The properties to check for for `required`.
|
||||
* @param {boolean} required Whether to throw an error if the component value(s) are not found.
|
||||
* @returns {ModalData} The option, if found.
|
||||
* @private
|
||||
*/
|
||||
_getTypedComponent(customId, allowedTypes, properties, required) {
|
||||
const component = this.getComponent(customId);
|
||||
if (!allowedTypes.includes(component.type)) {
|
||||
throw new DiscordjsTypeError(
|
||||
ErrorCodes.ModalSubmitInteractionComponentType,
|
||||
customId,
|
||||
component.type,
|
||||
allowedTypes.join(', '),
|
||||
);
|
||||
} else if (required && properties.every(prop => component[prop] === null || component[prop] === undefined)) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.ModalSubmitInteractionComponentEmpty, customId, component.type);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a text input component
|
||||
*
|
||||
* @param {string} customId The custom id of the text input component
|
||||
* @returns {?string}
|
||||
*/
|
||||
getTextInputValue(customId) {
|
||||
return this._getTypedComponent(customId, [ComponentType.TextInput]).value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the values of a string select component
|
||||
*
|
||||
* @param {string} customId The custom id of the string select component
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getStringSelectValues(customId) {
|
||||
return this._getTypedComponent(customId, [ComponentType.StringSelect]).values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets users component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?Collection<Snowflake, User>} The selected users, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedUsers(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.UserSelect, ComponentType.MentionableSelect],
|
||||
['users'],
|
||||
required,
|
||||
);
|
||||
return component.users ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets roles component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?Collection<Snowflake, Role|APIRole>} The selected roles, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedRoles(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.RoleSelect, ComponentType.MentionableSelect],
|
||||
['roles'],
|
||||
required,
|
||||
);
|
||||
return component.roles ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channels component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @param {ChannelType[]} [channelTypes=[]] The allowed types of channels. If empty, all channel types are allowed.
|
||||
* @returns {?Collection<Snowflake, GuildChannel|ThreadChannel|APIChannel>} The selected channels, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedChannels(customId, required = false, channelTypes = []) {
|
||||
const component = this._getTypedComponent(customId, [ComponentType.ChannelSelect], ['channels'], required);
|
||||
const channels = component.channels;
|
||||
if (channels && channelTypes.length > 0) {
|
||||
for (const channel of channels.values()) {
|
||||
if (!channelTypes.includes(channel.type)) {
|
||||
throw new DiscordjsTypeError(
|
||||
ErrorCodes.ModalSubmitInteractionComponentInvalidChannelType,
|
||||
customId,
|
||||
channel.type,
|
||||
channelTypes.join(', '),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return channels ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets members component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @returns {?Collection<Snowflake, GuildMember|APIGuildMember>} The selected members, or null if none were selected or the users were not present in the guild
|
||||
*/
|
||||
getSelectedMembers(customId) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.UserSelect, ComponentType.MentionableSelect],
|
||||
['members'],
|
||||
false,
|
||||
);
|
||||
return component.members ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets mentionables component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?ModalSelectedMentionables} The selected mentionables, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedMentionables(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.MentionableSelect],
|
||||
['users', 'members', 'roles'],
|
||||
required,
|
||||
);
|
||||
|
||||
if (component.users || component.members || component.roles) {
|
||||
return {
|
||||
users: component.users ?? new Collection(),
|
||||
members: component.members ?? new Collection(),
|
||||
roles: component.roles ?? new Collection(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
exports.ModalComponentResolver = ModalComponentResolver;
|
||||
@@ -1,78 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { ComponentType } = require('discord-api-types/v10');
|
||||
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
||||
|
||||
/**
|
||||
* Represents the serialized fields from a modal submit interaction
|
||||
*/
|
||||
class ModalSubmitFields {
|
||||
constructor(components) {
|
||||
/**
|
||||
* The components within the modal
|
||||
*
|
||||
* @type {Array<ActionRowModalData | LabelModalData>}
|
||||
*/
|
||||
this.components = components;
|
||||
|
||||
/**
|
||||
* The extracted fields from the modal
|
||||
*
|
||||
* @type {Collection<string, ModalData>}
|
||||
*/
|
||||
this.fields = components.reduce((accumulator, next) => {
|
||||
// NOTE: for legacy support of action rows in modals, which has `components`
|
||||
if ('components' in next) {
|
||||
for (const component of next.components) accumulator.set(component.customId, component);
|
||||
}
|
||||
|
||||
// For label component
|
||||
if ('component' in next) {
|
||||
accumulator.set(next.component.customId, next.component);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}, new Collection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a field given a custom id from a component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {ComponentType} [type] The type of the component
|
||||
* @returns {ModalData}
|
||||
*/
|
||||
getField(customId, type) {
|
||||
const field = this.fields.get(customId);
|
||||
if (!field) throw new DiscordjsTypeError(ErrorCodes.ModalSubmitInteractionFieldNotFound, customId);
|
||||
|
||||
if (type !== undefined && type !== field.type) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.ModalSubmitInteractionFieldType, customId, field.type, type);
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a text input component given a custom id
|
||||
*
|
||||
* @param {string} customId The custom id of the text input component
|
||||
* @returns {string}
|
||||
*/
|
||||
getTextInputValue(customId) {
|
||||
return this.getField(customId, ComponentType.TextInput).value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the values of a string select component given a custom id
|
||||
*
|
||||
* @param {string} customId The custom id of the string select component
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getStringSelectValues(customId) {
|
||||
return this.getField(customId, ComponentType.StringSelect).values;
|
||||
}
|
||||
}
|
||||
|
||||
exports.ModalSubmitFields = ModalSubmitFields;
|
||||
@@ -1,46 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { lazy } = require('@discordjs/util');
|
||||
const { transformResolved } = require('../util/Util.js');
|
||||
const { BaseInteraction } = require('./BaseInteraction.js');
|
||||
const { InteractionWebhook } = require('./InteractionWebhook.js');
|
||||
const { ModalSubmitFields } = require('./ModalSubmitFields.js');
|
||||
const { ModalComponentResolver } = require('./ModalComponentResolver.js');
|
||||
const { InteractionResponses } = require('./interfaces/InteractionResponses.js');
|
||||
|
||||
const getMessage = lazy(() => require('./Message.js').Message);
|
||||
|
||||
/**
|
||||
* @typedef {Object} BaseModalData
|
||||
* @property {ComponentType} type The component type of the field
|
||||
* @property {string} customId The custom id of the field
|
||||
* @property {number} id The id of the field
|
||||
* @property {ComponentType} type The component type of the component
|
||||
* @property {number} id The id of the component
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} SelectMenuModalData
|
||||
* @property {string} customId The custom id of the component
|
||||
* @property {string[]} values The values of the component
|
||||
* @property {Collection<string, GuildMember|APIGuildMember>} [members] The resolved members
|
||||
* @property {Collection<string, User|APIUser>} [users] The resolved users
|
||||
* @property {Collection<string, Role|APIRole>} [roles] The resolved roles
|
||||
* @property {Collection<string, BaseChannel|APIChannel>} [channels] The resolved channels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} TextInputModalData
|
||||
* @property {string} value The value of the field
|
||||
* @property {string} customId The custom id of the component
|
||||
* @property {string} value The value of the component
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} StringSelectModalData
|
||||
* @property {string[]} values The values of the field
|
||||
* @typedef {BaseModalData} TextDisplayModalData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {TextInputModalData | StringSelectModalData} ModalData
|
||||
* @typedef {SelectMenuModalData|TextInputModalData} ModalData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} LabelModalData
|
||||
* @typedef {BaseModalData} LabelModalData
|
||||
* @property {ModalData} component The component within the label
|
||||
* @property {ComponentType} type The component type of the label
|
||||
* @property {number} id The id of the label
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ActionRowModalData
|
||||
* @typedef {BaseModalData} ActionRowModalData
|
||||
* @property {TextInputModalData[]} components The components of this action row
|
||||
* @property {ComponentType} type The component type of the action row
|
||||
* @property {number} id The id of the action row
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -73,16 +80,13 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
/**
|
||||
* The components within the modal
|
||||
*
|
||||
* @type {Array<ActionRowModalData | LabelModalData>}
|
||||
* @type {ModalComponentResolver}
|
||||
*/
|
||||
this.components = data.data.components?.map(component => ModalSubmitInteraction.transformComponent(component));
|
||||
|
||||
/**
|
||||
* The fields within the modal
|
||||
*
|
||||
* @type {ModalSubmitFields}
|
||||
*/
|
||||
this.fields = new ModalSubmitFields(this.components);
|
||||
this.components = new ModalComponentResolver(
|
||||
this.client,
|
||||
data.data.components?.map(component => this.transformComponent(component, data.data.resolved)),
|
||||
transformResolved({ client: this.client, guild: this.guild, channel: this.channel }, data.data.resolved),
|
||||
);
|
||||
|
||||
/**
|
||||
* Whether the reply to this interaction has been deferred
|
||||
@@ -117,15 +121,16 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
* Transforms component data to discord.js-compatible data
|
||||
*
|
||||
* @param {*} rawComponent The data to transform
|
||||
* @param {APIInteractionDataResolved} resolved The resolved data for the interaction
|
||||
* @returns {ModalData[]}
|
||||
* @private
|
||||
*/
|
||||
static transformComponent(rawComponent) {
|
||||
transformComponent(rawComponent, resolved) {
|
||||
if ('components' in rawComponent) {
|
||||
return {
|
||||
type: rawComponent.type,
|
||||
id: rawComponent.id,
|
||||
components: rawComponent.components.map(component => this.transformComponent(component)),
|
||||
components: rawComponent.components.map(component => this.transformComponent(component, resolved)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,18 +138,50 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
return {
|
||||
type: rawComponent.type,
|
||||
id: rawComponent.id,
|
||||
component: this.transformComponent(rawComponent.component),
|
||||
component: this.transformComponent(rawComponent.component, resolved),
|
||||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
type: rawComponent.type,
|
||||
customId: rawComponent.custom_id,
|
||||
id: rawComponent.id,
|
||||
};
|
||||
|
||||
if (rawComponent.value) data.value = rawComponent.value;
|
||||
if (rawComponent.values) data.values = rawComponent.values;
|
||||
// Text display components do not have custom ids.
|
||||
if ('custom_id' in rawComponent) data.customId = rawComponent.custom_id;
|
||||
|
||||
if ('value' in rawComponent) data.value = rawComponent.value;
|
||||
|
||||
if (rawComponent.values) {
|
||||
data.values = rawComponent.values;
|
||||
if (resolved) {
|
||||
const resolveCollection = (resolvedData, resolver) => {
|
||||
const collection = new Collection();
|
||||
for (const value of data.values) {
|
||||
if (resolvedData?.[value]) {
|
||||
collection.set(value, resolver(resolvedData[value]));
|
||||
}
|
||||
}
|
||||
|
||||
return collection.size ? collection : null;
|
||||
};
|
||||
|
||||
const users = resolveCollection(resolved.users, user => this.client.users._add(user));
|
||||
if (users) data.users = users;
|
||||
|
||||
const channels = resolveCollection(
|
||||
resolved.channels,
|
||||
channel => this.client.channels._add(channel, this.guild) ?? channel,
|
||||
);
|
||||
if (channels) data.channels = channels;
|
||||
|
||||
const members = resolveCollection(resolved.members, member => this.guild?.members._add(member) ?? member);
|
||||
if (members) data.members = members;
|
||||
|
||||
const roles = resolveCollection(resolved.roles, role => this.guild?.roles._add(role) ?? role);
|
||||
if (roles) data.roles = roles;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -235,6 +235,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISelectMenuOption}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APISelectMenuDefaultValue
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISelectMenuDefaultValue}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APISectionComponent
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISectionComponent}
|
||||
@@ -534,6 +539,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/Locale}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external LocalizationMap
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#LocalizationMap}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external MessageActivityType
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageActivityType}
|
||||
@@ -649,6 +659,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ThreadAutoArchiveDuration}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ThreadMemberFlags
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ThreadMemberFlags}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external UserFlags
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/UserFlags}
|
||||
|
||||
@@ -19,11 +19,12 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
* @typedef {Object} ModalComponentData
|
||||
* @property {string} title The title of the modal
|
||||
* @property {string} customId The custom id of the modal
|
||||
* @property {LabelData[]} components The components within this modal
|
||||
* @property {Array<TextDisplayComponentData|LabelData>} components The components within this modal
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {StringSelectMenuComponentData|TextInputComponentData} ComponentInLabelData
|
||||
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
|
||||
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData} ComponentInLabelData
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -44,16 +45,41 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} StringSelectMenuComponentData
|
||||
* @typedef {BaseComponentData} BaseSelectMenuComponentData
|
||||
* @property {string} customId The custom id of the select menu
|
||||
* @property {boolean} [disabled] Whether the select menu is disabled or not
|
||||
* @property {number} [maxValues] The maximum amount of options that can be selected
|
||||
* @property {number} [minValues] The minimum amount of options that can be selected
|
||||
* @property {SelectMenuComponentOptionData[]} [options] The options in this select menu
|
||||
* @property {string} [placeholder] The placeholder of the select menu
|
||||
* @property {boolean} [required] Whether this component is required in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} StringSelectMenuComponentData
|
||||
* @property {SelectMenuComponentOptionData[]} [options] The options in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} UserSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} RoleSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} MentionableSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} ChannelSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
* @property {ChannelType[]} [channelTypes] The types of channels that can be selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SelectMenuComponentOptionData
|
||||
* @property {string} label The label of the option
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable jsdoc/check-values */
|
||||
'use strict';
|
||||
|
||||
const { ThreadMemberFlags } = require('discord-api-types/v10');
|
||||
const { BitField } = require('./BitField.js');
|
||||
|
||||
/**
|
||||
@@ -12,10 +13,10 @@ class ThreadMemberFlagsBitField extends BitField {
|
||||
/**
|
||||
* Numeric thread member flags. There are currently no bitflags relevant to bots for this.
|
||||
*
|
||||
* @type {Object<string, number>}
|
||||
* @type {ThreadMemberFlags}
|
||||
* @memberof ThreadMemberFlagsBitField
|
||||
*/
|
||||
static Flags = {};
|
||||
static Flags = ThreadMemberFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
137
packages/discord.js/typings/index.d.ts
vendored
137
packages/discord.js/typings/index.d.ts
vendored
@@ -272,7 +272,13 @@ export interface ActionRowData<ComponentType extends ActionRowComponentData | JS
|
||||
components: readonly ComponentType[];
|
||||
}
|
||||
|
||||
export type ComponentInLabelData = StringSelectMenuComponentData | TextInputComponentData;
|
||||
export type ComponentInLabelData =
|
||||
| ChannelSelectMenuComponentData
|
||||
| MentionableSelectMenuComponentData
|
||||
| RoleSelectMenuComponentData
|
||||
| StringSelectMenuComponentData
|
||||
| TextInputComponentData
|
||||
| UserSelectMenuComponentData;
|
||||
export interface LabelData extends BaseComponentData {
|
||||
component: ComponentInLabelData;
|
||||
description?: string;
|
||||
@@ -2540,48 +2546,113 @@ export interface MessageReactionEventDetails {
|
||||
}
|
||||
|
||||
export interface ModalComponentData {
|
||||
components: readonly LabelData[];
|
||||
components: readonly (LabelData | TextDisplayComponentData)[];
|
||||
customId: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface BaseModalData<Type extends ComponentType> {
|
||||
customId: string;
|
||||
id: number;
|
||||
type: Type;
|
||||
}
|
||||
|
||||
export interface TextInputModalData extends BaseModalData<ComponentType.TextInput> {
|
||||
customId: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface StringSelectModalData extends BaseModalData<ComponentType.StringSelect> {
|
||||
export interface SelectMenuModalData<Cached extends CacheType = CacheType>
|
||||
extends BaseModalData<
|
||||
| ComponentType.ChannelSelect
|
||||
| ComponentType.MentionableSelect
|
||||
| ComponentType.RoleSelect
|
||||
| ComponentType.StringSelect
|
||||
| ComponentType.UserSelect
|
||||
> {
|
||||
channels?: ReadonlyCollection<
|
||||
Snowflake,
|
||||
CacheTypeReducer<Cached, GuildBasedChannel, APIInteractionDataResolvedChannel>
|
||||
>;
|
||||
customId: string;
|
||||
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
|
||||
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
values: readonly string[];
|
||||
}
|
||||
|
||||
export type ModalData = StringSelectModalData | TextInputModalData;
|
||||
export type ModalData = SelectMenuModalData | TextInputModalData;
|
||||
|
||||
export interface LabelModalData {
|
||||
export interface LabelModalData extends BaseModalData<ComponentType.Label> {
|
||||
component: readonly ModalData[];
|
||||
id: number;
|
||||
type: ComponentType.Label;
|
||||
}
|
||||
export interface ActionRowModalData {
|
||||
export interface ActionRowModalData extends BaseModalData<ComponentType.ActionRow> {
|
||||
components: readonly TextInputModalData[];
|
||||
type: ComponentType.ActionRow;
|
||||
}
|
||||
|
||||
export class ModalSubmitFields {
|
||||
private constructor(components: readonly (ActionRowModalData | LabelModalData)[]);
|
||||
public components: (ActionRowModalData | LabelModalData)[];
|
||||
public fields: Collection<string, StringSelectModalData | TextInputModalData>;
|
||||
public getField<Type extends ComponentType>(
|
||||
export interface TextDisplayModalData extends BaseModalData<ComponentType.TextDisplay> {}
|
||||
|
||||
export interface ModalSelectedMentionables<Cached extends CacheType = CacheType> {
|
||||
members: NonNullable<SelectMenuModalData<Cached>['members']>;
|
||||
roles: NonNullable<SelectMenuModalData<Cached>['roles']>;
|
||||
users: NonNullable<SelectMenuModalData<Cached>['users']>;
|
||||
}
|
||||
export class ModalComponentResolver<Cached extends CacheType = CacheType> {
|
||||
private constructor(client: Client<true>, components: readonly ModalData[], resolved: BaseInteractionResolvedData);
|
||||
public readonly client: Client<true>;
|
||||
public readonly data: readonly (ActionRowModalData | LabelModalData | TextDisplayModalData)[];
|
||||
public readonly resolved: Readonly<BaseInteractionResolvedData<Cached>> | null;
|
||||
public readonly hoistedComponents: ReadonlyCollection<string, ModalData>;
|
||||
public getComponent(customId: string): ModalData;
|
||||
private _getTypedComponent(
|
||||
customId: string,
|
||||
type: Type,
|
||||
): { type: Type } & (StringSelectModalData | TextInputModalData);
|
||||
public getField(customId: string, type?: ComponentType): StringSelectModalData | TextInputModalData;
|
||||
allowedTypes: readonly ComponentType[],
|
||||
properties: string,
|
||||
required: boolean,
|
||||
): ModalData;
|
||||
public getTextInputValue(customId: string): string;
|
||||
public getStringSelectValues(customId: string): readonly string[];
|
||||
public getSelectedUsers(customId: string, required: true): ReadonlyCollection<Snowflake, User>;
|
||||
public getSelectedUsers(customId: string, required?: boolean): ReadonlyCollection<Snowflake, User> | null;
|
||||
public getSelectedMembers(customId: string): NonNullable<SelectMenuModalData<Cached>['members']> | null;
|
||||
public getSelectedChannels<const Type extends ChannelType = ChannelType>(
|
||||
customId: string,
|
||||
required: true,
|
||||
channelTypes?: readonly Type[],
|
||||
): ReadonlyCollection<
|
||||
Snowflake,
|
||||
Extract<
|
||||
NonNullable<CommandInteractionOption<Cached>['channel']>,
|
||||
{
|
||||
type: Type extends ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
? ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
: Type;
|
||||
}
|
||||
>
|
||||
>;
|
||||
public getSelectedChannels<const Type extends ChannelType = ChannelType>(
|
||||
customId: string,
|
||||
required?: boolean,
|
||||
channelTypes?: readonly Type[],
|
||||
): ReadonlyCollection<
|
||||
Snowflake,
|
||||
Extract<
|
||||
NonNullable<CommandInteractionOption<Cached>['channel']>,
|
||||
{
|
||||
type: Type extends ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
? ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
: Type;
|
||||
}
|
||||
>
|
||||
> | null;
|
||||
|
||||
public getSelectedRoles(customId: string, required: true): NonNullable<SelectMenuModalData<Cached>['roles']>;
|
||||
public getSelectedRoles(
|
||||
customId: string,
|
||||
required?: boolean,
|
||||
): NonNullable<SelectMenuModalData<Cached>['roles']> | null;
|
||||
|
||||
public getSelectedMentionables(customId: string, required: true): ModalSelectedMentionables<Cached>;
|
||||
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
|
||||
}
|
||||
|
||||
export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
|
||||
@@ -2604,8 +2675,7 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
private constructor(client: Client<true>, data: APIModalSubmitInteraction);
|
||||
public type: InteractionType.ModalSubmit;
|
||||
public readonly customId: string;
|
||||
public readonly components: (ActionRowModalData | LabelModalData)[];
|
||||
public readonly fields: ModalSubmitFields;
|
||||
public readonly components: ModalComponentResolver<Cached>;
|
||||
public deferred: boolean;
|
||||
public ephemeral: boolean | null;
|
||||
public message: Message<BooleanCache<Cached>> | null;
|
||||
@@ -4021,8 +4091,10 @@ export enum DiscordjsErrorCodes {
|
||||
CommandInteractionOptionNoSubcommandGroup = 'CommandInteractionOptionNoSubcommandGroup',
|
||||
AutocompleteInteractionOptionNoFocusedOption = 'AutocompleteInteractionOptionNoFocusedOption',
|
||||
|
||||
ModalSubmitInteractionFieldNotFound = 'ModalSubmitInteractionFieldNotFound',
|
||||
ModalSubmitInteractionFieldType = 'ModalSubmitInteractionFieldType',
|
||||
ModalSubmitInteractionComponentNotFound = 'ModalSubmitInteractionComponentNotFound',
|
||||
ModalSubmitInteractionComponentType = 'ModalSubmitInteractionComponentType',
|
||||
ModalSubmitInteractionComponentEmpty = 'ModalSubmitInteractionComponentEmpty',
|
||||
ModalSubmitInteractionComponentInvalidChannelType = 'ModalSubmitInteractionComponentInvalidChannelType',
|
||||
|
||||
InvalidMissingScopes = 'InvalidMissingScopes',
|
||||
InvalidScopesWithPermissions = 'InvalidScopesWithPermissions',
|
||||
@@ -4413,6 +4485,7 @@ export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, Us
|
||||
options?: BanOptions,
|
||||
): Promise<BulkBanResult>;
|
||||
public edit(user: UserResolvable, options: GuildMemberEditOptions): Promise<GuildMember>;
|
||||
public editMe(options: GuildMemberEditMeOptions): Promise<GuildMember>;
|
||||
public fetch(
|
||||
options: FetchMemberOptions | UserResolvable | (FetchMembersOptions & { user: UserResolvable }),
|
||||
): Promise<GuildMember>;
|
||||
@@ -5548,15 +5621,19 @@ export interface CommandInteractionOption<Cached extends CacheType = CacheType>
|
||||
value?: boolean | number | string;
|
||||
}
|
||||
|
||||
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType> {
|
||||
attachments?: ReadonlyCollection<Snowflake, Attachment>;
|
||||
export interface BaseInteractionResolvedData<Cached extends CacheType = CacheType> {
|
||||
channels?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
|
||||
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
|
||||
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
|
||||
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
}
|
||||
|
||||
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType>
|
||||
extends BaseInteractionResolvedData<Cached> {
|
||||
attachments?: ReadonlyCollection<Snowflake, Attachment>;
|
||||
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
|
||||
}
|
||||
|
||||
export interface AutocompleteFocusedOption {
|
||||
focused: true;
|
||||
name: string;
|
||||
@@ -6216,6 +6293,14 @@ export interface GuildMemberEditOptions {
|
||||
roles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
|
||||
}
|
||||
|
||||
export interface GuildMemberEditMeOptions {
|
||||
avatar?: Base64Resolvable | BufferResolvable | null;
|
||||
banner?: Base64Resolvable | BufferResolvable | null;
|
||||
bio?: string | null;
|
||||
nick?: string | null;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export type GuildResolvable =
|
||||
| Guild
|
||||
| GuildEmoji
|
||||
@@ -6691,11 +6776,11 @@ export interface BaseSelectMenuComponentData extends BaseComponentData {
|
||||
maxValues?: number;
|
||||
minValues?: number;
|
||||
placeholder?: string;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export interface StringSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
options: readonly SelectMenuComponentOptionData[];
|
||||
required?: boolean;
|
||||
type: ComponentType.StringSelect;
|
||||
}
|
||||
|
||||
|
||||
@@ -2609,6 +2609,31 @@ await chatInputInteraction.showModal({
|
||||
},
|
||||
label: 'yo',
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
component: {
|
||||
type: ComponentType.UserSelect,
|
||||
customId: 'user',
|
||||
},
|
||||
label: 'aa',
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
component: {
|
||||
type: ComponentType.RoleSelect,
|
||||
customId: 'role',
|
||||
},
|
||||
label: 'bb',
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
component: {
|
||||
type: ComponentType.ChannelSelect,
|
||||
customId: 'channel',
|
||||
channelTypes: [ChannelType.GuildText, ChannelType.GuildVoice],
|
||||
},
|
||||
label: 'cc',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@@ -45,7 +45,7 @@ importers:
|
||||
version: 0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)
|
||||
eslint-import-resolver-typescript:
|
||||
specifier: ^4.4.4
|
||||
version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-react-compiler:
|
||||
specifier: 19.1.0-rc.2
|
||||
version: 19.1.0-rc.2(eslint@9.33.0(jiti@2.5.1))
|
||||
@@ -589,7 +589,7 @@ importers:
|
||||
version: 9.33.0(jiti@2.5.1)
|
||||
eslint-config-neon:
|
||||
specifier: ^0.2.7
|
||||
version: 0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
version: 0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
eslint-formatter-compact:
|
||||
specifier: ^8.40.0
|
||||
version: 8.40.0
|
||||
@@ -897,9 +897,6 @@ importers:
|
||||
discord-api-types:
|
||||
specifier: ^0.38.23
|
||||
version: 0.38.23
|
||||
type-fest:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
devDependencies:
|
||||
'@discordjs/api-extractor':
|
||||
specifier: workspace:^
|
||||
@@ -1082,7 +1079,7 @@ importers:
|
||||
version: 6.0.1
|
||||
eslint-plugin-import:
|
||||
specifier: ^2.32.0
|
||||
version: 2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
version: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-jsdoc:
|
||||
specifier: ^54.1.1
|
||||
version: 54.1.1(eslint@9.33.0(jiti@2.5.1))
|
||||
@@ -1833,7 +1830,7 @@ importers:
|
||||
version: 9.33.0(jiti@2.5.1)
|
||||
eslint-config-neon:
|
||||
specifier: ^0.2.7
|
||||
version: 0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
version: 0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
eslint-formatter-compact:
|
||||
specifier: ^8.40.0
|
||||
version: 8.40.0
|
||||
@@ -10787,7 +10784,6 @@ packages:
|
||||
|
||||
path-match@1.2.4:
|
||||
resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==}
|
||||
deprecated: This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
@@ -12020,10 +12016,6 @@ packages:
|
||||
resolution: {integrity: sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
tagged-tag@1.0.0:
|
||||
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
tailwind-merge@3.3.1:
|
||||
resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
|
||||
|
||||
@@ -12367,10 +12359,6 @@ packages:
|
||||
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
type-fest@5.0.0:
|
||||
resolution: {integrity: sha512-GeJop7+u7BYlQ6yQCAY1nBQiRSHR+6OdCEtd8Bwp9a3NK3+fWAVjOaPKJDteB9f6cIJ0wt4IfnScjLG450EpXA==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -20873,7 +20861,7 @@ snapshots:
|
||||
eslint: 9.33.0(jiti@2.5.1)
|
||||
semver: 7.6.3
|
||||
|
||||
eslint-config-neon@0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4):
|
||||
eslint-config-neon@0.2.7(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4):
|
||||
dependencies:
|
||||
'@angular-eslint/eslint-plugin': 19.8.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
'@angular-eslint/eslint-plugin-template': 19.8.1(@angular-eslint/template-parser@19.8.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(@typescript-eslint/types@8.40.0)(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4))(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
@@ -20888,7 +20876,7 @@ snapshots:
|
||||
'@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.5.4)
|
||||
astro-eslint-parser: 1.2.2
|
||||
eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-mdx: 3.6.2(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-astro: 1.3.1(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-cypress: 4.3.0(eslint@9.33.0(jiti@2.5.1))
|
||||
@@ -20940,7 +20928,7 @@ snapshots:
|
||||
'@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)
|
||||
astro-eslint-parser: 1.2.2
|
||||
eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-mdx: 3.6.2(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-astro: 1.3.1(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-cypress: 4.3.0(eslint@9.33.0(jiti@2.5.1))
|
||||
@@ -21040,7 +21028,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)):
|
||||
eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)):
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
eslint: 9.33.0(jiti@2.5.1)
|
||||
@@ -21051,7 +21039,7 @@ snapshots:
|
||||
tinyglobby: 0.2.14
|
||||
unrs-resolver: 1.11.1
|
||||
optionalDependencies:
|
||||
eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -21076,13 +21064,13 @@ snapshots:
|
||||
- bluebird
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)):
|
||||
eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1)):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
eslint: 9.33.0(jiti@2.5.1)
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -21148,7 +21136,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1)):
|
||||
eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1)):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.9
|
||||
@@ -21159,7 +21147,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 9.33.0(jiti@2.5.1)
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.33.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))
|
||||
eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.33.0(jiti@2.5.1))
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
@@ -25749,8 +25737,6 @@ snapshots:
|
||||
typical: 2.6.1
|
||||
wordwrapjs: 3.0.0
|
||||
|
||||
tagged-tag@1.0.0: {}
|
||||
|
||||
tailwind-merge@3.3.1: {}
|
||||
|
||||
tailwindcss-react-aria-components@2.0.0(tailwindcss@4.1.12):
|
||||
@@ -26128,10 +26114,6 @@ snapshots:
|
||||
|
||||
type-fest@4.41.0: {}
|
||||
|
||||
type-fest@5.0.0:
|
||||
dependencies:
|
||||
tagged-tag: 1.0.0
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
Reference in New Issue
Block a user