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,112 @@
|
|
|
1
|
+
import { cdn } from '../discord/cdn.js';
|
|
2
|
+
import { DeleteGuildRole, ModifyGuildRole } from '../discord/endpoints.js';
|
|
3
|
+
import { roleMention } from '../discord/formatting.js';
|
|
4
|
+
import { Permissions } from '../discord/permissions.js';
|
|
5
|
+
import { toSnakeCase } from '../util/case.js';
|
|
6
|
+
import { ctxOf, dataOf, IdStructure } from './base.js';
|
|
7
|
+
import { guildOf } from './known.js';
|
|
8
|
+
/**
|
|
9
|
+
* A role of a server.
|
|
10
|
+
* @see https://docs.discord.com/developers/topics/permissions#role-object
|
|
11
|
+
*/
|
|
12
|
+
export class Role extends IdStructure {
|
|
13
|
+
/** The id of the server of the role. */
|
|
14
|
+
guildId;
|
|
15
|
+
constructor(ctx, data, guildId) {
|
|
16
|
+
super(ctx, data);
|
|
17
|
+
this.guildId = guildId;
|
|
18
|
+
}
|
|
19
|
+
/** The server of the role. */
|
|
20
|
+
get guild() {
|
|
21
|
+
return guildOf(this, this.guildId);
|
|
22
|
+
}
|
|
23
|
+
/** The name of the role. */
|
|
24
|
+
get name() {
|
|
25
|
+
return dataOf(this).name;
|
|
26
|
+
}
|
|
27
|
+
/** The color as a number (`0xff0000`); `0` means no color. */
|
|
28
|
+
get color() {
|
|
29
|
+
return dataOf(this).colors?.primary_color ?? dataOf(this).color;
|
|
30
|
+
}
|
|
31
|
+
/** Whether members with this role are shown apart in the member list. */
|
|
32
|
+
get hoist() {
|
|
33
|
+
return dataOf(this).hoist;
|
|
34
|
+
}
|
|
35
|
+
/** Where the role is in the hierarchy: the higher, the more powerful. */
|
|
36
|
+
get position() {
|
|
37
|
+
return dataOf(this).position;
|
|
38
|
+
}
|
|
39
|
+
/** What the role allows in the server. */
|
|
40
|
+
get permissions() {
|
|
41
|
+
return new Permissions(dataOf(this).permissions);
|
|
42
|
+
}
|
|
43
|
+
/** Whether the role belongs to an integration (a bot, boosters...). */
|
|
44
|
+
get managed() {
|
|
45
|
+
return dataOf(this).managed;
|
|
46
|
+
}
|
|
47
|
+
/** Whether everyone can mention the role. */
|
|
48
|
+
get mentionable() {
|
|
49
|
+
return dataOf(this).mentionable;
|
|
50
|
+
}
|
|
51
|
+
/** The standard emoji shown next to the role, when it has one. */
|
|
52
|
+
get unicodeEmoji() {
|
|
53
|
+
return dataOf(this).unicode_emoji ?? null;
|
|
54
|
+
}
|
|
55
|
+
/** Whether this is the @everyone role, which every member has. */
|
|
56
|
+
get isEveryone() {
|
|
57
|
+
return this.id === this.guildId;
|
|
58
|
+
}
|
|
59
|
+
/** The members that have this role, among the ones the bot knows. */
|
|
60
|
+
get members() {
|
|
61
|
+
const guild = this.guild;
|
|
62
|
+
if (!guild)
|
|
63
|
+
return [];
|
|
64
|
+
return [...guild.members.values()].filter(member => member.roleIds.includes(this.id));
|
|
65
|
+
}
|
|
66
|
+
/** The URL of the icon of the role, when it has one. */
|
|
67
|
+
iconURL(options) {
|
|
68
|
+
const icon = dataOf(this).icon;
|
|
69
|
+
return icon ? cdn.roleIcon(this.id, icon, options) : null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Whether this role is above another one in the hierarchy. With the same
|
|
73
|
+
* position, the oldest role is above.
|
|
74
|
+
* @see https://docs.discord.com/developers/topics/permissions#permission-hierarchy
|
|
75
|
+
*/
|
|
76
|
+
isHigherThan(other) {
|
|
77
|
+
if (this.position !== other.position) {
|
|
78
|
+
return this.position > other.position;
|
|
79
|
+
}
|
|
80
|
+
return BigInt(this.id) < BigInt(other.id);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Changes the role.
|
|
84
|
+
* @see https://docs.discord.com/developers/resources/guild#modify-guild-role
|
|
85
|
+
*/
|
|
86
|
+
async edit(options, reason) {
|
|
87
|
+
const { rest, entities } = ctxOf(this);
|
|
88
|
+
const { permissions, ...rest_ } = options;
|
|
89
|
+
const body = toSnakeCase(rest_);
|
|
90
|
+
if (permissions !== undefined) {
|
|
91
|
+
body.permissions = new Permissions(permissions).toString();
|
|
92
|
+
}
|
|
93
|
+
const raw = await rest.request(ModifyGuildRole, [this.guildId, this.id], {
|
|
94
|
+
body,
|
|
95
|
+
reason,
|
|
96
|
+
});
|
|
97
|
+
return entities.role(this.guildId, raw);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Deletes the role.
|
|
101
|
+
* @see https://docs.discord.com/developers/resources/guild#delete-guild-role
|
|
102
|
+
*/
|
|
103
|
+
async delete(reason) {
|
|
104
|
+
await ctxOf(this).rest.request(DeleteGuildRole, [this.guildId, this.id], {
|
|
105
|
+
reason,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/** `<@&id>`: mentions the role when put in a message. */
|
|
109
|
+
toString() {
|
|
110
|
+
return this.isEveryone ? '@everyone' : roleMention(this.id);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type ImageOptions } from '../discord/cdn.js';
|
|
2
|
+
import type { Locale } from '../discord/types/common.js';
|
|
3
|
+
import type { RawPresenceUpdateEvent } from '../discord/types/gateway-events.js';
|
|
4
|
+
import { UserFlags, type RawUser } from '../discord/types/user.js';
|
|
5
|
+
import type { Camelize } from '../util/case.js';
|
|
6
|
+
import { IdStructure } from './base.js';
|
|
7
|
+
import type { DMChannel } from './channel.js';
|
|
8
|
+
import type { Message } from './message.js';
|
|
9
|
+
import type { MessageInput } from './payload.js';
|
|
10
|
+
export type UserFlagName = keyof typeof UserFlags;
|
|
11
|
+
/**
|
|
12
|
+
* Whether someone is online and what they are doing: their status, their
|
|
13
|
+
* activities, and on which devices.
|
|
14
|
+
* @see https://docs.discord.com/developers/events/gateway-events#presence-update-presence-update-event-fields
|
|
15
|
+
*/
|
|
16
|
+
export type UserPresence = Camelize<Omit<RawPresenceUpdateEvent, 'user' | 'guild_id'>>;
|
|
17
|
+
/**
|
|
18
|
+
* A Discord account, the same in every server.
|
|
19
|
+
* @see https://docs.discord.com/developers/resources/user#user-object
|
|
20
|
+
*/
|
|
21
|
+
export declare class User extends IdStructure<RawUser> {
|
|
22
|
+
/** The unique name of the account (`@name`). */
|
|
23
|
+
get username(): string;
|
|
24
|
+
/** The name shown in Discord, when the user chose one. */
|
|
25
|
+
get globalName(): string | null;
|
|
26
|
+
/** The name to show: the display name, or else the username. */
|
|
27
|
+
get displayName(): string;
|
|
28
|
+
/** `"0"` for users on the current username system. */
|
|
29
|
+
get discriminator(): string;
|
|
30
|
+
/** Whether the account is a bot. */
|
|
31
|
+
get bot(): boolean;
|
|
32
|
+
/** Whether the account is an official Discord system account. */
|
|
33
|
+
get system(): boolean;
|
|
34
|
+
/** The hash of the avatar; use `avatarURL()` to get the image. */
|
|
35
|
+
get avatar(): string | null;
|
|
36
|
+
/** The hash of the banner; use `bannerURL()` to get the image. */
|
|
37
|
+
get banner(): string | null;
|
|
38
|
+
/** The banner color, as a number (`0xff0000`). */
|
|
39
|
+
get accentColor(): number | null;
|
|
40
|
+
/** Only known for the bot itself. */
|
|
41
|
+
get locale(): Locale | null;
|
|
42
|
+
/** The public badges of the account, by name. */
|
|
43
|
+
get flags(): UserFlagName[];
|
|
44
|
+
/** The URL of the avatar; of the default one when none is set. */
|
|
45
|
+
avatarURL(options?: ImageOptions): string;
|
|
46
|
+
/** The URL of the banner, when one is set. */
|
|
47
|
+
bannerURL(options?: ImageOptions): string | null;
|
|
48
|
+
/** Asks Discord for the latest data of this user. */
|
|
49
|
+
fetch(): Promise<User>;
|
|
50
|
+
/**
|
|
51
|
+
* Opens the private conversation with this user.
|
|
52
|
+
* @see https://docs.discord.com/developers/resources/user#create-dm
|
|
53
|
+
*/
|
|
54
|
+
createDM(): Promise<DMChannel>;
|
|
55
|
+
/** Sends a private message to this user. */
|
|
56
|
+
send(message: MessageInput): Promise<Message>;
|
|
57
|
+
/** `<@id>`: mentions the user when put in a message. */
|
|
58
|
+
toString(): string;
|
|
59
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { cdn } from '../discord/cdn.js';
|
|
2
|
+
import { CreateDm, GetUser } from '../discord/endpoints.js';
|
|
3
|
+
import { userMention } from '../discord/formatting.js';
|
|
4
|
+
import { UserFlags } from '../discord/types/user.js';
|
|
5
|
+
import { ctxOf, dataOf, IdStructure } from './base.js';
|
|
6
|
+
/**
|
|
7
|
+
* A Discord account, the same in every server.
|
|
8
|
+
* @see https://docs.discord.com/developers/resources/user#user-object
|
|
9
|
+
*/
|
|
10
|
+
export class User extends IdStructure {
|
|
11
|
+
/** The unique name of the account (`@name`). */
|
|
12
|
+
get username() {
|
|
13
|
+
return dataOf(this).username;
|
|
14
|
+
}
|
|
15
|
+
/** The name shown in Discord, when the user chose one. */
|
|
16
|
+
get globalName() {
|
|
17
|
+
return dataOf(this).global_name ?? null;
|
|
18
|
+
}
|
|
19
|
+
/** The name to show: the display name, or else the username. */
|
|
20
|
+
get displayName() {
|
|
21
|
+
return this.globalName ?? this.username;
|
|
22
|
+
}
|
|
23
|
+
/** `"0"` for users on the current username system. */
|
|
24
|
+
get discriminator() {
|
|
25
|
+
return dataOf(this).discriminator;
|
|
26
|
+
}
|
|
27
|
+
/** Whether the account is a bot. */
|
|
28
|
+
get bot() {
|
|
29
|
+
return dataOf(this).bot ?? false;
|
|
30
|
+
}
|
|
31
|
+
/** Whether the account is an official Discord system account. */
|
|
32
|
+
get system() {
|
|
33
|
+
return dataOf(this).system ?? false;
|
|
34
|
+
}
|
|
35
|
+
/** The hash of the avatar; use `avatarURL()` to get the image. */
|
|
36
|
+
get avatar() {
|
|
37
|
+
return dataOf(this).avatar;
|
|
38
|
+
}
|
|
39
|
+
/** The hash of the banner; use `bannerURL()` to get the image. */
|
|
40
|
+
get banner() {
|
|
41
|
+
return dataOf(this).banner ?? null;
|
|
42
|
+
}
|
|
43
|
+
/** The banner color, as a number (`0xff0000`). */
|
|
44
|
+
get accentColor() {
|
|
45
|
+
return dataOf(this).accent_color ?? null;
|
|
46
|
+
}
|
|
47
|
+
/** Only known for the bot itself. */
|
|
48
|
+
get locale() {
|
|
49
|
+
return dataOf(this).locale ?? null;
|
|
50
|
+
}
|
|
51
|
+
/** The public badges of the account, by name. */
|
|
52
|
+
get flags() {
|
|
53
|
+
const bits = dataOf(this).public_flags ?? dataOf(this).flags ?? 0;
|
|
54
|
+
return Object.keys(UserFlags).filter(name => (bits & UserFlags[name]) !== 0);
|
|
55
|
+
}
|
|
56
|
+
/** The URL of the avatar; of the default one when none is set. */
|
|
57
|
+
avatarURL(options) {
|
|
58
|
+
return this.avatar
|
|
59
|
+
? cdn.userAvatar(this.id, this.avatar, options)
|
|
60
|
+
: cdn.defaultUserAvatar(this.id, this.discriminator);
|
|
61
|
+
}
|
|
62
|
+
/** The URL of the banner, when one is set. */
|
|
63
|
+
bannerURL(options) {
|
|
64
|
+
return this.banner ? cdn.userBanner(this.id, this.banner, options) : null;
|
|
65
|
+
}
|
|
66
|
+
/** Asks Discord for the latest data of this user. */
|
|
67
|
+
async fetch() {
|
|
68
|
+
const { rest, entities } = ctxOf(this);
|
|
69
|
+
return entities.user(await rest.request(GetUser, [this.id]));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Opens the private conversation with this user.
|
|
73
|
+
* @see https://docs.discord.com/developers/resources/user#create-dm
|
|
74
|
+
*/
|
|
75
|
+
async createDM() {
|
|
76
|
+
const { rest, entities, cache } = ctxOf(this);
|
|
77
|
+
for (const channel of cache.channels.values()) {
|
|
78
|
+
if (channel.isDM() && channel.recipientId === this.id)
|
|
79
|
+
return channel;
|
|
80
|
+
}
|
|
81
|
+
const raw = await rest.request(CreateDm, [], {
|
|
82
|
+
body: { recipient_id: this.id },
|
|
83
|
+
});
|
|
84
|
+
return entities.channel(raw);
|
|
85
|
+
}
|
|
86
|
+
/** Sends a private message to this user. */
|
|
87
|
+
async send(message) {
|
|
88
|
+
return (await this.createDM()).send(message);
|
|
89
|
+
}
|
|
90
|
+
/** `<@id>`: mentions the user when put in a message. */
|
|
91
|
+
toString() {
|
|
92
|
+
return userMention(this.id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Snowflake } from '../discord/types/common.js';
|
|
2
|
+
import type { ModifyWebhookJSONParams, RawWebhook } from '../discord/types/webhook.js';
|
|
3
|
+
import { type Camelize } from '../util/case.js';
|
|
4
|
+
import { IdStructure } from './base.js';
|
|
5
|
+
import type { Message } from './message.js';
|
|
6
|
+
import { type MessageOptions } from './payload.js';
|
|
7
|
+
/** What a message posted with a webhook can contain. */
|
|
8
|
+
export interface WebhookMessageOptions extends Omit<MessageOptions, 'replyTo'> {
|
|
9
|
+
/** Shows this name instead of the name of the webhook. */
|
|
10
|
+
username?: string;
|
|
11
|
+
/** Shows this avatar instead of the avatar of the webhook. */
|
|
12
|
+
avatarURL?: string;
|
|
13
|
+
/** Sends the message in this thread of the channel of the webhook. */
|
|
14
|
+
threadId?: Snowflake;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A webhook: a way to post messages in a channel under any name.
|
|
18
|
+
* @see https://docs.discord.com/developers/resources/webhook#webhook-object
|
|
19
|
+
*/
|
|
20
|
+
export declare class Webhook extends IdStructure<Omit<RawWebhook, 'user'>> {
|
|
21
|
+
/** The default name the webhook posts with. */
|
|
22
|
+
get name(): string | null;
|
|
23
|
+
/** The id of the channel the webhook posts in. */
|
|
24
|
+
get channelId(): Snowflake | null;
|
|
25
|
+
/** The id of the server of the webhook. */
|
|
26
|
+
get guildId(): Snowflake | null;
|
|
27
|
+
/** The data of the webhook, without its token: a token is a secret. */
|
|
28
|
+
toJSON(): Camelize<Omit<RawWebhook, 'user'>>;
|
|
29
|
+
/** Whether the bot can post with it: only webhooks it created. */
|
|
30
|
+
get canSend(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Posts a message with the webhook.
|
|
33
|
+
* @see https://docs.discord.com/developers/resources/webhook#execute-webhook
|
|
34
|
+
*/
|
|
35
|
+
send(message: string | WebhookMessageOptions): Promise<Message>;
|
|
36
|
+
/**
|
|
37
|
+
* Changes the name, the avatar or the channel of the webhook.
|
|
38
|
+
* @see https://docs.discord.com/developers/resources/webhook#modify-webhook
|
|
39
|
+
*/
|
|
40
|
+
edit(options: Camelize<ModifyWebhookJSONParams>, reason?: string): Promise<Webhook>;
|
|
41
|
+
/**
|
|
42
|
+
* Deletes the webhook.
|
|
43
|
+
* @see https://docs.discord.com/developers/resources/webhook#delete-webhook
|
|
44
|
+
*/
|
|
45
|
+
delete(reason?: string): Promise<void>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { DeleteWebhook, ExecuteWebhook, ModifyWebhook, } from '../discord/endpoints.js';
|
|
2
|
+
import { toSnakeCase } from '../util/case.js';
|
|
3
|
+
import { ctxOf, dataOf, IdStructure } from './base.js';
|
|
4
|
+
import { buildMessage } from './payload.js';
|
|
5
|
+
import { translatorOf } from '../messages/translate.js';
|
|
6
|
+
/**
|
|
7
|
+
* A webhook: a way to post messages in a channel under any name.
|
|
8
|
+
* @see https://docs.discord.com/developers/resources/webhook#webhook-object
|
|
9
|
+
*/
|
|
10
|
+
export class Webhook extends IdStructure {
|
|
11
|
+
/** The default name the webhook posts with. */
|
|
12
|
+
get name() {
|
|
13
|
+
return dataOf(this).name;
|
|
14
|
+
}
|
|
15
|
+
/** The id of the channel the webhook posts in. */
|
|
16
|
+
get channelId() {
|
|
17
|
+
return dataOf(this).channel_id;
|
|
18
|
+
}
|
|
19
|
+
/** The id of the server of the webhook. */
|
|
20
|
+
get guildId() {
|
|
21
|
+
return dataOf(this).guild_id ?? null;
|
|
22
|
+
}
|
|
23
|
+
/** The data of the webhook, without its token: a token is a secret. */
|
|
24
|
+
toJSON() {
|
|
25
|
+
const { token: _token, ...data } = super.toJSON();
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
/** Whether the bot can post with it: only webhooks it created. */
|
|
29
|
+
get canSend() {
|
|
30
|
+
return typeof dataOf(this).token === 'string';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Posts a message with the webhook.
|
|
34
|
+
* @see https://docs.discord.com/developers/resources/webhook#execute-webhook
|
|
35
|
+
*/
|
|
36
|
+
async send(message) {
|
|
37
|
+
const { rest, entities } = ctxOf(this);
|
|
38
|
+
const token = dataOf(this).token;
|
|
39
|
+
if (!token) {
|
|
40
|
+
throw new Error('This webhook was not created by the bot: Discord only lets its creator post with it.');
|
|
41
|
+
}
|
|
42
|
+
const options = typeof message === 'string' ? { content: message } : message;
|
|
43
|
+
const { body, files } = buildMessage(options, {
|
|
44
|
+
t: translatorOf(ctxOf(this), {
|
|
45
|
+
guild: this.guildId ? ctxOf(this).cache.guilds.get(this.guildId) : null,
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
const raw = await rest.request(ExecuteWebhook, [this.id, token], {
|
|
49
|
+
body: {
|
|
50
|
+
...body,
|
|
51
|
+
username: options.username,
|
|
52
|
+
avatar_url: options.avatarURL,
|
|
53
|
+
},
|
|
54
|
+
query: { wait: true, thread_id: options.threadId },
|
|
55
|
+
files,
|
|
56
|
+
auth: false,
|
|
57
|
+
});
|
|
58
|
+
return entities.message(raw, this.guildId ?? undefined);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Changes the name, the avatar or the channel of the webhook.
|
|
62
|
+
* @see https://docs.discord.com/developers/resources/webhook#modify-webhook
|
|
63
|
+
*/
|
|
64
|
+
async edit(options, reason) {
|
|
65
|
+
const { rest, entities } = ctxOf(this);
|
|
66
|
+
const raw = await rest.request(ModifyWebhook, [this.id], {
|
|
67
|
+
body: toSnakeCase(options),
|
|
68
|
+
reason,
|
|
69
|
+
});
|
|
70
|
+
return entities.webhook(raw);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Deletes the webhook.
|
|
74
|
+
* @see https://docs.discord.com/developers/resources/webhook#delete-webhook
|
|
75
|
+
*/
|
|
76
|
+
async delete(reason) {
|
|
77
|
+
await ctxOf(this).rest.request(DeleteWebhook, [this.id], { reason });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Convention } from '../loader/loader.js';
|
|
2
|
+
import { type Schedule } from './schedule.js';
|
|
3
|
+
import { type TaskContext } from './task.js';
|
|
4
|
+
/** A task file, checked: what the scheduler works with. */
|
|
5
|
+
export interface LoadedTask {
|
|
6
|
+
/** The name of the task: the path of the file, without extension. */
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly schedule: Schedule;
|
|
9
|
+
readonly onStart: boolean;
|
|
10
|
+
readonly run: (context: TaskContext) => unknown;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* `src/tasks/`: each file is a task, named after its path. It exports by
|
|
14
|
+
* default what `task()` returns:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // src/tasks/report.ts
|
|
18
|
+
* import { task } from 'chapterjs';
|
|
19
|
+
*
|
|
20
|
+
* export default task({
|
|
21
|
+
* cron: '0 9 * * 1',
|
|
22
|
+
* async run({ guilds }) { ... },
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare const tasksConvention: Convention<LoadedTask>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// `src/tasks/`: one file per task, named after it. What the file declares
|
|
2
|
+
// is checked when it loads, so a wrong duration or cron is explained
|
|
3
|
+
// before the bot waits for it.
|
|
4
|
+
import { parseCron, parseEvery } from './schedule.js';
|
|
5
|
+
import { isTaskFile } from './task.js';
|
|
6
|
+
const fail = (message) => {
|
|
7
|
+
throw new TypeError(message);
|
|
8
|
+
};
|
|
9
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
10
|
+
const KEYS = ['every', 'cron', 'timezone', 'onStart', 'run'];
|
|
11
|
+
/**
|
|
12
|
+
* `src/tasks/`: each file is a task, named after its path. It exports by
|
|
13
|
+
* default what `task()` returns:
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* // src/tasks/report.ts
|
|
17
|
+
* import { task } from 'chapterjs';
|
|
18
|
+
*
|
|
19
|
+
* export default task({
|
|
20
|
+
* cron: '0 9 * * 1',
|
|
21
|
+
* async run({ guilds }) { ... },
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const tasksConvention = {
|
|
26
|
+
folder: 'tasks',
|
|
27
|
+
one: 'task',
|
|
28
|
+
many: 'tasks',
|
|
29
|
+
check(path) {
|
|
30
|
+
for (const part of path.replace(/\.[^./]+$/, '').split('/')) {
|
|
31
|
+
if (!/^[A-Za-z0-9_-]+$/.test(part)) {
|
|
32
|
+
fail(`"${part}" can't be in the name of a task: use letters, digits, - and _ only. The path of the file is the name of the task.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
read(exports, path) {
|
|
37
|
+
const file = exports.default;
|
|
38
|
+
const example = `import { task } from 'chapterjs'; export default task({ every: '10m', run() { ... } })`;
|
|
39
|
+
if (!isTaskFile(file)) {
|
|
40
|
+
return fail('default' in exports
|
|
41
|
+
? `The default export of this file must be what task() returns: ${example}`
|
|
42
|
+
: `This file has no default export. It should look like: ${example}`);
|
|
43
|
+
}
|
|
44
|
+
const config = file.config;
|
|
45
|
+
if (!isRecord(config)) {
|
|
46
|
+
return fail(`task() needs an object: task({ every: '10m', run() { ... } })`);
|
|
47
|
+
}
|
|
48
|
+
for (const key of Object.keys(config)) {
|
|
49
|
+
if (!KEYS.includes(key)) {
|
|
50
|
+
fail(`"${key}" is not something a task has. It can have: ${KEYS.join(', ')}.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (config.every !== undefined && config.cron !== undefined) {
|
|
54
|
+
fail(`This task has both "every" and "cron": keep one. "every" is an interval ('10m'), "cron" a time ('0 9 * * *').`);
|
|
55
|
+
}
|
|
56
|
+
if (config.every === undefined && config.cron === undefined) {
|
|
57
|
+
fail(`This task does not say when it runs: add every: '10m' (an interval) or cron: '0 9 * * *' (a time).`);
|
|
58
|
+
}
|
|
59
|
+
if (config.every !== undefined && config.timezone !== undefined) {
|
|
60
|
+
fail(`"timezone" only goes with "cron": an interval is the same in every timezone.`);
|
|
61
|
+
}
|
|
62
|
+
const schedule = config.every !== undefined
|
|
63
|
+
? parseEvery(config.every)
|
|
64
|
+
: parseCron(config.cron, config.timezone);
|
|
65
|
+
if (config.onStart !== undefined && typeof config.onStart !== 'boolean') {
|
|
66
|
+
fail(`"onStart" is true or false, got ${JSON.stringify(config.onStart) ?? typeof config.onStart}.`);
|
|
67
|
+
}
|
|
68
|
+
if (typeof config.run !== 'function') {
|
|
69
|
+
fail(`This task has no "run": the function to run each time, like async run({ guilds }) { ... }`);
|
|
70
|
+
}
|
|
71
|
+
return Object.freeze({
|
|
72
|
+
name: path.replace(/\.[^./]+$/, ''),
|
|
73
|
+
schedule,
|
|
74
|
+
onStart: config.onStart === true,
|
|
75
|
+
run: config.run,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** A duration: every so often. */
|
|
2
|
+
export interface EverySchedule {
|
|
3
|
+
readonly kind: 'every';
|
|
4
|
+
/** The text the file gave: `'10m'`. */
|
|
5
|
+
readonly text: string;
|
|
6
|
+
readonly ms: number;
|
|
7
|
+
}
|
|
8
|
+
/** A cron expression, in a timezone. */
|
|
9
|
+
export interface CronSchedule {
|
|
10
|
+
readonly kind: 'cron';
|
|
11
|
+
/** The text the file gave: `'0 9 * * 1-5'`. */
|
|
12
|
+
readonly text: string;
|
|
13
|
+
readonly timezone: string;
|
|
14
|
+
/** For each field, the values that match. */
|
|
15
|
+
readonly minutes: ReadonlySet<number>;
|
|
16
|
+
readonly hours: ReadonlySet<number>;
|
|
17
|
+
readonly days: ReadonlySet<number>;
|
|
18
|
+
readonly months: ReadonlySet<number>;
|
|
19
|
+
readonly weekdays: ReadonlySet<number>;
|
|
20
|
+
/** Whether the day of month was given (`*` in both day fields means every day). */
|
|
21
|
+
readonly anyDay: boolean;
|
|
22
|
+
readonly anyWeekday: boolean;
|
|
23
|
+
}
|
|
24
|
+
export type Schedule = EverySchedule | CronSchedule;
|
|
25
|
+
/** The shortest `every` accepted, in milliseconds. */
|
|
26
|
+
export declare const MIN_EVERY = 1000;
|
|
27
|
+
/**
|
|
28
|
+
* Parses a duration: a number and a unit, `s`, `m`, `h` or `d`, like
|
|
29
|
+
* `'30s'`, `'10m'`, `'2h'`, `'1d'`. Several parts add up: `'1h30m'`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseEvery(text: unknown): EverySchedule;
|
|
32
|
+
/** Whether a timezone exists, as `Intl` knows them. */
|
|
33
|
+
export declare function isTimezone(name: string): boolean;
|
|
34
|
+
/** The timezone of the machine. */
|
|
35
|
+
export declare const localTimezone: () => string;
|
|
36
|
+
/**
|
|
37
|
+
* Parses a cron expression: five fields, minute, hour, day of month,
|
|
38
|
+
* month and day of week, with `*`, lists, ranges, steps and names.
|
|
39
|
+
* @see https://en.wikipedia.org/wiki/Cron#Cron_expression
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseCron(text: unknown, timezone: unknown): CronSchedule;
|
|
42
|
+
/**
|
|
43
|
+
* The next moment a cron matches, strictly after `from`; `null` when none
|
|
44
|
+
* comes in the next five years. Walks the clock of the timezone: minute
|
|
45
|
+
* by minute within a matching hour, hour by hour otherwise, so a change
|
|
46
|
+
* of daylight saving time is read, not computed.
|
|
47
|
+
*/
|
|
48
|
+
export declare function nextCron(schedule: CronSchedule, from: Date): Date | null;
|
|
49
|
+
/** The next time a schedule is due, strictly after `from`. */
|
|
50
|
+
export declare function nextRun(schedule: Schedule, from: Date): Date;
|
|
51
|
+
/** What tells one schedule from another: the same key is the same timing. */
|
|
52
|
+
export declare const scheduleKey: (schedule: Schedule) => string;
|
|
53
|
+
/** The schedule in words, for the developer. */
|
|
54
|
+
export declare const describeSchedule: (schedule: Schedule) => string;
|