baff.js 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/LICENSE +7 -0
- package/README.md +244 -3
- package/dist/cjs/builders/EmbedBuilder.d.ts +51 -0
- package/dist/cjs/builders/EmbedBuilder.js +150 -0
- package/dist/cjs/builders/SlashCommandBuilder.d.ts +69 -0
- package/dist/cjs/builders/SlashCommandBuilder.js +185 -0
- package/dist/cjs/builders/components/ActionRowBuilder.d.ts +14 -0
- package/dist/cjs/builders/components/ActionRowBuilder.js +45 -0
- package/dist/cjs/builders/components/ButtonBuilder.d.ts +19 -0
- package/dist/cjs/builders/components/ButtonBuilder.js +69 -0
- package/dist/cjs/builders/components/LayoutBuilders.d.ts +63 -0
- package/dist/cjs/builders/components/LayoutBuilders.js +179 -0
- package/dist/cjs/builders/components/ModalBuilder.d.ts +36 -0
- package/dist/cjs/builders/components/ModalBuilder.js +118 -0
- package/dist/cjs/builders/components/SelectMenuBuilder.d.ts +80 -0
- package/dist/cjs/builders/components/SelectMenuBuilder.js +192 -0
- package/dist/cjs/builders/components/shared.d.ts +16 -0
- package/dist/cjs/builders/components/shared.js +32 -0
- package/dist/cjs/builders/messagePayload.d.ts +35 -0
- package/dist/cjs/builders/messagePayload.js +88 -0
- package/dist/cjs/builders/validate.d.ts +12 -0
- package/dist/cjs/builders/validate.js +54 -0
- package/dist/cjs/client/Client.d.ts +63 -0
- package/dist/cjs/client/Client.js +152 -0
- package/dist/cjs/client/dispatch.d.ts +2 -0
- package/dist/cjs/client/dispatch.js +224 -0
- package/dist/cjs/client/events.d.ts +129 -0
- package/dist/cjs/client/events.js +2 -0
- package/dist/cjs/collectors/Collector.d.ts +37 -0
- package/dist/cjs/collectors/Collector.js +84 -0
- package/dist/cjs/collectors/InteractionCollector.d.ts +21 -0
- package/dist/cjs/collectors/InteractionCollector.js +44 -0
- package/dist/cjs/collectors/MessageCollector.d.ts +14 -0
- package/dist/cjs/collectors/MessageCollector.js +23 -0
- package/dist/cjs/errors/BaffError.d.ts +26 -0
- package/dist/cjs/errors/BaffError.js +39 -0
- package/dist/cjs/gateway/Gateway.d.ts +53 -0
- package/dist/cjs/gateway/Gateway.js +128 -0
- package/dist/cjs/http/handler.d.ts +11 -0
- package/dist/cjs/http/handler.js +72 -0
- package/dist/cjs/http/verify.d.ts +11 -0
- package/dist/cjs/http/verify.js +28 -0
- package/dist/cjs/index.d.ts +51 -0
- package/dist/cjs/index.js +185 -0
- package/dist/cjs/managers/CachedManager.d.ts +16 -0
- package/dist/cjs/managers/CachedManager.js +18 -0
- package/dist/cjs/managers/ChannelManager.d.ts +23 -0
- package/dist/cjs/managers/ChannelManager.js +85 -0
- package/dist/cjs/managers/CommandManager.d.ts +32 -0
- package/dist/cjs/managers/CommandManager.js +72 -0
- package/dist/cjs/managers/EventManager.d.ts +15 -0
- package/dist/cjs/managers/EventManager.js +36 -0
- package/dist/cjs/managers/ExpressionManagers.d.ts +36 -0
- package/dist/cjs/managers/ExpressionManagers.js +73 -0
- package/dist/cjs/managers/InviteManager.d.ts +17 -0
- package/dist/cjs/managers/InviteManager.js +26 -0
- package/dist/cjs/managers/MemberManager.d.ts +31 -0
- package/dist/cjs/managers/MemberManager.js +62 -0
- package/dist/cjs/managers/MessageManager.d.ts +32 -0
- package/dist/cjs/managers/MessageManager.js +79 -0
- package/dist/cjs/managers/RoleManager.d.ts +22 -0
- package/dist/cjs/managers/RoleManager.js +73 -0
- package/dist/cjs/managers/ServerChannelManager.d.ts +20 -0
- package/dist/cjs/managers/ServerChannelManager.js +30 -0
- package/dist/cjs/managers/ServerManager.d.ts +12 -0
- package/dist/cjs/managers/ServerManager.js +62 -0
- package/dist/cjs/managers/ThreadManager.d.ts +12 -0
- package/dist/cjs/managers/ThreadManager.js +20 -0
- package/dist/cjs/managers/UserManager.d.ts +11 -0
- package/dist/cjs/managers/UserManager.js +38 -0
- package/dist/cjs/managers/VoiceManager.d.ts +8 -0
- package/dist/cjs/managers/VoiceManager.js +17 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/rest/REST.d.ts +58 -0
- package/dist/cjs/rest/REST.js +193 -0
- package/dist/cjs/rest/Routes.d.ts +54 -0
- package/dist/cjs/rest/Routes.js +58 -0
- package/dist/cjs/rest/files.d.ts +19 -0
- package/dist/cjs/rest/files.js +37 -0
- package/dist/cjs/structures/Base.d.ts +13 -0
- package/dist/cjs/structures/Base.js +30 -0
- package/dist/cjs/structures/Message.d.ts +91 -0
- package/dist/cjs/structures/Message.js +200 -0
- package/dist/cjs/structures/Role.d.ts +34 -0
- package/dist/cjs/structures/Role.js +84 -0
- package/dist/cjs/structures/ScheduledEvent.d.ts +37 -0
- package/dist/cjs/structures/ScheduledEvent.js +73 -0
- package/dist/cjs/structures/Server.d.ts +68 -0
- package/dist/cjs/structures/Server.js +124 -0
- package/dist/cjs/structures/ServerAssets.d.ts +48 -0
- package/dist/cjs/structures/ServerAssets.js +104 -0
- package/dist/cjs/structures/ServerMember.d.ts +47 -0
- package/dist/cjs/structures/ServerMember.js +138 -0
- package/dist/cjs/structures/User.d.ts +35 -0
- package/dist/cjs/structures/User.js +87 -0
- package/dist/cjs/structures/Webhook.d.ts +30 -0
- package/dist/cjs/structures/Webhook.js +68 -0
- package/dist/cjs/structures/channels/BaseChannel.d.ts +49 -0
- package/dist/cjs/structures/channels/BaseChannel.js +81 -0
- package/dist/cjs/structures/channels/DMChannel.d.ts +9 -0
- package/dist/cjs/structures/channels/DMChannel.js +21 -0
- package/dist/cjs/structures/channels/ServerChannels.d.ts +57 -0
- package/dist/cjs/structures/channels/ServerChannels.js +138 -0
- package/dist/cjs/structures/channels/TextBasedChannel.d.ts +25 -0
- package/dist/cjs/structures/channels/TextBasedChannel.js +53 -0
- package/dist/cjs/structures/interactions/BaseInteraction.d.ts +74 -0
- package/dist/cjs/structures/interactions/BaseInteraction.js +221 -0
- package/dist/cjs/structures/interactions/CommandInteraction.d.ts +44 -0
- package/dist/cjs/structures/interactions/CommandInteraction.js +109 -0
- package/dist/cjs/structures/interactions/ComponentInteraction.d.ts +44 -0
- package/dist/cjs/structures/interactions/ComponentInteraction.js +64 -0
- package/dist/cjs/structures/interactions/ModalSubmitInteraction.d.ts +29 -0
- package/dist/cjs/structures/interactions/ModalSubmitInteraction.js +42 -0
- package/dist/cjs/structures/interactions/createInteraction.d.ts +4 -0
- package/dist/cjs/structures/interactions/createInteraction.js +34 -0
- package/dist/cjs/types.d.ts +369 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/util/Collection.d.ts +32 -0
- package/dist/cjs/util/Collection.js +145 -0
- package/dist/cjs/util/Permissions.d.ts +87 -0
- package/dist/cjs/util/Permissions.js +113 -0
- package/dist/cjs/util/Snowflake.d.ts +20 -0
- package/dist/cjs/util/Snowflake.js +40 -0
- package/dist/cjs/util/TypedEmitter.d.ts +17 -0
- package/dist/cjs/util/TypedEmitter.js +5 -0
- package/dist/cjs/util/constants.d.ts +78 -0
- package/dist/cjs/util/constants.js +81 -0
- package/dist/cjs/util/emoji.d.ts +8 -0
- package/dist/cjs/util/emoji.js +10 -0
- package/dist/cjs/util/formatters.d.ts +29 -0
- package/dist/cjs/util/formatters.js +55 -0
- package/dist/esm/builders/EmbedBuilder.d.ts +51 -0
- package/dist/esm/builders/EmbedBuilder.js +145 -0
- package/dist/esm/builders/SlashCommandBuilder.d.ts +69 -0
- package/dist/esm/builders/SlashCommandBuilder.js +170 -0
- package/dist/esm/builders/components/ActionRowBuilder.d.ts +14 -0
- package/dist/esm/builders/components/ActionRowBuilder.js +41 -0
- package/dist/esm/builders/components/ButtonBuilder.d.ts +19 -0
- package/dist/esm/builders/components/ButtonBuilder.js +65 -0
- package/dist/esm/builders/components/LayoutBuilders.d.ts +63 -0
- package/dist/esm/builders/components/LayoutBuilders.js +169 -0
- package/dist/esm/builders/components/ModalBuilder.d.ts +36 -0
- package/dist/esm/builders/components/ModalBuilder.js +113 -0
- package/dist/esm/builders/components/SelectMenuBuilder.d.ts +80 -0
- package/dist/esm/builders/components/SelectMenuBuilder.js +183 -0
- package/dist/esm/builders/components/shared.d.ts +16 -0
- package/dist/esm/builders/components/shared.js +26 -0
- package/dist/esm/builders/messagePayload.d.ts +35 -0
- package/dist/esm/builders/messagePayload.js +83 -0
- package/dist/esm/builders/validate.d.ts +12 -0
- package/dist/esm/builders/validate.js +46 -0
- package/dist/esm/client/Client.d.ts +63 -0
- package/dist/esm/client/Client.js +147 -0
- package/dist/esm/client/dispatch.d.ts +2 -0
- package/dist/esm/client/dispatch.js +221 -0
- package/dist/esm/client/events.d.ts +129 -0
- package/dist/esm/client/events.js +1 -0
- package/dist/esm/collectors/Collector.d.ts +37 -0
- package/dist/esm/collectors/Collector.js +78 -0
- package/dist/esm/collectors/InteractionCollector.d.ts +21 -0
- package/dist/esm/collectors/InteractionCollector.js +40 -0
- package/dist/esm/collectors/MessageCollector.d.ts +14 -0
- package/dist/esm/collectors/MessageCollector.js +19 -0
- package/dist/esm/errors/BaffError.d.ts +26 -0
- package/dist/esm/errors/BaffError.js +33 -0
- package/dist/esm/gateway/Gateway.d.ts +53 -0
- package/dist/esm/gateway/Gateway.js +124 -0
- package/dist/esm/http/handler.d.ts +11 -0
- package/dist/esm/http/handler.js +68 -0
- package/dist/esm/http/verify.d.ts +11 -0
- package/dist/esm/http/verify.js +22 -0
- package/dist/esm/index.d.ts +51 -0
- package/dist/esm/index.js +49 -0
- package/dist/esm/managers/CachedManager.d.ts +16 -0
- package/dist/esm/managers/CachedManager.js +14 -0
- package/dist/esm/managers/ChannelManager.d.ts +23 -0
- package/dist/esm/managers/ChannelManager.js +81 -0
- package/dist/esm/managers/CommandManager.d.ts +32 -0
- package/dist/esm/managers/CommandManager.js +67 -0
- package/dist/esm/managers/EventManager.d.ts +15 -0
- package/dist/esm/managers/EventManager.js +32 -0
- package/dist/esm/managers/ExpressionManagers.d.ts +36 -0
- package/dist/esm/managers/ExpressionManagers.js +68 -0
- package/dist/esm/managers/InviteManager.d.ts +17 -0
- package/dist/esm/managers/InviteManager.js +22 -0
- package/dist/esm/managers/MemberManager.d.ts +31 -0
- package/dist/esm/managers/MemberManager.js +58 -0
- package/dist/esm/managers/MessageManager.d.ts +32 -0
- package/dist/esm/managers/MessageManager.js +75 -0
- package/dist/esm/managers/RoleManager.d.ts +22 -0
- package/dist/esm/managers/RoleManager.js +69 -0
- package/dist/esm/managers/ServerChannelManager.d.ts +20 -0
- package/dist/esm/managers/ServerChannelManager.js +26 -0
- package/dist/esm/managers/ServerManager.d.ts +12 -0
- package/dist/esm/managers/ServerManager.js +58 -0
- package/dist/esm/managers/ThreadManager.d.ts +12 -0
- package/dist/esm/managers/ThreadManager.js +16 -0
- package/dist/esm/managers/UserManager.d.ts +11 -0
- package/dist/esm/managers/UserManager.js +34 -0
- package/dist/esm/managers/VoiceManager.d.ts +8 -0
- package/dist/esm/managers/VoiceManager.js +13 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/rest/REST.d.ts +58 -0
- package/dist/esm/rest/REST.js +188 -0
- package/dist/esm/rest/Routes.d.ts +54 -0
- package/dist/esm/rest/Routes.js +55 -0
- package/dist/esm/rest/files.d.ts +19 -0
- package/dist/esm/rest/files.js +31 -0
- package/dist/esm/structures/Base.d.ts +13 -0
- package/dist/esm/structures/Base.js +25 -0
- package/dist/esm/structures/Message.d.ts +91 -0
- package/dist/esm/structures/Message.js +194 -0
- package/dist/esm/structures/Role.d.ts +34 -0
- package/dist/esm/structures/Role.js +79 -0
- package/dist/esm/structures/ScheduledEvent.d.ts +37 -0
- package/dist/esm/structures/ScheduledEvent.js +68 -0
- package/dist/esm/structures/Server.d.ts +68 -0
- package/dist/esm/structures/Server.js +120 -0
- package/dist/esm/structures/ServerAssets.d.ts +48 -0
- package/dist/esm/structures/ServerAssets.js +98 -0
- package/dist/esm/structures/ServerMember.d.ts +47 -0
- package/dist/esm/structures/ServerMember.js +133 -0
- package/dist/esm/structures/User.d.ts +35 -0
- package/dist/esm/structures/User.js +82 -0
- package/dist/esm/structures/Webhook.d.ts +30 -0
- package/dist/esm/structures/Webhook.js +63 -0
- package/dist/esm/structures/channels/BaseChannel.d.ts +49 -0
- package/dist/esm/structures/channels/BaseChannel.js +77 -0
- package/dist/esm/structures/channels/DMChannel.d.ts +9 -0
- package/dist/esm/structures/channels/DMChannel.js +17 -0
- package/dist/esm/structures/channels/ServerChannels.d.ts +57 -0
- package/dist/esm/structures/channels/ServerChannels.js +129 -0
- package/dist/esm/structures/channels/TextBasedChannel.d.ts +25 -0
- package/dist/esm/structures/channels/TextBasedChannel.js +49 -0
- package/dist/esm/structures/interactions/BaseInteraction.d.ts +74 -0
- package/dist/esm/structures/interactions/BaseInteraction.js +217 -0
- package/dist/esm/structures/interactions/CommandInteraction.d.ts +44 -0
- package/dist/esm/structures/interactions/CommandInteraction.js +104 -0
- package/dist/esm/structures/interactions/ComponentInteraction.d.ts +44 -0
- package/dist/esm/structures/interactions/ComponentInteraction.js +53 -0
- package/dist/esm/structures/interactions/ModalSubmitInteraction.d.ts +29 -0
- package/dist/esm/structures/interactions/ModalSubmitInteraction.js +37 -0
- package/dist/esm/structures/interactions/createInteraction.d.ts +4 -0
- package/dist/esm/structures/interactions/createInteraction.js +31 -0
- package/dist/esm/types.d.ts +369 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/util/Collection.d.ts +32 -0
- package/dist/esm/util/Collection.js +141 -0
- package/dist/esm/util/Permissions.d.ts +87 -0
- package/dist/esm/util/Permissions.js +109 -0
- package/dist/esm/util/Snowflake.d.ts +20 -0
- package/dist/esm/util/Snowflake.js +37 -0
- package/dist/esm/util/TypedEmitter.d.ts +17 -0
- package/dist/esm/util/TypedEmitter.js +2 -0
- package/dist/esm/util/constants.d.ts +78 -0
- package/dist/esm/util/constants.js +78 -0
- package/dist/esm/util/emoji.d.ts +8 -0
- package/dist/esm/util/emoji.js +7 -0
- package/dist/esm/util/formatters.d.ts +29 -0
- package/dist/esm/util/formatters.js +34 -0
- package/package.json +58 -6
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hideLinkEmbed = exports.hyperlink = exports.subtext = exports.heading = exports.blockQuote = exports.quote = exports.codeBlock = exports.inlineCode = exports.spoiler = exports.strikethrough = exports.underline = exports.italic = exports.bold = exports.formatEmoji = exports.hereMention = exports.everyoneMention = exports.channelMention = exports.roleMention = exports.userMention = void 0;
|
|
4
|
+
exports.escapeMarkdown = escapeMarkdown;
|
|
5
|
+
const userMention = (id) => `<@${id}>`;
|
|
6
|
+
exports.userMention = userMention;
|
|
7
|
+
const roleMention = (id) => `<@&${id}>`;
|
|
8
|
+
exports.roleMention = roleMention;
|
|
9
|
+
const channelMention = (id) => `<#${id}>`;
|
|
10
|
+
exports.channelMention = channelMention;
|
|
11
|
+
exports.everyoneMention = '@everyone';
|
|
12
|
+
exports.hereMention = '@here';
|
|
13
|
+
const formatEmoji = (id, name, animated = false) => `<${animated ? 'a' : ''}:${name}:${id}>`;
|
|
14
|
+
exports.formatEmoji = formatEmoji;
|
|
15
|
+
const bold = (text) => `**${text}**`;
|
|
16
|
+
exports.bold = bold;
|
|
17
|
+
const italic = (text) => `*${text}*`;
|
|
18
|
+
exports.italic = italic;
|
|
19
|
+
const underline = (text) => `__${text}__`;
|
|
20
|
+
exports.underline = underline;
|
|
21
|
+
const strikethrough = (text) => `~~${text}~~`;
|
|
22
|
+
exports.strikethrough = strikethrough;
|
|
23
|
+
const spoiler = (text) => `||${text}||`;
|
|
24
|
+
exports.spoiler = spoiler;
|
|
25
|
+
const inlineCode = (text) => `\`${text}\``;
|
|
26
|
+
exports.inlineCode = inlineCode;
|
|
27
|
+
const codeBlock = (content, language = '') => `\`\`\`${language}\n${content}\n\`\`\``;
|
|
28
|
+
exports.codeBlock = codeBlock;
|
|
29
|
+
const quote = (text) => `> ${text}`;
|
|
30
|
+
exports.quote = quote;
|
|
31
|
+
const blockQuote = (text) => `>>> ${text}`;
|
|
32
|
+
exports.blockQuote = blockQuote;
|
|
33
|
+
const heading = (text, level = 1) => `${'#'.repeat(level)} ${text}`;
|
|
34
|
+
exports.heading = heading;
|
|
35
|
+
const subtext = (text) => `-# ${text}`;
|
|
36
|
+
exports.subtext = subtext;
|
|
37
|
+
const hyperlink = (text, url) => `[${text}](${url})`;
|
|
38
|
+
exports.hyperlink = hyperlink;
|
|
39
|
+
const hideLinkEmbed = (url) => `<${url}>`;
|
|
40
|
+
exports.hideLinkEmbed = hideLinkEmbed;
|
|
41
|
+
function escapeMarkdown(text, options = {}) {
|
|
42
|
+
const on = (key) => options[key] !== false;
|
|
43
|
+
let chars = '\\';
|
|
44
|
+
if (on('italic') || on('bold'))
|
|
45
|
+
chars += '*';
|
|
46
|
+
if (on('italic') || on('underline'))
|
|
47
|
+
chars += '_';
|
|
48
|
+
if (on('strikethrough'))
|
|
49
|
+
chars += '~';
|
|
50
|
+
if (on('inlineCode') || on('codeBlock'))
|
|
51
|
+
chars += '`';
|
|
52
|
+
if (on('spoiler'))
|
|
53
|
+
chars += '|';
|
|
54
|
+
return text.replace(new RegExp(`[${chars.replace(/[\]\\^-]/g, '\\$&')}]`, 'g'), '\\$&');
|
|
55
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { APIEmbed } from '../types.js';
|
|
2
|
+
export declare const EmbedLimits: {
|
|
3
|
+
readonly embeds: 10;
|
|
4
|
+
readonly fields: 25;
|
|
5
|
+
readonly title: 256;
|
|
6
|
+
readonly description: 4096;
|
|
7
|
+
readonly fieldName: 256;
|
|
8
|
+
readonly fieldValue: 1024;
|
|
9
|
+
readonly footer: 2048;
|
|
10
|
+
readonly author: 256;
|
|
11
|
+
readonly total: 6000;
|
|
12
|
+
};
|
|
13
|
+
export type ColorResolvable = number | `#${string}` | readonly [number, number, number];
|
|
14
|
+
export declare function resolveColor(color: ColorResolvable): number;
|
|
15
|
+
export declare class EmbedBuilder {
|
|
16
|
+
readonly data: APIEmbed;
|
|
17
|
+
constructor(data?: APIEmbed);
|
|
18
|
+
setTitle(title: string | null): this;
|
|
19
|
+
setDescription(description: string | null): this;
|
|
20
|
+
setURL(value: string | null): this;
|
|
21
|
+
setColor(color: ColorResolvable | null): this;
|
|
22
|
+
setTimestamp(timestamp?: Date | number | string | null): this;
|
|
23
|
+
setAuthor(author: {
|
|
24
|
+
name: string;
|
|
25
|
+
url?: string;
|
|
26
|
+
iconURL?: string;
|
|
27
|
+
} | null): this;
|
|
28
|
+
setFooter(footer: {
|
|
29
|
+
text: string;
|
|
30
|
+
iconURL?: string;
|
|
31
|
+
} | null): this;
|
|
32
|
+
setThumbnail(imageURL: string | null): this;
|
|
33
|
+
setImage(imageURL: string | null): this;
|
|
34
|
+
addFields(...fields: {
|
|
35
|
+
name: string;
|
|
36
|
+
value: string;
|
|
37
|
+
inline?: boolean;
|
|
38
|
+
}[]): this;
|
|
39
|
+
setFields(...fields: {
|
|
40
|
+
name: string;
|
|
41
|
+
value: string;
|
|
42
|
+
inline?: boolean;
|
|
43
|
+
}[]): this;
|
|
44
|
+
spliceFields(index: number, deleteCount: number, ...fields: {
|
|
45
|
+
name: string;
|
|
46
|
+
value: string;
|
|
47
|
+
inline?: boolean;
|
|
48
|
+
}[]): this;
|
|
49
|
+
get length(): number;
|
|
50
|
+
toJSON(): APIEmbed;
|
|
51
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { BaffError } from '../errors/BaffError.js';
|
|
2
|
+
import { fail, range, text, url } from './validate.js';
|
|
3
|
+
export const EmbedLimits = {
|
|
4
|
+
embeds: 10,
|
|
5
|
+
fields: 25,
|
|
6
|
+
title: 256,
|
|
7
|
+
description: 4096,
|
|
8
|
+
fieldName: 256,
|
|
9
|
+
fieldValue: 1024,
|
|
10
|
+
footer: 2048,
|
|
11
|
+
author: 256,
|
|
12
|
+
total: 6000
|
|
13
|
+
};
|
|
14
|
+
export function resolveColor(color) {
|
|
15
|
+
if (typeof color === 'number')
|
|
16
|
+
return range('INVALID_EMBED', 'color', color, 0, 0xffffff);
|
|
17
|
+
if (typeof color === 'string') {
|
|
18
|
+
if (!/^#[0-9a-f]{6}$/i.test(color))
|
|
19
|
+
return fail('INVALID_EMBED', 'color', 'must be #rrggbb.');
|
|
20
|
+
return parseInt(color.slice(1), 16);
|
|
21
|
+
}
|
|
22
|
+
const [r, g, b] = color;
|
|
23
|
+
return (range('INVALID_EMBED', 'color', r, 0, 255) << 16) | (range('INVALID_EMBED', 'color', g, 0, 255) << 8) | range('INVALID_EMBED', 'color', b, 0, 255);
|
|
24
|
+
}
|
|
25
|
+
export class EmbedBuilder {
|
|
26
|
+
data;
|
|
27
|
+
constructor(data = {}) {
|
|
28
|
+
this.data = { ...data, fields: data.fields ? data.fields.map((f) => ({ ...f })) : undefined };
|
|
29
|
+
}
|
|
30
|
+
setTitle(title) {
|
|
31
|
+
this.data.title = title ?? undefined;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
setDescription(description) {
|
|
35
|
+
this.data.description = description ?? undefined;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
setURL(value) {
|
|
39
|
+
this.data.url = value ?? undefined;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
setColor(color) {
|
|
43
|
+
this.data.color = color === null ? undefined : resolveColor(color);
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
setTimestamp(timestamp = new Date()) {
|
|
47
|
+
if (timestamp === null)
|
|
48
|
+
this.data.timestamp = undefined;
|
|
49
|
+
else {
|
|
50
|
+
const date = new Date(timestamp);
|
|
51
|
+
if (Number.isNaN(date.getTime()))
|
|
52
|
+
throw new BaffError('INVALID_EMBED', 'timestamp is not a valid date.');
|
|
53
|
+
this.data.timestamp = date.toISOString();
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
setAuthor(author) {
|
|
58
|
+
this.data.author = author ? { name: author.name, url: author.url, icon_url: author.iconURL } : undefined;
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
setFooter(footer) {
|
|
62
|
+
this.data.footer = footer ? { text: footer.text, icon_url: footer.iconURL } : undefined;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
setThumbnail(imageURL) {
|
|
66
|
+
this.data.thumbnail = imageURL ? { url: imageURL } : undefined;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
setImage(imageURL) {
|
|
70
|
+
this.data.image = imageURL ? { url: imageURL } : undefined;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
addFields(...fields) {
|
|
74
|
+
this.data.fields = [...(this.data.fields ?? []), ...fields];
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
setFields(...fields) {
|
|
78
|
+
this.data.fields = [...fields];
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
spliceFields(index, deleteCount, ...fields) {
|
|
82
|
+
const next = [...(this.data.fields ?? [])];
|
|
83
|
+
next.splice(index, deleteCount, ...fields);
|
|
84
|
+
this.data.fields = next;
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
get length() {
|
|
88
|
+
const d = this.data;
|
|
89
|
+
const size = (s) => [...(s ?? '')].length;
|
|
90
|
+
return size(d.title) + size(d.description) + size(d.footer?.text) + size(d.author?.name) + (d.fields ?? []).reduce((sum, f) => sum + size(f.name) + size(f.value), 0);
|
|
91
|
+
}
|
|
92
|
+
toJSON() {
|
|
93
|
+
const d = this.data;
|
|
94
|
+
const code = 'INVALID_EMBED';
|
|
95
|
+
const out = {};
|
|
96
|
+
const title = text(code, 'title', d.title, EmbedLimits.title, { optional: true });
|
|
97
|
+
const description = text(code, 'description', d.description, EmbedLimits.description, { optional: true });
|
|
98
|
+
if (title !== undefined)
|
|
99
|
+
out.title = title;
|
|
100
|
+
if (description !== undefined)
|
|
101
|
+
out.description = description;
|
|
102
|
+
const link = url(code, 'url', d.url);
|
|
103
|
+
if (link)
|
|
104
|
+
out.url = link;
|
|
105
|
+
if (d.color !== undefined)
|
|
106
|
+
out.color = range(code, 'color', d.color, 0, 0xffffff);
|
|
107
|
+
if (d.timestamp)
|
|
108
|
+
out.timestamp = d.timestamp;
|
|
109
|
+
if (d.footer) {
|
|
110
|
+
out.footer = { text: text(code, 'footer.text', d.footer.text, EmbedLimits.footer) };
|
|
111
|
+
const icon = url(code, 'footer.iconURL', d.footer.icon_url);
|
|
112
|
+
if (icon)
|
|
113
|
+
out.footer.icon_url = icon;
|
|
114
|
+
}
|
|
115
|
+
if (d.author) {
|
|
116
|
+
out.author = { name: text(code, 'author.name', d.author.name, EmbedLimits.author) };
|
|
117
|
+
const authorUrl = url(code, 'author.url', d.author.url);
|
|
118
|
+
const icon = url(code, 'author.iconURL', d.author.icon_url);
|
|
119
|
+
if (authorUrl)
|
|
120
|
+
out.author.url = authorUrl;
|
|
121
|
+
if (icon)
|
|
122
|
+
out.author.icon_url = icon;
|
|
123
|
+
}
|
|
124
|
+
for (const key of ['image', 'thumbnail']) {
|
|
125
|
+
const media = d[key];
|
|
126
|
+
if (media)
|
|
127
|
+
out[key] = { url: url(code, key, media.url, false) };
|
|
128
|
+
}
|
|
129
|
+
if (d.fields?.length) {
|
|
130
|
+
if (d.fields.length > EmbedLimits.fields)
|
|
131
|
+
fail(code, 'fields', `can have up to ${EmbedLimits.fields} entries.`);
|
|
132
|
+
out.fields = d.fields.map((f, i) => ({
|
|
133
|
+
name: text(code, `fields[${i}].name`, f.name, EmbedLimits.fieldName),
|
|
134
|
+
value: text(code, `fields[${i}].value`, f.value, EmbedLimits.fieldValue),
|
|
135
|
+
inline: f.inline ?? false
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
if (!Object.keys(out).filter((k) => k !== 'color' && k !== 'timestamp' && k !== 'url').length) {
|
|
139
|
+
fail(code, 'embed', 'is empty: give it a title, description, fields, image, thumbnail, author or footer.');
|
|
140
|
+
}
|
|
141
|
+
if (this.length > EmbedLimits.total)
|
|
142
|
+
fail(code, 'embed', `has ${this.length} characters; the limit is ${EmbedLimits.total} across all of a message's embeds.`);
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { APICommand, APICommandOption } from '../types.js';
|
|
2
|
+
declare abstract class Named {
|
|
3
|
+
protected name?: string;
|
|
4
|
+
protected description?: string;
|
|
5
|
+
setName(name: string): this;
|
|
6
|
+
setDescription(description: string): this;
|
|
7
|
+
protected header(path: string): {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare abstract class OptionBuilder extends Named {
|
|
13
|
+
protected required: boolean;
|
|
14
|
+
abstract readonly type: string;
|
|
15
|
+
setRequired(required?: boolean): this;
|
|
16
|
+
toJSON(path?: string): APICommandOption;
|
|
17
|
+
}
|
|
18
|
+
export declare class StringOption extends OptionBuilder {
|
|
19
|
+
readonly type = "string";
|
|
20
|
+
}
|
|
21
|
+
export declare class IntegerOption extends OptionBuilder {
|
|
22
|
+
readonly type = "integer";
|
|
23
|
+
}
|
|
24
|
+
export declare class NumberOption extends OptionBuilder {
|
|
25
|
+
readonly type = "number";
|
|
26
|
+
}
|
|
27
|
+
export declare class BooleanOption extends OptionBuilder {
|
|
28
|
+
readonly type = "boolean";
|
|
29
|
+
}
|
|
30
|
+
export declare class UserOption extends OptionBuilder {
|
|
31
|
+
readonly type = "user";
|
|
32
|
+
}
|
|
33
|
+
export declare class ChannelOption extends OptionBuilder {
|
|
34
|
+
readonly type = "channel";
|
|
35
|
+
}
|
|
36
|
+
export declare class RoleOption extends OptionBuilder {
|
|
37
|
+
readonly type = "role";
|
|
38
|
+
}
|
|
39
|
+
type OptionInput<T> = T | ((option: T) => T);
|
|
40
|
+
declare class OptionHolder extends Named {
|
|
41
|
+
protected plain: OptionBuilder[];
|
|
42
|
+
addStringOption(option: OptionInput<StringOption>): this;
|
|
43
|
+
addIntegerOption(option: OptionInput<IntegerOption>): this;
|
|
44
|
+
addNumberOption(option: OptionInput<NumberOption>): this;
|
|
45
|
+
addBooleanOption(option: OptionInput<BooleanOption>): this;
|
|
46
|
+
addUserOption(option: OptionInput<UserOption>): this;
|
|
47
|
+
addChannelOption(option: OptionInput<ChannelOption>): this;
|
|
48
|
+
addRoleOption(option: OptionInput<RoleOption>): this;
|
|
49
|
+
}
|
|
50
|
+
export declare class SubcommandBuilder extends OptionHolder {
|
|
51
|
+
toJSON(path?: string): APICommandOption;
|
|
52
|
+
}
|
|
53
|
+
export declare class SubcommandGroupBuilder extends Named {
|
|
54
|
+
private subcommands;
|
|
55
|
+
addSubcommand(sub: OptionInput<SubcommandBuilder>): this;
|
|
56
|
+
toJSON(path?: string): APICommandOption;
|
|
57
|
+
}
|
|
58
|
+
export declare class SlashCommandBuilder extends OptionHolder {
|
|
59
|
+
private nested;
|
|
60
|
+
addSubcommand(sub: OptionInput<SubcommandBuilder>): this;
|
|
61
|
+
addSubcommandGroup(group: OptionInput<SubcommandGroupBuilder>): this;
|
|
62
|
+
toJSON(): APICommand;
|
|
63
|
+
}
|
|
64
|
+
export declare class PrefixCommandBuilder extends Named {
|
|
65
|
+
private prefix?;
|
|
66
|
+
setPrefix(prefix: string): this;
|
|
67
|
+
toJSON(): APICommand;
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { fail, text } from './validate.js';
|
|
2
|
+
const code = 'INVALID_COMMAND';
|
|
3
|
+
const NAME = /^[a-z0-9_-]{1,32}$/;
|
|
4
|
+
const MAX_OPTIONS = 25;
|
|
5
|
+
function checkName(path, name) {
|
|
6
|
+
if (typeof name !== 'string' || !NAME.test(name))
|
|
7
|
+
return fail(code, `${path}.name`, 'must be 1-32 lowercase letters, numbers, - or _.');
|
|
8
|
+
return name;
|
|
9
|
+
}
|
|
10
|
+
class Named {
|
|
11
|
+
name;
|
|
12
|
+
description;
|
|
13
|
+
setName(name) {
|
|
14
|
+
this.name = name;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
setDescription(description) {
|
|
18
|
+
this.description = description;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
header(path) {
|
|
22
|
+
return { name: checkName(path, this.name), description: text(code, `${path}.description`, this.description, 100) };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class OptionBuilder extends Named {
|
|
26
|
+
required = false;
|
|
27
|
+
setRequired(required = true) {
|
|
28
|
+
this.required = required;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
toJSON(path = 'option') {
|
|
32
|
+
return { ...this.header(path), type: this.type, required: this.required };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class StringOption extends OptionBuilder {
|
|
36
|
+
type = 'string';
|
|
37
|
+
}
|
|
38
|
+
export class IntegerOption extends OptionBuilder {
|
|
39
|
+
type = 'integer';
|
|
40
|
+
}
|
|
41
|
+
export class NumberOption extends OptionBuilder {
|
|
42
|
+
type = 'number';
|
|
43
|
+
}
|
|
44
|
+
export class BooleanOption extends OptionBuilder {
|
|
45
|
+
type = 'boolean';
|
|
46
|
+
}
|
|
47
|
+
export class UserOption extends OptionBuilder {
|
|
48
|
+
type = 'user';
|
|
49
|
+
}
|
|
50
|
+
export class ChannelOption extends OptionBuilder {
|
|
51
|
+
type = 'channel';
|
|
52
|
+
}
|
|
53
|
+
export class RoleOption extends OptionBuilder {
|
|
54
|
+
type = 'role';
|
|
55
|
+
}
|
|
56
|
+
function build(input, make) {
|
|
57
|
+
return typeof input === 'function' ? input(make()) : input;
|
|
58
|
+
}
|
|
59
|
+
function checkPlain(path, options) {
|
|
60
|
+
if (options.length > MAX_OPTIONS)
|
|
61
|
+
fail(code, path, `can have up to ${MAX_OPTIONS} options.`);
|
|
62
|
+
const names = new Set();
|
|
63
|
+
let optionalSeen = false;
|
|
64
|
+
return options.map((option, i) => {
|
|
65
|
+
const json = option.toJSON(`${path}.options[${i}]`);
|
|
66
|
+
if (names.has(json.name))
|
|
67
|
+
fail(code, `${path}.options[${i}]`, `name "${json.name}" is used twice.`);
|
|
68
|
+
names.add(json.name);
|
|
69
|
+
if (json.required && optionalSeen)
|
|
70
|
+
fail(code, `${path}.options[${i}]`, `is required, so it must come before the optional options.`);
|
|
71
|
+
optionalSeen ||= !json.required;
|
|
72
|
+
return json;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
class OptionHolder extends Named {
|
|
76
|
+
plain = [];
|
|
77
|
+
addStringOption(option) {
|
|
78
|
+
this.plain.push(build(option, () => new StringOption()));
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
addIntegerOption(option) {
|
|
82
|
+
this.plain.push(build(option, () => new IntegerOption()));
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
addNumberOption(option) {
|
|
86
|
+
this.plain.push(build(option, () => new NumberOption()));
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
addBooleanOption(option) {
|
|
90
|
+
this.plain.push(build(option, () => new BooleanOption()));
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
addUserOption(option) {
|
|
94
|
+
this.plain.push(build(option, () => new UserOption()));
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
addChannelOption(option) {
|
|
98
|
+
this.plain.push(build(option, () => new ChannelOption()));
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
addRoleOption(option) {
|
|
102
|
+
this.plain.push(build(option, () => new RoleOption()));
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export class SubcommandBuilder extends OptionHolder {
|
|
107
|
+
toJSON(path = 'subcommand') {
|
|
108
|
+
const options = checkPlain(path, this.plain);
|
|
109
|
+
return { ...this.header(path), type: 'subcommand', options };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export class SubcommandGroupBuilder extends Named {
|
|
113
|
+
subcommands = [];
|
|
114
|
+
addSubcommand(sub) {
|
|
115
|
+
this.subcommands.push(build(sub, () => new SubcommandBuilder()));
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
toJSON(path = 'group') {
|
|
119
|
+
if (!this.subcommands.length)
|
|
120
|
+
fail(code, path, 'needs at least one subcommand.');
|
|
121
|
+
return { ...this.header(path), type: 'subcommand_group', options: checkNested(path, this.subcommands) };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function checkNested(path, list) {
|
|
125
|
+
if (list.length > MAX_OPTIONS)
|
|
126
|
+
fail(code, path, `can have up to ${MAX_OPTIONS} options.`);
|
|
127
|
+
const names = new Set();
|
|
128
|
+
return list.map((item, i) => {
|
|
129
|
+
const json = item.toJSON(`${path}.options[${i}]`);
|
|
130
|
+
if (names.has(json.name))
|
|
131
|
+
fail(code, `${path}.options[${i}]`, `name "${json.name}" is used twice.`);
|
|
132
|
+
names.add(json.name);
|
|
133
|
+
return json;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export class SlashCommandBuilder extends OptionHolder {
|
|
137
|
+
nested = [];
|
|
138
|
+
addSubcommand(sub) {
|
|
139
|
+
this.nested.push(build(sub, () => new SubcommandBuilder()));
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
addSubcommandGroup(group) {
|
|
143
|
+
this.nested.push(build(group, () => new SubcommandGroupBuilder()));
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
toJSON() {
|
|
147
|
+
const path = `command "${this.name ?? ''}"`;
|
|
148
|
+
const header = this.header('command');
|
|
149
|
+
if (this.nested.length && this.plain.length)
|
|
150
|
+
fail(code, path, 'has both subcommands and plain options: use one or the other.');
|
|
151
|
+
const options = this.nested.length ? checkNested(path, this.nested) : checkPlain(path, this.plain);
|
|
152
|
+
return { ...header, kind: 'slash', options };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export class PrefixCommandBuilder extends Named {
|
|
156
|
+
prefix;
|
|
157
|
+
setPrefix(prefix) {
|
|
158
|
+
this.prefix = prefix;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
toJSON() {
|
|
162
|
+
const prefix = this.prefix;
|
|
163
|
+
if (!prefix || [...prefix].length > 5 || /\s/.test(prefix))
|
|
164
|
+
fail(code, 'command.prefix', 'must be 1-5 characters with no spaces.');
|
|
165
|
+
if (!this.name || [...this.name].length > 32 || /\s/.test(this.name))
|
|
166
|
+
fail(code, 'command.name', 'must be 1-32 characters with no spaces.');
|
|
167
|
+
const description = text(code, 'command.description', this.description, 100, { optional: true }) ?? '';
|
|
168
|
+
return { kind: 'prefix', prefix, name: this.name, description };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { APIComponent } from '../../types.js';
|
|
2
|
+
import { type Serializable } from '../validate.js';
|
|
3
|
+
import { ComponentBuilder } from './shared.js';
|
|
4
|
+
export declare class ActionRowBuilder<T extends Serializable = Serializable> extends ComponentBuilder {
|
|
5
|
+
components: (T | APIComponent)[];
|
|
6
|
+
constructor(data?: {
|
|
7
|
+
components?: (T | APIComponent)[];
|
|
8
|
+
});
|
|
9
|
+
addComponents(...components: (T | APIComponent)[]): this;
|
|
10
|
+
setComponents(...components: (T | APIComponent)[]): this;
|
|
11
|
+
toJSON(): APIComponent;
|
|
12
|
+
toModalJSON(): APIComponent;
|
|
13
|
+
private render;
|
|
14
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ComponentType } from '../../util/constants.js';
|
|
2
|
+
import { fail, resolveJSON } from '../validate.js';
|
|
3
|
+
import { ComponentBuilder } from './shared.js';
|
|
4
|
+
export class ActionRowBuilder extends ComponentBuilder {
|
|
5
|
+
components;
|
|
6
|
+
constructor(data = {}) {
|
|
7
|
+
super();
|
|
8
|
+
this.components = [...(data.components ?? [])];
|
|
9
|
+
}
|
|
10
|
+
addComponents(...components) {
|
|
11
|
+
this.components.push(...components);
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
setComponents(...components) {
|
|
15
|
+
this.components = [...components];
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
toJSON() {
|
|
19
|
+
return this.render(false);
|
|
20
|
+
}
|
|
21
|
+
toModalJSON() {
|
|
22
|
+
return this.render(true);
|
|
23
|
+
}
|
|
24
|
+
render(modal) {
|
|
25
|
+
const children = this.components.map((c) => resolveJSON(c));
|
|
26
|
+
const kinds = children.map((c) => c.type);
|
|
27
|
+
const code = 'INVALID_COMPONENT';
|
|
28
|
+
if (modal) {
|
|
29
|
+
if (kinds.length !== 1 || kinds[0] !== ComponentType.TextInput)
|
|
30
|
+
fail(code, 'modal row', 'needs exactly one text input.');
|
|
31
|
+
}
|
|
32
|
+
else if (kinds[0] === ComponentType.Button) {
|
|
33
|
+
if (kinds.length > 5 || kinds.some((k) => k !== ComponentType.Button))
|
|
34
|
+
fail(code, 'action row', 'can hold up to 5 buttons, all buttons.');
|
|
35
|
+
}
|
|
36
|
+
else if (kinds.length !== 1 || kinds[0] === ComponentType.TextInput || kinds[0] === undefined) {
|
|
37
|
+
fail(code, 'action row', 'needs 1-5 buttons, or exactly one select menu.');
|
|
38
|
+
}
|
|
39
|
+
return { ...this.base(ComponentType.ActionRow), components: children };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { APIComponent } from '../../types.js';
|
|
2
|
+
import { ComponentBuilder, type EmojiInput } from './shared.js';
|
|
3
|
+
type StyleName = 'primary' | 'secondary' | 'success' | 'danger' | 'link';
|
|
4
|
+
export declare class ButtonBuilder extends ComponentBuilder {
|
|
5
|
+
private customId?;
|
|
6
|
+
private label?;
|
|
7
|
+
private style?;
|
|
8
|
+
private emoji?;
|
|
9
|
+
private link?;
|
|
10
|
+
private disabled;
|
|
11
|
+
setCustomId(customId: string): this;
|
|
12
|
+
setLabel(label: string): this;
|
|
13
|
+
setStyle(style: number | StyleName): this;
|
|
14
|
+
setEmoji(emoji: EmojiInput): this;
|
|
15
|
+
setURL(link: string): this;
|
|
16
|
+
setDisabled(disabled?: boolean): this;
|
|
17
|
+
toJSON(): APIComponent;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ButtonStyle, ComponentType } from '../../util/constants.js';
|
|
2
|
+
import { fail, text, url } from '../validate.js';
|
|
3
|
+
import { ComponentBuilder, emojiJSON } from './shared.js';
|
|
4
|
+
const STYLE_NUMBERS = { primary: 1, secondary: 2, success: 3, danger: 4, link: 5 };
|
|
5
|
+
export class ButtonBuilder extends ComponentBuilder {
|
|
6
|
+
customId;
|
|
7
|
+
label;
|
|
8
|
+
style;
|
|
9
|
+
emoji;
|
|
10
|
+
link;
|
|
11
|
+
disabled = false;
|
|
12
|
+
setCustomId(customId) {
|
|
13
|
+
this.customId = customId;
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
setLabel(label) {
|
|
17
|
+
this.label = label;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
setStyle(style) {
|
|
21
|
+
const value = typeof style === 'string' ? STYLE_NUMBERS[style] : style;
|
|
22
|
+
if (!Number.isInteger(value) || value < 1 || value > 5)
|
|
23
|
+
fail('INVALID_COMPONENT', 'button.style', 'must be 1 (primary), 2 (secondary), 3 (success), 4 (danger) or 5 (link).');
|
|
24
|
+
this.style = value;
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
setEmoji(emoji) {
|
|
28
|
+
this.emoji = emoji;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
setURL(link) {
|
|
32
|
+
this.link = link;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
setDisabled(disabled = true) {
|
|
36
|
+
this.disabled = disabled;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
toJSON() {
|
|
40
|
+
const code = 'INVALID_COMPONENT';
|
|
41
|
+
const style = this.style ?? (this.link ? ButtonStyle.Link : ButtonStyle.Primary);
|
|
42
|
+
const out = this.base(ComponentType.Button);
|
|
43
|
+
out.style = style;
|
|
44
|
+
const label = text(code, 'button.label', this.label, 80, { optional: true });
|
|
45
|
+
const emoji = emojiJSON('button.emoji', this.emoji);
|
|
46
|
+
if (label !== undefined)
|
|
47
|
+
out.label = label;
|
|
48
|
+
if (emoji)
|
|
49
|
+
out.emoji = emoji;
|
|
50
|
+
if (label === undefined && !emoji)
|
|
51
|
+
fail(code, 'button', 'needs a label (1-80 characters) or an emoji.');
|
|
52
|
+
if (style === ButtonStyle.Link) {
|
|
53
|
+
if (this.customId !== undefined)
|
|
54
|
+
fail(code, 'button', 'is a link button: it has a url and no custom id.');
|
|
55
|
+
out.url = url(code, 'button.url', this.link, false);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
if (this.link !== undefined)
|
|
59
|
+
fail(code, 'button', 'has a url, so its style must be Link.');
|
|
60
|
+
out.custom_id = text(code, 'button.customId', this.customId, 100);
|
|
61
|
+
}
|
|
62
|
+
out.disabled = this.disabled;
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
}
|