chapterjs 0.1.2 → 0.1.4
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/dist/assets/asset.d.ts +46 -0
- package/dist/assets/asset.js +86 -0
- package/dist/assets/public.d.ts +19 -0
- package/dist/assets/public.js +120 -0
- package/dist/cache/cache.d.ts +62 -0
- package/dist/cache/cache.js +80 -0
- package/dist/cache/store.d.ts +45 -0
- package/dist/cache/store.js +53 -0
- package/dist/cli/build.d.ts +41 -0
- package/dist/cli/build.js +206 -0
- package/dist/cli/cli.js +108 -25
- package/dist/cli/cluster.d.ts +70 -0
- package/dist/cli/cluster.js +213 -0
- package/dist/cli/dev.d.ts +18 -1
- package/dist/cli/dev.js +252 -198
- package/dist/cli/env.d.ts +31 -0
- package/dist/cli/env.js +93 -0
- package/dist/cli/log.d.ts +13 -0
- package/dist/cli/log.js +17 -0
- package/dist/cli/node-version.d.ts +8 -0
- package/dist/cli/node-version.js +13 -0
- package/dist/cli/preflight.d.ts +36 -0
- package/dist/cli/preflight.js +122 -0
- package/dist/cli/project.d.ts +122 -0
- package/dist/cli/project.js +452 -0
- package/dist/cli/start.d.ts +25 -0
- package/dist/cli/start.js +225 -0
- package/dist/commands/autocomplete.d.ts +13 -0
- package/dist/commands/autocomplete.js +159 -0
- package/dist/commands/command.d.ts +346 -0
- package/dist/commands/command.js +28 -0
- package/dist/commands/convention.d.ts +64 -0
- package/dist/commands/convention.js +464 -0
- package/dist/commands/register.d.ts +18 -0
- package/dist/commands/register.js +42 -0
- package/dist/commands/router.d.ts +20 -0
- package/dist/commands/router.js +228 -0
- package/dist/commands/tree.d.ts +43 -0
- package/dist/commands/tree.js +206 -0
- package/dist/commands/twins.d.ts +15 -0
- package/dist/commands/twins.js +78 -0
- package/dist/components/button.d.ts +79 -0
- package/dist/components/button.js +108 -0
- package/dist/components/component.d.ts +140 -0
- package/dist/components/component.js +39 -0
- package/dist/components/convention.d.ts +35 -0
- package/dist/components/convention.js +339 -0
- package/dist/components/custom-id.d.ts +72 -0
- package/dist/components/custom-id.js +128 -0
- package/dist/components/embed.d.ts +28 -0
- package/dist/components/embed.js +11 -0
- package/dist/components/file.d.ts +30 -0
- package/dist/components/file.js +52 -0
- package/dist/components/instance.d.ts +100 -0
- package/dist/components/instance.js +86 -0
- package/dist/components/layout.d.ts +103 -0
- package/dist/components/layout.js +279 -0
- package/dist/components/modal.d.ts +244 -0
- package/dist/components/modal.js +399 -0
- package/dist/components/options.d.ts +41 -0
- package/dist/components/options.js +101 -0
- package/dist/components/render.d.ts +12 -0
- package/dist/components/render.js +58 -0
- package/dist/components/router.d.ts +18 -0
- package/dist/components/router.js +256 -0
- package/dist/components/select.d.ts +144 -0
- package/dist/components/select.js +179 -0
- package/dist/core/bot.d.ts +99 -0
- package/dist/core/bot.js +174 -0
- package/dist/core/memory.d.ts +66 -0
- package/dist/core/memory.js +115 -0
- package/dist/discord/api.d.ts +112 -0
- package/dist/discord/api.js +115 -0
- package/dist/discord/cdn.d.ts +67 -0
- package/dist/discord/cdn.js +100 -0
- package/dist/discord/codes.d.ts +171 -0
- package/dist/discord/codes.js +421 -0
- package/dist/discord/endpoint.d.ts +56 -0
- package/dist/discord/endpoint.js +53 -0
- package/dist/discord/endpoints.d.ts +1529 -0
- package/dist/discord/endpoints.js +1139 -0
- package/dist/discord/formatting.d.ts +67 -0
- package/dist/discord/formatting.js +87 -0
- package/dist/discord/index.d.ts +10 -0
- package/dist/discord/index.js +13 -0
- package/dist/discord/intents.d.ts +48 -0
- package/dist/discord/intents.js +128 -0
- package/dist/discord/permissions.d.ts +94 -0
- package/dist/discord/permissions.js +185 -0
- package/dist/discord/snowflake.d.ts +21 -0
- package/dist/discord/snowflake.js +36 -0
- package/dist/discord/types/application-command.d.ts +332 -0
- package/dist/discord/types/application-command.js +48 -0
- package/dist/discord/types/application-role-connection-metadata.d.ts +42 -0
- package/dist/discord/types/application-role-connection-metadata.js +22 -0
- package/dist/discord/types/application.d.ts +208 -0
- package/dist/discord/types/application.js +48 -0
- package/dist/discord/types/audit-log.d.ts +255 -0
- package/dist/discord/types/audit-log.js +144 -0
- package/dist/discord/types/auto-moderation.d.ts +167 -0
- package/dist/discord/types/auto-moderation.js +52 -0
- package/dist/discord/types/channel.d.ts +557 -0
- package/dist/discord/types/channel.js +88 -0
- package/dist/discord/types/common.d.ts +54 -0
- package/dist/discord/types/common.js +38 -0
- package/dist/discord/types/component.d.ts +775 -0
- package/dist/discord/types/component.js +76 -0
- package/dist/discord/types/emoji.d.ts +74 -0
- package/dist/discord/types/emoji.js +1 -0
- package/dist/discord/types/entitlement.d.ts +84 -0
- package/dist/discord/types/entitlement.js +22 -0
- package/dist/discord/types/gateway-events.d.ts +1148 -0
- package/dist/discord/types/gateway-events.js +54 -0
- package/dist/discord/types/gateway.d.ts +38 -0
- package/dist/discord/types/gateway.js +1 -0
- package/dist/discord/types/guild-scheduled-event.d.ts +257 -0
- package/dist/discord/types/guild-scheduled-event.js +68 -0
- package/dist/discord/types/guild-template.d.ts +51 -0
- package/dist/discord/types/guild-template.js +1 -0
- package/dist/discord/types/guild.d.ts +910 -0
- package/dist/discord/types/guild.js +153 -0
- package/dist/discord/types/index.d.ts +31 -0
- package/dist/discord/types/index.js +31 -0
- package/dist/discord/types/interaction.d.ts +321 -0
- package/dist/discord/types/interaction.js +47 -0
- package/dist/discord/types/invite.d.ts +158 -0
- package/dist/discord/types/invite.js +39 -0
- package/dist/discord/types/message.d.ts +834 -0
- package/dist/discord/types/message.js +159 -0
- package/dist/discord/types/oauth2.d.ts +22 -0
- package/dist/discord/types/oauth2.js +1 -0
- package/dist/discord/types/permissions.d.ts +183 -0
- package/dist/discord/types/permissions.js +118 -0
- package/dist/discord/types/poll.d.ts +106 -0
- package/dist/discord/types/poll.js +8 -0
- package/dist/discord/types/sku.d.ts +47 -0
- package/dist/discord/types/sku.js +26 -0
- package/dist/discord/types/soundboard.d.ts +71 -0
- package/dist/discord/types/soundboard.js +1 -0
- package/dist/discord/types/stage-instance.d.ts +58 -0
- package/dist/discord/types/stage-instance.js +10 -0
- package/dist/discord/types/sticker.d.ts +115 -0
- package/dist/discord/types/sticker.js +20 -0
- package/dist/discord/types/subscription.d.ts +54 -0
- package/dist/discord/types/subscription.js +12 -0
- package/dist/discord/types/team.d.ts +55 -0
- package/dist/discord/types/team.js +21 -0
- package/dist/discord/types/user.d.ts +273 -0
- package/dist/discord/types/user.js +83 -0
- package/dist/discord/types/voice.d.ts +72 -0
- package/dist/discord/types/voice.js +1 -0
- package/dist/discord/types/webhook.d.ts +184 -0
- package/dist/discord/types/webhook.js +12 -0
- package/dist/events/convention.d.ts +25 -0
- package/dist/events/convention.js +97 -0
- package/dist/events/event.d.ts +8 -0
- package/dist/events/event.js +20 -0
- package/dist/events/registry.d.ts +706 -0
- package/dist/events/registry.js +839 -0
- package/dist/events/router.d.ts +45 -0
- package/dist/events/router.js +133 -0
- package/dist/events/types.d.ts +7 -0
- package/dist/events/types.js +48 -0
- package/dist/gateway/errors.d.ts +18 -0
- package/dist/gateway/errors.js +47 -0
- package/dist/gateway/gateway.d.ts +64 -0
- package/dist/gateway/gateway.js +117 -0
- package/dist/gateway/identify-queue.d.ts +25 -0
- package/dist/gateway/identify-queue.js +29 -0
- package/dist/gateway/shard.d.ts +94 -0
- package/dist/gateway/shard.js +414 -0
- package/dist/gateway/state.d.ts +11 -0
- package/dist/gateway/state.js +184 -0
- package/dist/index.d.ts +55 -18
- package/dist/index.js +38 -12
- package/dist/interactions/cooldown.d.ts +33 -0
- package/dist/interactions/cooldown.js +74 -0
- package/dist/interactions/dispatch.d.ts +91 -0
- package/dist/interactions/dispatch.js +110 -0
- package/dist/loader/generated.d.ts +37 -0
- package/dist/loader/generated.js +114 -0
- package/dist/loader/hot.d.ts +13 -0
- package/dist/loader/hot.js +85 -0
- package/dist/loader/loader.d.ts +72 -0
- package/dist/loader/loader.js +135 -0
- package/dist/loader/locate.d.ts +10 -0
- package/dist/loader/locate.js +36 -0
- package/dist/loader/watch.d.ts +17 -0
- package/dist/loader/watch.js +66 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +6 -0
- package/dist/messages/commands.d.ts +23 -0
- package/dist/messages/commands.js +123 -0
- package/dist/messages/convention.d.ts +89 -0
- package/dist/messages/convention.js +347 -0
- package/dist/messages/messages.d.ts +219 -0
- package/dist/messages/messages.js +30 -0
- package/dist/messages/phrases.d.ts +23 -0
- package/dist/messages/phrases.js +44 -0
- package/dist/messages/translate.d.ts +100 -0
- package/dist/messages/translate.js +249 -0
- package/dist/presence/convention.d.ts +26 -0
- package/dist/presence/convention.js +133 -0
- package/dist/presence/presence.d.ts +57 -0
- package/dist/presence/presence.js +27 -0
- package/dist/rest/errors.d.ts +55 -0
- package/dist/rest/errors.js +92 -0
- package/dist/rest/rate-limiter.d.ts +46 -0
- package/dist/rest/rate-limiter.js +153 -0
- package/dist/rest/rest.d.ts +63 -0
- package/dist/rest/rest.js +194 -0
- package/dist/structures/base.d.ts +48 -0
- package/dist/structures/base.js +84 -0
- package/dist/structures/channel.d.ts +380 -0
- package/dist/structures/channel.js +627 -0
- package/dist/structures/context.d.ts +30 -0
- package/dist/structures/context.js +7 -0
- package/dist/structures/emoji.d.ts +46 -0
- package/dist/structures/emoji.js +65 -0
- package/dist/structures/entities.d.ts +62 -0
- package/dist/structures/entities.js +226 -0
- package/dist/structures/guild.d.ts +348 -0
- package/dist/structures/guild.js +466 -0
- package/dist/structures/interaction.d.ts +197 -0
- package/dist/structures/interaction.js +396 -0
- package/dist/structures/invite.d.ts +38 -0
- package/dist/structures/invite.js +57 -0
- package/dist/structures/known.d.ts +28 -0
- package/dist/structures/known.js +58 -0
- package/dist/structures/member.d.ts +140 -0
- package/dist/structures/member.js +260 -0
- package/dist/structures/message.d.ts +197 -0
- package/dist/structures/message.js +268 -0
- package/dist/structures/payload.d.ts +91 -0
- package/dist/structures/payload.js +184 -0
- package/dist/structures/role.d.ts +69 -0
- package/dist/structures/role.js +112 -0
- package/dist/structures/user.d.ts +59 -0
- package/dist/structures/user.js +94 -0
- package/dist/structures/webhook.d.ts +46 -0
- package/dist/structures/webhook.js +79 -0
- package/dist/tasks/convention.d.ts +26 -0
- package/dist/tasks/convention.js +78 -0
- package/dist/tasks/schedule.d.ts +54 -0
- package/dist/tasks/schedule.js +236 -0
- package/dist/tasks/scheduler.d.ts +33 -0
- package/dist/tasks/scheduler.js +107 -0
- package/dist/tasks/task.d.ts +76 -0
- package/dist/tasks/task.js +28 -0
- package/dist/util/case.d.ts +13 -0
- package/dist/util/case.js +54 -0
- package/dist/util/duration.d.ts +8 -0
- package/dist/util/duration.js +29 -0
- package/dist/util/websocket.d.ts +9 -0
- package/dist/util/websocket.js +31 -0
- package/dist/voice/connection.d.ts +90 -0
- package/dist/voice/connection.js +494 -0
- package/dist/voice/dave.d.ts +109 -0
- package/dist/voice/dave.js +245 -0
- package/dist/voice/opus.d.ts +19 -0
- package/dist/voice/opus.js +273 -0
- package/dist/voice/session.d.ts +55 -0
- package/dist/voice/session.js +405 -0
- package/dist/voice/source.d.ts +22 -0
- package/dist/voice/source.js +195 -0
- package/dist/voice/transport.d.ts +43 -0
- package/dist/voice/transport.js +140 -0
- package/dist/voice/usage.d.ts +4 -0
- package/dist/voice/usage.js +33 -0
- package/package.json +26 -7
- package/vendor/dave/LICENSE +231 -0
- package/vendor/dave/libdave.d.mts +99 -0
- package/vendor/dave/libdave.mjs +2 -0
- package/vendor/dave/libdave.wasm +0 -0
- package/dist/components.d.ts +0 -97
- package/dist/components.js +0 -260
- package/dist/context.d.ts +0 -72
- package/dist/context.js +0 -273
- package/dist/discord/client.d.ts +0 -35
- package/dist/discord/client.js +0 -66
- package/dist/discord/constants.d.ts +0 -49
- package/dist/discord/constants.js +0 -61
- package/dist/discord/events.d.ts +0 -129
- package/dist/discord/events.js +0 -102
- package/dist/discord/gateway.d.ts +0 -61
- package/dist/discord/gateway.js +0 -320
- package/dist/discord/payloads.d.ts +0 -275
- package/dist/discord/payloads.js +0 -3
- package/dist/discord/presence.d.ts +0 -42
- package/dist/discord/presence.js +0 -51
- package/dist/discord/rest.d.ts +0 -49
- package/dist/discord/rest.js +0 -271
- package/dist/discord/types.d.ts +0 -334
- package/dist/discord/types.js +0 -4
- package/dist/events.d.ts +0 -94
- package/dist/events.js +0 -255
- package/dist/presence.d.ts +0 -92
- package/dist/presence.js +0 -250
- package/dist/structures/Channel.d.ts +0 -110
- package/dist/structures/Channel.js +0 -171
- package/dist/structures/Guild.d.ts +0 -70
- package/dist/structures/Guild.js +0 -105
- package/dist/structures/Interaction.d.ts +0 -113
- package/dist/structures/Interaction.js +0 -274
- package/dist/structures/Member.d.ts +0 -70
- package/dist/structures/Member.js +0 -124
- package/dist/structures/Message.d.ts +0 -87
- package/dist/structures/Message.js +0 -182
- package/dist/structures/Reaction.d.ts +0 -38
- package/dist/structures/Reaction.js +0 -64
- package/dist/structures/Role.d.ts +0 -43
- package/dist/structures/Role.js +0 -77
- package/dist/structures/User.d.ts +0 -41
- package/dist/structures/User.js +0 -79
- package/dist/structures/utils.d.ts +0 -72
- package/dist/structures/utils.js +0 -59
- package/dist/utils/errors.d.ts +0 -5
- package/dist/utils/errors.js +0 -28
- package/dist/utils/modules.d.ts +0 -39
- package/dist/utils/modules.js +0 -156
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** The kinds of values a component can carry in its `data`. */
|
|
2
|
+
export type DataKind = 'string' | 'number' | 'boolean';
|
|
3
|
+
/**
|
|
4
|
+
* One value a component carries: its kind, or its kind with a default
|
|
5
|
+
* value, which makes it optional where the component is put in a message.
|
|
6
|
+
*/
|
|
7
|
+
export type DataField = DataKind | {
|
|
8
|
+
type: 'string';
|
|
9
|
+
default?: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'number';
|
|
12
|
+
default?: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'boolean';
|
|
15
|
+
default?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** What a component carries: a name for each value, and its kind. */
|
|
18
|
+
export type DataShape = Readonly<Record<string, DataField>>;
|
|
19
|
+
/** The kind of a field, however it was written. */
|
|
20
|
+
type KindOf<Field extends DataField> = Field extends DataKind ? Field : Field extends {
|
|
21
|
+
type: infer Kind;
|
|
22
|
+
} ? Kind : never;
|
|
23
|
+
type ValueOf<Field extends DataField> = KindOf<Field> extends 'string' ? string : KindOf<Field> extends 'number' ? number : boolean;
|
|
24
|
+
/** The names of the fields that have a default value. */
|
|
25
|
+
type WithDefault<Shape extends DataShape> = {
|
|
26
|
+
[Name in keyof Shape]: Shape[Name] extends {
|
|
27
|
+
default: {};
|
|
28
|
+
} ? Name : never;
|
|
29
|
+
}[keyof Shape];
|
|
30
|
+
/**
|
|
31
|
+
* The values of a `data` declaration, typed from it: what `run` and the
|
|
32
|
+
* texts of the component receive. A value with a default is always there.
|
|
33
|
+
*/
|
|
34
|
+
export type DataValuesOf<Shape extends DataShape> = {
|
|
35
|
+
[Name in keyof Shape]: ValueOf<Shape[Name]>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* What a message gives to a component: the values of its `data`, those
|
|
39
|
+
* with a default value being optional.
|
|
40
|
+
*/
|
|
41
|
+
export type DataInputOf<Shape extends DataShape> = {
|
|
42
|
+
[Name in Exclude<keyof Shape, WithDefault<Shape>>]: ValueOf<Shape[Name]>;
|
|
43
|
+
} & {
|
|
44
|
+
[Name in WithDefault<Shape>]?: ValueOf<Shape[Name]>;
|
|
45
|
+
};
|
|
46
|
+
export declare const DATA_KINDS: readonly DataKind[];
|
|
47
|
+
/** The kind of a field, however it was written. */
|
|
48
|
+
export declare const kindOf: (field: DataField) => DataKind;
|
|
49
|
+
/** The default value of a field, if it has one. */
|
|
50
|
+
export declare const defaultOf: (field: DataField) => string | number | boolean | undefined;
|
|
51
|
+
/** Whether a component can be put in a message without data. */
|
|
52
|
+
export declare const needsNoData: (shape: DataShape) => boolean;
|
|
53
|
+
/** Checks the values a file gives to a component against its `data`. */
|
|
54
|
+
export declare function checkData(what: string, shape: DataShape, values: unknown): Record<string, string | number | boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* The `custom_id` of a component: its path, then its values in the order
|
|
57
|
+
* of the declaration. Discord accepts 100 characters: when the data does
|
|
58
|
+
* not fit, the error says by how much.
|
|
59
|
+
*/
|
|
60
|
+
export declare function encodeCustomId(path: string, shape: DataShape, values: Record<string, string | number | boolean>): string;
|
|
61
|
+
/** The path and the encoded values of a `custom_id` the framework wrote. */
|
|
62
|
+
export declare function decodeCustomId(id: string): {
|
|
63
|
+
path: string;
|
|
64
|
+
parts: string[];
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The values a `custom_id` carries, typed as the component declares them.
|
|
68
|
+
* `null` when they do not match the declaration: the file changed since the
|
|
69
|
+
* message was sent.
|
|
70
|
+
*/
|
|
71
|
+
export declare function readData(shape: DataShape, parts: readonly string[]): Record<string, string | number | boolean> | null;
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// The `custom_id` of a component is never written by users: it is the path
|
|
2
|
+
// of the file of the component (`buttons/ban`), followed by the data the
|
|
3
|
+
// component carries, encoded by the framework. Stateless by design: it
|
|
4
|
+
// survives a restart, and every process of the bot reads it the same way.
|
|
5
|
+
// https://docs.discord.com/developers/components/reference#anatomy-of-a-component-custom-id
|
|
6
|
+
import { Limits } from '../discord/api.js';
|
|
7
|
+
export const DATA_KINDS = ['string', 'number', 'boolean'];
|
|
8
|
+
/** The kind of a field, however it was written. */
|
|
9
|
+
export const kindOf = (field) => typeof field === 'string' ? field : field.type;
|
|
10
|
+
/** The default value of a field, if it has one. */
|
|
11
|
+
export const defaultOf = (field) => typeof field === 'string' ? undefined : field.default;
|
|
12
|
+
/** Whether a component can be put in a message without data. */
|
|
13
|
+
export const needsNoData = (shape) => Object.values(shape).every(field => defaultOf(field) !== undefined);
|
|
14
|
+
/** Fields are separated by `:`; a `:` or a `\` inside a value is escaped. */
|
|
15
|
+
const SEPARATOR = ':';
|
|
16
|
+
const escape = (value) => value.replace(/[\\:]/g, char => `\\${char}`);
|
|
17
|
+
/**
|
|
18
|
+
* Splits on the separators that are not escaped, and unescapes the rest.
|
|
19
|
+
* Written by hand: a regular expression would need lookbehinds that count.
|
|
20
|
+
*/
|
|
21
|
+
function split(encoded) {
|
|
22
|
+
const parts = [];
|
|
23
|
+
let current = '';
|
|
24
|
+
for (let index = 0; index < encoded.length; index++) {
|
|
25
|
+
const char = encoded[index];
|
|
26
|
+
if (char === '\\' && index + 1 < encoded.length) {
|
|
27
|
+
current += encoded[++index];
|
|
28
|
+
}
|
|
29
|
+
else if (char === SEPARATOR) {
|
|
30
|
+
parts.push(current);
|
|
31
|
+
current = '';
|
|
32
|
+
}
|
|
33
|
+
else
|
|
34
|
+
current += char;
|
|
35
|
+
}
|
|
36
|
+
parts.push(current);
|
|
37
|
+
return parts;
|
|
38
|
+
}
|
|
39
|
+
/** Checks the values a file gives to a component against its `data`. */
|
|
40
|
+
export function checkData(what, shape, values) {
|
|
41
|
+
const names = Object.keys(shape);
|
|
42
|
+
if (names.length === 0) {
|
|
43
|
+
if (values !== undefined) {
|
|
44
|
+
throw new TypeError(`${what} carries no data: it is used as is, without arguments.`);
|
|
45
|
+
}
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
const example = `${what}({ ${names
|
|
49
|
+
.filter(name => defaultOf(shape[name]) === undefined)
|
|
50
|
+
.map(name => `${name}: ${kindOf(shape[name]) === 'string' ? "'...'" : kindOf(shape[name]) === 'number' ? '1' : 'true'}`)
|
|
51
|
+
.join(', ')} })`;
|
|
52
|
+
// Every value has a default: the component is used as is, or with some.
|
|
53
|
+
if (values === undefined && needsNoData(shape))
|
|
54
|
+
values = {};
|
|
55
|
+
if (typeof values !== 'object' || values === null || Array.isArray(values)) {
|
|
56
|
+
throw new TypeError(`${what} needs its data: write ${example}.`);
|
|
57
|
+
}
|
|
58
|
+
const given = values;
|
|
59
|
+
for (const key of Object.keys(given)) {
|
|
60
|
+
if (!Object.hasOwn(shape, key)) {
|
|
61
|
+
throw new TypeError(`"${key}" is not in the data of ${what}. Its data is: ${names.join(', ')}.`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const result = {};
|
|
65
|
+
for (const name of names) {
|
|
66
|
+
const fallback = defaultOf(shape[name]);
|
|
67
|
+
const value = given[name] === undefined ? fallback : given[name];
|
|
68
|
+
const kind = kindOf(shape[name]);
|
|
69
|
+
const got = JSON.stringify(value) ?? typeof value;
|
|
70
|
+
if (typeof value !== kind ||
|
|
71
|
+
(kind === 'number' && !Number.isFinite(value))) {
|
|
72
|
+
throw new TypeError(`The data "${name}" of ${what} is a ${kind}, got ${got}.`);
|
|
73
|
+
}
|
|
74
|
+
result[name] = value;
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The `custom_id` of a component: its path, then its values in the order
|
|
80
|
+
* of the declaration. Discord accepts 100 characters: when the data does
|
|
81
|
+
* not fit, the error says by how much.
|
|
82
|
+
*/
|
|
83
|
+
export function encodeCustomId(path, shape, values) {
|
|
84
|
+
const parts = [path];
|
|
85
|
+
for (const name of Object.keys(shape))
|
|
86
|
+
parts.push(escape(String(values[name])));
|
|
87
|
+
const id = parts.join(SEPARATOR);
|
|
88
|
+
if (id.length > Limits.CustomId) {
|
|
89
|
+
throw new RangeError(`The data of ${path} is ${id.length - path.length - 1} characters long once encoded, and Discord leaves ${Limits.CustomId - path.length - 1} for it (its id is ${path}, ${path.length} characters, out of ${Limits.CustomId}). Carry less: an id instead of a name, or a shorter file name.`);
|
|
90
|
+
}
|
|
91
|
+
return id;
|
|
92
|
+
}
|
|
93
|
+
/** The path and the encoded values of a `custom_id` the framework wrote. */
|
|
94
|
+
export function decodeCustomId(id) {
|
|
95
|
+
const [path = '', ...parts] = split(id);
|
|
96
|
+
return { path, parts };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The values a `custom_id` carries, typed as the component declares them.
|
|
100
|
+
* `null` when they do not match the declaration: the file changed since the
|
|
101
|
+
* message was sent.
|
|
102
|
+
*/
|
|
103
|
+
export function readData(shape, parts) {
|
|
104
|
+
const names = Object.keys(shape);
|
|
105
|
+
if (parts.length !== names.length)
|
|
106
|
+
return null;
|
|
107
|
+
const values = {};
|
|
108
|
+
for (const [index, name] of names.entries()) {
|
|
109
|
+
const part = parts[index];
|
|
110
|
+
switch (kindOf(shape[name])) {
|
|
111
|
+
case 'number': {
|
|
112
|
+
const number = Number(part);
|
|
113
|
+
if (part.trim() === '' || !Number.isFinite(number))
|
|
114
|
+
return null;
|
|
115
|
+
values[name] = number;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case 'boolean':
|
|
119
|
+
if (part !== 'true' && part !== 'false')
|
|
120
|
+
return null;
|
|
121
|
+
values[name] = part === 'true';
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
values[name] = part;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return values;
|
|
128
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Embed } from '../structures/payload.js';
|
|
2
|
+
/**
|
|
3
|
+
* What `embed()` returns: the default export of an embed file. Import it
|
|
4
|
+
* where you send a message: `embeds: [welcome({ member })]`, or
|
|
5
|
+
* `embeds: [rules]` for an embed that always looks the same.
|
|
6
|
+
*/
|
|
7
|
+
export type EmbedFile<Args extends readonly unknown[] = []> = {
|
|
8
|
+
/** What the file gave to `embed()`, not checked yet. */
|
|
9
|
+
readonly config: unknown;
|
|
10
|
+
} & ((...args: Args) => Embed);
|
|
11
|
+
/**
|
|
12
|
+
* Declares an embed. Export the result as the default export of a file of
|
|
13
|
+
* `src/components/embeds/`. Give it the embed itself when it always looks
|
|
14
|
+
* the same, or a function of what it shows:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { embed, type GuildMember } from 'chapterjs';
|
|
18
|
+
*
|
|
19
|
+
* export default embed((member: GuildMember) => ({
|
|
20
|
+
* title: `Welcome ${member.displayName}!`,
|
|
21
|
+
* color: 0x57f287,
|
|
22
|
+
* }));
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function embed(definition: Embed): EmbedFile<[]>;
|
|
26
|
+
export declare function embed<const Args extends readonly unknown[]>(definition: (...args: Args) => Embed): EmbedFile<Args>;
|
|
27
|
+
/** Whether a value is an embed file: a function to call for the embed. */
|
|
28
|
+
export declare const isEmbedFile: (value: unknown) => value is EmbedFile<readonly unknown[]>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// `embed()`, as the files of `src/components/embeds/` import it from
|
|
2
|
+
// 'chapterjs': an embed written once, used in every message that needs it.
|
|
3
|
+
// Static, or a function of what it shows.
|
|
4
|
+
import { createFile, fileStateOf } from './file.js';
|
|
5
|
+
export function embed(definition) {
|
|
6
|
+
return createFile('embed', definition, {
|
|
7
|
+
asPiece: false,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
/** Whether a value is an embed file: a function to call for the embed. */
|
|
11
|
+
export const isEmbedFile = (value) => fileStateOf(value)?.kind === 'embed';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type PieceKind, type Rendered } from './instance.js';
|
|
2
|
+
/** The kinds of files of `src/components/`, which are its folders. */
|
|
3
|
+
export type ComponentKind = 'button' | 'select' | 'modal' | 'embed';
|
|
4
|
+
export declare const COMPONENT_FOLDERS: Record<string, ComponentKind>;
|
|
5
|
+
/** A file as the loader knows it: what it declared, and once loaded, how to make instances. */
|
|
6
|
+
export interface ComponentFileState {
|
|
7
|
+
readonly kind: ComponentKind;
|
|
8
|
+
readonly config: unknown;
|
|
9
|
+
/** The name of the file for messages, before it is bound: `button()`. */
|
|
10
|
+
readonly made: string;
|
|
11
|
+
bound?: {
|
|
12
|
+
/** The path of the file inside `src/components/`, without extension. */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Makes an instance from what the file was called with. */
|
|
15
|
+
render: (args: readonly unknown[]) => Rendered | object;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** The state of a component file, if the value is one. */
|
|
19
|
+
export declare function fileStateOf(value: unknown): ComponentFileState | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Makes a component file. `asPiece` says whether the file itself stands
|
|
22
|
+
* for its instance when it carries no data (a button, a menu, a modal: not
|
|
23
|
+
* an embed, which is only a function).
|
|
24
|
+
*/
|
|
25
|
+
export declare function createFile(kind: ComponentKind, config: unknown, { asPiece, pieceKind }: {
|
|
26
|
+
asPiece: boolean;
|
|
27
|
+
pieceKind?: PieceKind;
|
|
28
|
+
}): (...args: unknown[]) => unknown;
|
|
29
|
+
/** Binds a file to its path and to what makes its instances. */
|
|
30
|
+
export declare function bindFile(file: unknown, bound: NonNullable<ComponentFileState['bound']>): void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// What `button()`, `select()`, `modal()` and `embed()` return: the default
|
|
2
|
+
// export of a file of `src/components/`. It is a function (called with the
|
|
3
|
+
// data the component carries) that the loader recognises, checks, and binds
|
|
4
|
+
// to the path of its file: that path is the custom_id. Until then it can't
|
|
5
|
+
// make anything, which is how a definition outside `src/components/` is
|
|
6
|
+
// refused.
|
|
7
|
+
import { piece, pieceFunction, } from './instance.js';
|
|
8
|
+
export const COMPONENT_FOLDERS = {
|
|
9
|
+
buttons: 'button',
|
|
10
|
+
selects: 'select',
|
|
11
|
+
modals: 'modal',
|
|
12
|
+
embeds: 'embed',
|
|
13
|
+
};
|
|
14
|
+
const FILE = Symbol.for('chapterjs.component.file');
|
|
15
|
+
/** The state of a component file, if the value is one. */
|
|
16
|
+
export function fileStateOf(value) {
|
|
17
|
+
if (typeof value !== 'function')
|
|
18
|
+
return undefined;
|
|
19
|
+
return value[FILE];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Makes a component file. `asPiece` says whether the file itself stands
|
|
23
|
+
* for its instance when it carries no data (a button, a menu, a modal: not
|
|
24
|
+
* an embed, which is only a function).
|
|
25
|
+
*/
|
|
26
|
+
export function createFile(kind, config, { asPiece, pieceKind }) {
|
|
27
|
+
const state = { kind, config, made: `${kind}()` };
|
|
28
|
+
const notBound = () => {
|
|
29
|
+
throw new Error(`This ${kind} was not loaded by ChapterJS: a ${kind} is a file of src/components/${Object.keys(COMPONENT_FOLDERS).find(folder => COMPONENT_FOLDERS[folder] === kind)}/, exported by default, and used after the bot started.`);
|
|
30
|
+
};
|
|
31
|
+
const file = (...args) => {
|
|
32
|
+
if (!state.bound)
|
|
33
|
+
return notBound();
|
|
34
|
+
const rendered = state.bound.render(args);
|
|
35
|
+
return pieceKind
|
|
36
|
+
? piece(pieceKind, rendered.raw)
|
|
37
|
+
: rendered;
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(file, FILE, { value: state });
|
|
40
|
+
Object.defineProperty(file, 'config', { value: config, enumerable: true });
|
|
41
|
+
if (asPiece) {
|
|
42
|
+
pieceFunction(file, () => state.bound ? state.bound.render([]) : notBound());
|
|
43
|
+
}
|
|
44
|
+
return file;
|
|
45
|
+
}
|
|
46
|
+
/** Binds a file to its path and to what makes its instances. */
|
|
47
|
+
export function bindFile(file, bound) {
|
|
48
|
+
const state = fileStateOf(file);
|
|
49
|
+
if (!state)
|
|
50
|
+
throw new TypeError('Not a component file.');
|
|
51
|
+
state.bound = bound;
|
|
52
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { RawActionRow, RawButton, RawContainer, RawFileComponent, RawMediaGallery, RawSection, RawSelectMenu, RawSeparator, RawTextDisplay, RawThumbnail } from '../discord/types/component.js';
|
|
2
|
+
import type { RawEmoji } from '../discord/types/emoji.js';
|
|
3
|
+
import type { RawInteractionCallbackModalData } from '../discord/types/interaction.js';
|
|
4
|
+
import type { EmojiInput } from '../structures/message.js';
|
|
5
|
+
import type { Translator } from '../messages/messages.js';
|
|
6
|
+
declare const brand: unique symbol;
|
|
7
|
+
/** A piece of a message made by ChapterJS: a button, a menu, a layout. */
|
|
8
|
+
export interface Piece<Kind extends string> {
|
|
9
|
+
/** What kind of piece it is. Only the framework makes pieces. */
|
|
10
|
+
readonly [brand]: Kind;
|
|
11
|
+
}
|
|
12
|
+
/** A button: of a file of `src/components/buttons/`, `linkButton()` or `premiumButton()`. */
|
|
13
|
+
export type ButtonComponent = Piece<'button'>;
|
|
14
|
+
/** A select menu of a file of `src/components/selects/`. */
|
|
15
|
+
export type SelectComponent = Piece<'select'>;
|
|
16
|
+
/** A row of up to 5 buttons, or of one menu: `row()`. */
|
|
17
|
+
export type ActionRowComponent = Piece<'row'>;
|
|
18
|
+
/** A text: `text()`. */
|
|
19
|
+
export type TextComponent = Piece<'text'>;
|
|
20
|
+
/** Texts with a button or a thumbnail beside them: `section()`. */
|
|
21
|
+
export type SectionComponent = Piece<'section'>;
|
|
22
|
+
/** A small image beside a section: `thumbnail()`. */
|
|
23
|
+
export type ThumbnailComponent = Piece<'thumbnail'>;
|
|
24
|
+
/** Up to 10 images or videos: `gallery()`. */
|
|
25
|
+
export type GalleryComponent = Piece<'gallery'>;
|
|
26
|
+
/** An attached file shown in the message: `file()`. */
|
|
27
|
+
export type FileComponent = Piece<'file'>;
|
|
28
|
+
/** Space, with or without a line: `separator()`. */
|
|
29
|
+
export type SeparatorComponent = Piece<'separator'>;
|
|
30
|
+
/** A box around other pieces, with an optional color: `container()`. */
|
|
31
|
+
export type ContainerComponent = Piece<'container'>;
|
|
32
|
+
/** A form to open with `interaction.showModal()`: of a file of `src/components/modals/`. */
|
|
33
|
+
export type ModalComponent = Piece<'modal'>;
|
|
34
|
+
/** What a container can hold. */
|
|
35
|
+
export type ContainerChild = ButtonComponent | SelectComponent | ActionRowComponent | TextComponent | SectionComponent | GalleryComponent | FileComponent | SeparatorComponent;
|
|
36
|
+
/**
|
|
37
|
+
* What the `components` of a message take. Buttons and menus are put in
|
|
38
|
+
* rows by the framework (5 buttons per row, a menu alone in its row);
|
|
39
|
+
* `row()` is there to choose. As soon as a message has a text, a section,
|
|
40
|
+
* a gallery, a file, a separator or a container, it is built with
|
|
41
|
+
* components only: Discord then takes no `content` and no `embeds`.
|
|
42
|
+
* @see https://docs.discord.com/developers/components/reference
|
|
43
|
+
*/
|
|
44
|
+
export type MessageComponent = ContainerChild | ContainerComponent;
|
|
45
|
+
export type PieceKind = 'button' | 'select' | 'row' | 'text' | 'section' | 'thumbnail' | 'gallery' | 'file' | 'separator' | 'container' | 'modal';
|
|
46
|
+
interface RawOf {
|
|
47
|
+
button: RawButton;
|
|
48
|
+
select: RawSelectMenu;
|
|
49
|
+
row: RawActionRow;
|
|
50
|
+
text: RawTextDisplay;
|
|
51
|
+
section: RawSection;
|
|
52
|
+
thumbnail: RawThumbnail;
|
|
53
|
+
gallery: RawMediaGallery;
|
|
54
|
+
file: RawFileComponent;
|
|
55
|
+
separator: RawSeparator;
|
|
56
|
+
container: RawContainer;
|
|
57
|
+
modal: RawInteractionCallbackModalData;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* What a piece sends: known when the piece is made, or computed when the
|
|
61
|
+
* message is sent, with `t` in the language of who will read it (a piece
|
|
62
|
+
* whose texts are functions).
|
|
63
|
+
*/
|
|
64
|
+
export type Deferred<R> = R | ((t: Translator) => R);
|
|
65
|
+
/** A piece as the framework sees it. */
|
|
66
|
+
export interface Rendered<Kind extends PieceKind = PieceKind> {
|
|
67
|
+
kind: Kind;
|
|
68
|
+
raw: Deferred<RawOf[Kind]>;
|
|
69
|
+
}
|
|
70
|
+
/** A piece with what it sends, known: after `resolve()`. */
|
|
71
|
+
export interface Resolved<Kind extends PieceKind = PieceKind> {
|
|
72
|
+
kind: Kind;
|
|
73
|
+
raw: RawOf[Kind];
|
|
74
|
+
}
|
|
75
|
+
/** What a piece sends, for the language of who will read it. */
|
|
76
|
+
export declare function resolve<Kind extends PieceKind>(rendered: Rendered<Kind>, t: Translator): Resolved<Kind>;
|
|
77
|
+
/**
|
|
78
|
+
* What a piece made of others sends: known now when every child is, else
|
|
79
|
+
* computed when the message is sent, from what the children send then.
|
|
80
|
+
*/
|
|
81
|
+
export declare function compose<R>(children: readonly Rendered[], build: (raws: readonly unknown[]) => R): Deferred<R>;
|
|
82
|
+
/** Makes a piece. `raw` is frozen: a piece never changes once made. */
|
|
83
|
+
export declare function piece<Kind extends PieceKind>(kind: Kind, raw: Deferred<RawOf[Kind]>): Piece<Kind>;
|
|
84
|
+
/**
|
|
85
|
+
* Lets a function stand for a piece: the file of a button without data is
|
|
86
|
+
* a function (called with a look) and also the button itself. `render`
|
|
87
|
+
* is asked for the piece when the message is built.
|
|
88
|
+
*/
|
|
89
|
+
export declare function pieceFunction<F extends object>(target: F, render: () => Rendered): F;
|
|
90
|
+
/** Whether a value is a piece made by the framework. */
|
|
91
|
+
export declare function isPiece(value: unknown): value is Piece<PieceKind>;
|
|
92
|
+
/** What a piece is and how it is sent. Throws on anything else. */
|
|
93
|
+
export declare function renderedOf(value: unknown, where: string): Rendered;
|
|
94
|
+
/**
|
|
95
|
+
* An emoji as a component takes it: a standard one (`'👍'`), a custom one as
|
|
96
|
+
* Discord writes it (`'<:name:id>'`, `'<a:name:id>'`) or one of
|
|
97
|
+
* `guild.emojis`.
|
|
98
|
+
*/
|
|
99
|
+
export declare function emojiOf(input: EmojiInput, what: string): Partial<RawEmoji>;
|
|
100
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// What goes in the `components` of a message: pieces made by the framework
|
|
2
|
+
// (a button of `src/components/buttons/`, a `row()`, a `container()`...),
|
|
3
|
+
// never raw JSON. Each piece knows the Discord shape it is sent as; the
|
|
4
|
+
// brand is what lets a message refuse anything else, so that no custom_id
|
|
5
|
+
// is ever written by hand.
|
|
6
|
+
/** What a piece sends, for the language of who will read it. */
|
|
7
|
+
export function resolve(rendered, t) {
|
|
8
|
+
const { kind, raw } = rendered;
|
|
9
|
+
return { kind, raw: typeof raw === 'function' ? raw(t) : raw };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* What a piece made of others sends: known now when every child is, else
|
|
13
|
+
* computed when the message is sent, from what the children send then.
|
|
14
|
+
*/
|
|
15
|
+
export function compose(children, build) {
|
|
16
|
+
if (children.every(child => typeof child.raw !== 'function')) {
|
|
17
|
+
return build(children.map(child => child.raw));
|
|
18
|
+
}
|
|
19
|
+
return (t) => build(children.map(child => resolve(child, t).raw));
|
|
20
|
+
}
|
|
21
|
+
const INSTANCE = Symbol.for('chapterjs.component');
|
|
22
|
+
/** Makes a piece. `raw` is frozen: a piece never changes once made. */
|
|
23
|
+
export function piece(kind, raw) {
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
[INSTANCE]: true,
|
|
26
|
+
kind,
|
|
27
|
+
raw,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Lets a function stand for a piece: the file of a button without data is
|
|
32
|
+
* a function (called with a look) and also the button itself. `render`
|
|
33
|
+
* is asked for the piece when the message is built.
|
|
34
|
+
*/
|
|
35
|
+
export function pieceFunction(target, render) {
|
|
36
|
+
Object.defineProperty(target, INSTANCE, { value: true });
|
|
37
|
+
Object.defineProperty(target, 'kind', { get: () => render().kind });
|
|
38
|
+
Object.defineProperty(target, 'raw', { get: () => render().raw });
|
|
39
|
+
return target;
|
|
40
|
+
}
|
|
41
|
+
/** Whether a value is a piece made by the framework. */
|
|
42
|
+
export function isPiece(value) {
|
|
43
|
+
return ((typeof value === 'object' || typeof value === 'function') &&
|
|
44
|
+
value !== null &&
|
|
45
|
+
value[INSTANCE] === true);
|
|
46
|
+
}
|
|
47
|
+
/** What a piece is and how it is sent. Throws on anything else. */
|
|
48
|
+
export function renderedOf(value, where) {
|
|
49
|
+
if (!isPiece(value)) {
|
|
50
|
+
throw new TypeError(`${where} is not a component made by ChapterJS, got ${value === null ? 'null' : typeof value === 'object' && 'custom_id' in value ? 'an object with a custom_id' : typeof value}. Use the buttons, menus and modals of src/components/, and row(), text(), section(), container()... from 'chapterjs'. Components are never written as JSON.`);
|
|
51
|
+
}
|
|
52
|
+
const { kind, raw } = value;
|
|
53
|
+
return { kind, raw };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* An emoji as a component takes it: a standard one (`'👍'`), a custom one as
|
|
57
|
+
* Discord writes it (`'<:name:id>'`, `'<a:name:id>'`) or one of
|
|
58
|
+
* `guild.emojis`.
|
|
59
|
+
*/
|
|
60
|
+
export function emojiOf(input, what) {
|
|
61
|
+
if (typeof input !== 'string') {
|
|
62
|
+
const id = input.id ?? null;
|
|
63
|
+
const name = input.name ?? null;
|
|
64
|
+
if (!id && !name) {
|
|
65
|
+
throw new TypeError(`The emoji of ${what} has no name and no id.`);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
...(id ? { id } : {}),
|
|
69
|
+
...(name ? { name } : {}),
|
|
70
|
+
...(input.animated ? { animated: true } : {}),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const text = input.trim();
|
|
74
|
+
const custom = /^<(a?):(\w+):(\d+)>$/.exec(text);
|
|
75
|
+
if (custom) {
|
|
76
|
+
return {
|
|
77
|
+
id: custom[3],
|
|
78
|
+
name: custom[2],
|
|
79
|
+
...(custom[1] ? { animated: true } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (text === '') {
|
|
83
|
+
throw new TypeError(`The emoji of ${what} is empty: pass one like "👍", or a custom one like "<:name:id>".`);
|
|
84
|
+
}
|
|
85
|
+
return { name: text };
|
|
86
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { Snowflake } from '../discord/types/common.js';
|
|
2
|
+
import type { EmojiInput } from '../structures/message.js';
|
|
3
|
+
import { type ActionRowComponent, type ButtonComponent, type ContainerChild, type ContainerComponent, type FileComponent, type GalleryComponent, type Rendered, type SectionComponent, type SelectComponent, type SeparatorComponent, type TextComponent, type ThumbnailComponent } from './instance.js';
|
|
4
|
+
/** A link button: what it shows, and the address it opens. */
|
|
5
|
+
export interface LinkButtonOptions {
|
|
6
|
+
/** The text on the button (80 characters at most). */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** An emoji on the button, before the label. */
|
|
9
|
+
emoji?: EmojiInput;
|
|
10
|
+
/** The address the button opens (512 characters at most). */
|
|
11
|
+
url: string;
|
|
12
|
+
/** Shows the button greyed out, impossible to click. */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A button that opens a link. Nothing runs in your bot when it is clicked:
|
|
17
|
+
* Discord opens the address.
|
|
18
|
+
* @see https://docs.discord.com/developers/components/reference#button
|
|
19
|
+
*/
|
|
20
|
+
export declare function linkButton(options: LinkButtonOptions): ButtonComponent;
|
|
21
|
+
/**
|
|
22
|
+
* A button that offers something to buy: Discord shows the name and the
|
|
23
|
+
* price of the SKU itself.
|
|
24
|
+
* @see https://docs.discord.com/developers/components/reference#button
|
|
25
|
+
*/
|
|
26
|
+
export declare function premiumButton(skuId: Snowflake, { disabled }?: {
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
}): ButtonComponent;
|
|
29
|
+
/**
|
|
30
|
+
* A row of components: up to 5 buttons, or one select menu. The framework
|
|
31
|
+
* makes rows by itself; use this to choose which buttons share a row.
|
|
32
|
+
* @see https://docs.discord.com/developers/components/reference#action-row
|
|
33
|
+
*/
|
|
34
|
+
export declare function row(components: readonly (ButtonComponent | SelectComponent)[]): ActionRowComponent;
|
|
35
|
+
/**
|
|
36
|
+
* A text in a message built with components. Markdown works as in any
|
|
37
|
+
* message, mentions included. The texts of a message add up to 4000
|
|
38
|
+
* characters at most.
|
|
39
|
+
* @see https://docs.discord.com/developers/components/reference#text-display
|
|
40
|
+
*/
|
|
41
|
+
export declare function text(content: string): TextComponent;
|
|
42
|
+
/** A picture or a video: its address, or `attachment://name` for a file of the message. */
|
|
43
|
+
export interface MediaOptions {
|
|
44
|
+
/** The address of the media: a link, or `attachment://chart.png` for a file sent with the message. */
|
|
45
|
+
url: string;
|
|
46
|
+
/** What the media shows, for people who can't see it (1024 characters at most). */
|
|
47
|
+
description?: string;
|
|
48
|
+
/** Blurs the media until it is clicked. */
|
|
49
|
+
spoiler?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A small picture beside the texts of a section.
|
|
53
|
+
* @see https://docs.discord.com/developers/components/reference#thumbnail
|
|
54
|
+
*/
|
|
55
|
+
export declare function thumbnail(media: string | MediaOptions): ThumbnailComponent;
|
|
56
|
+
/**
|
|
57
|
+
* One to three texts with a button or a thumbnail beside them.
|
|
58
|
+
* @see https://docs.discord.com/developers/components/reference#section
|
|
59
|
+
*/
|
|
60
|
+
export declare function section(texts: string | readonly string[], accessory: ButtonComponent | ThumbnailComponent): SectionComponent;
|
|
61
|
+
/**
|
|
62
|
+
* Up to 10 pictures or videos, shown in a grid.
|
|
63
|
+
* @see https://docs.discord.com/developers/components/reference#media-gallery
|
|
64
|
+
*/
|
|
65
|
+
export declare function gallery(items: readonly (string | MediaOptions)[]): GalleryComponent;
|
|
66
|
+
/**
|
|
67
|
+
* A file sent with the message (its `files`), shown where it is placed.
|
|
68
|
+
* @see https://docs.discord.com/developers/components/reference#file
|
|
69
|
+
*/
|
|
70
|
+
export declare function file(name: string, { spoiler }?: {
|
|
71
|
+
spoiler?: boolean;
|
|
72
|
+
}): FileComponent;
|
|
73
|
+
/** How a separator looks. */
|
|
74
|
+
export interface SeparatorOptions {
|
|
75
|
+
/** Shows a line. Shown by default. */
|
|
76
|
+
divider?: boolean;
|
|
77
|
+
/** How much space: `'small'` (the default) or `'large'`. */
|
|
78
|
+
spacing?: 'small' | 'large';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Space between two pieces, with a line by default.
|
|
82
|
+
* @see https://docs.discord.com/developers/components/reference#separator
|
|
83
|
+
*/
|
|
84
|
+
export declare function separator({ divider, spacing, }?: SeparatorOptions): SeparatorComponent;
|
|
85
|
+
/** How a container looks. */
|
|
86
|
+
export interface ContainerOptions {
|
|
87
|
+
/** The color of the line on its left, as a number (`0xc026d3`). */
|
|
88
|
+
color?: number;
|
|
89
|
+
/** Blurs the whole container until it is clicked. */
|
|
90
|
+
spoiler?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A box around texts, sections, rows, galleries, files and separators,
|
|
94
|
+
* with an optional color on its left, like an embed.
|
|
95
|
+
* @see https://docs.discord.com/developers/components/reference#container
|
|
96
|
+
*/
|
|
97
|
+
export declare function container(children: readonly ContainerChild[], { color, spoiler }?: ContainerOptions): ContainerComponent;
|
|
98
|
+
/**
|
|
99
|
+
* Puts the buttons and menus of a list in rows: buttons that follow each
|
|
100
|
+
* other share a row of 5 at most, a menu gets its own. Rows and layout
|
|
101
|
+
* pieces are kept as they are.
|
|
102
|
+
*/
|
|
103
|
+
export declare function autoRows(pieces: readonly Rendered[], where: string): Rendered[];
|