@mostfeatured/dbi 0.0.1
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/.gitattributes +2 -0
- package/LICENSE +674 -0
- package/dist/src/DBI.d.ts +78 -0
- package/dist/src/DBI.d.ts.map +1 -0
- package/dist/src/DBI.js +202 -0
- package/dist/src/DBI.js.map +1 -0
- package/dist/src/Events.d.ts +29 -0
- package/dist/src/Events.d.ts.map +1 -0
- package/dist/src/Events.js +51 -0
- package/dist/src/Events.js.map +1 -0
- package/dist/src/data/eventMap.json +234 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/methods/hookEventListeners.d.ts +3 -0
- package/dist/src/methods/hookEventListeners.d.ts.map +1 -0
- package/dist/src/methods/hookEventListeners.js +34 -0
- package/dist/src/methods/hookEventListeners.js.map +1 -0
- package/dist/src/methods/hookInteractionListeners.d.ts +3 -0
- package/dist/src/methods/hookInteractionListeners.d.ts.map +1 -0
- package/dist/src/methods/hookInteractionListeners.js +97 -0
- package/dist/src/methods/hookInteractionListeners.js.map +1 -0
- package/dist/src/methods/publishInteractions.d.ts +4 -0
- package/dist/src/methods/publishInteractions.d.ts.map +1 -0
- package/dist/src/methods/publishInteractions.js +150 -0
- package/dist/src/methods/publishInteractions.js.map +1 -0
- package/dist/src/types/Button.d.ts +19 -0
- package/dist/src/types/Button.d.ts.map +1 -0
- package/dist/src/types/Button.js +27 -0
- package/dist/src/types/Button.js.map +1 -0
- package/dist/src/types/ChatInput/ChatInput.d.ts +15 -0
- package/dist/src/types/ChatInput/ChatInput.d.ts.map +1 -0
- package/dist/src/types/ChatInput/ChatInput.js +19 -0
- package/dist/src/types/ChatInput/ChatInput.js.map +1 -0
- package/dist/src/types/ChatInput/ChatInputOptions.d.ts +153 -0
- package/dist/src/types/ChatInput/ChatInputOptions.d.ts.map +1 -0
- package/dist/src/types/ChatInput/ChatInputOptions.js +149 -0
- package/dist/src/types/ChatInput/ChatInputOptions.js.map +1 -0
- package/dist/src/types/Event.d.ts +257 -0
- package/dist/src/types/Event.d.ts.map +1 -0
- package/dist/src/types/Event.js +21 -0
- package/dist/src/types/Event.js.map +1 -0
- package/dist/src/types/Interaction.d.ts +34 -0
- package/dist/src/types/Interaction.d.ts.map +1 -0
- package/dist/src/types/Interaction.js +25 -0
- package/dist/src/types/Interaction.js.map +1 -0
- package/dist/src/types/Locale.d.ts +19 -0
- package/dist/src/types/Locale.d.ts.map +1 -0
- package/dist/src/types/Locale.js +31 -0
- package/dist/src/types/Locale.js.map +1 -0
- package/dist/src/types/MessageContextMenu.d.ts +14 -0
- package/dist/src/types/MessageContextMenu.d.ts.map +1 -0
- package/dist/src/types/MessageContextMenu.js +17 -0
- package/dist/src/types/MessageContextMenu.js.map +1 -0
- package/dist/src/types/Modal.d.ts +19 -0
- package/dist/src/types/Modal.d.ts.map +1 -0
- package/dist/src/types/Modal.js +24 -0
- package/dist/src/types/Modal.js.map +1 -0
- package/dist/src/types/SelectMenu.d.ts +19 -0
- package/dist/src/types/SelectMenu.d.ts.map +1 -0
- package/dist/src/types/SelectMenu.js +27 -0
- package/dist/src/types/SelectMenu.js.map +1 -0
- package/dist/src/types/UserContextMenu.d.ts +14 -0
- package/dist/src/types/UserContextMenu.d.ts.map +1 -0
- package/dist/src/types/UserContextMenu.js +17 -0
- package/dist/src/types/UserContextMenu.js.map +1 -0
- package/dist/src/utils/MemoryStore.d.ts +9 -0
- package/dist/src/utils/MemoryStore.d.ts.map +1 -0
- package/dist/src/utils/MemoryStore.js +30 -0
- package/dist/src/utils/MemoryStore.js.map +1 -0
- package/dist/src/utils/customId.d.ts +7 -0
- package/dist/src/utils/customId.d.ts.map +1 -0
- package/dist/src/utils/customId.js +44 -0
- package/dist/src/utils/customId.js.map +1 -0
- package/dist/src/utils/permissions.d.ts +3 -0
- package/dist/src/utils/permissions.d.ts.map +1 -0
- package/dist/src/utils/permissions.js +9 -0
- package/dist/src/utils/permissions.js.map +1 -0
- package/dist/src/utils/recursiveImport.d.ts +2 -0
- package/dist/src/utils/recursiveImport.d.ts.map +1 -0
- package/dist/src/utils/recursiveImport.js +20 -0
- package/dist/src/utils/recursiveImport.js.map +1 -0
- package/dist/test/commands/hello world.d.ts +2 -0
- package/dist/test/commands/hello world.d.ts.map +1 -0
- package/dist/test/commands/hello world.js +46 -0
- package/dist/test/commands/hello world.js.map +1 -0
- package/dist/test/commands/stuff.d.ts +2 -0
- package/dist/test/commands/stuff.d.ts.map +1 -0
- package/dist/test/commands/stuff.js +22 -0
- package/dist/test/commands/stuff.js.map +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +33 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/publish.d.ts +2 -0
- package/dist/test/publish.d.ts.map +1 -0
- package/dist/test/publish.js +5 -0
- package/dist/test/publish.js.map +1 -0
- package/dist/test/things/test.d.ts +2 -0
- package/dist/test/things/test.d.ts.map +1 -0
- package/dist/test/things/test.js +84 -0
- package/dist/test/things/test.js.map +1 -0
- package/package.json +40 -0
- package/src/DBI.ts +262 -0
- package/src/Events.ts +72 -0
- package/src/data/eventMap.json +234 -0
- package/src/index.ts +7 -0
- package/src/methods/hookEventListeners.ts +38 -0
- package/src/methods/hookInteractionListeners.ts +118 -0
- package/src/methods/publishInteractions.ts +158 -0
- package/src/types/Button.ts +32 -0
- package/src/types/ChatInput/ChatInput.ts +24 -0
- package/src/types/ChatInput/ChatInputOptions.ts +168 -0
- package/src/types/Event.ts +115 -0
- package/src/types/Interaction.ts +69 -0
- package/src/types/Locale.ts +39 -0
- package/src/types/MessageContextMenu.ts +23 -0
- package/src/types/Modal.ts +32 -0
- package/src/types/SelectMenu.ts +32 -0
- package/src/types/UserContextMenu.ts +21 -0
- package/src/utils/MemoryStore.ts +28 -0
- package/src/utils/customId.ts +35 -0
- package/src/utils/permissions.ts +5 -0
- package/src/utils/recursiveImport.ts +15 -0
- package/tsconfig.json +39 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { DBI } from "../DBI";
|
|
2
|
+
import Discord from "discord.js";
|
|
3
|
+
import { parseCustomId } from "../utils/customId";
|
|
4
|
+
|
|
5
|
+
export function hookInteractionListeners(dbi: DBI): () => any {
|
|
6
|
+
async function handle(inter: Discord.Interaction<Discord.CacheType>) {
|
|
7
|
+
|
|
8
|
+
const dbiInter =
|
|
9
|
+
dbi.data.interactions.find(i => {
|
|
10
|
+
let isUsesCustomId = (inter.isButton() || inter.isSelectMenu() || inter.isModalSubmit());
|
|
11
|
+
let parsedId = isUsesCustomId ? parseCustomId(dbi, (inter as any).customId) : null;
|
|
12
|
+
return (
|
|
13
|
+
(
|
|
14
|
+
i.type == "ChatInput"
|
|
15
|
+
&& (inter.isChatInputCommand() || inter.isAutocomplete())
|
|
16
|
+
&& i.name == [inter.commandName, inter.options.getSubcommandGroup(false), inter.options.getSubcommand(false)].filter(i => !!i).join(" ")
|
|
17
|
+
)
|
|
18
|
+
||
|
|
19
|
+
(
|
|
20
|
+
(i.type == "MessageContextMenu" || i.type == "UserContextMenu")
|
|
21
|
+
&& (inter.isMessageContextMenuCommand() || inter.isUserContextMenuCommand())
|
|
22
|
+
&& inter.commandName == i.name
|
|
23
|
+
)
|
|
24
|
+
||
|
|
25
|
+
(
|
|
26
|
+
(i.type == "Button" || i.type == "SelectMenu" || i.type == "Modal")
|
|
27
|
+
&& isUsesCustomId
|
|
28
|
+
&& parsedId.name == i.name
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!dbiInter) return;
|
|
34
|
+
|
|
35
|
+
if (inter.isAutocomplete()) {
|
|
36
|
+
let focussed = inter.options.getFocused(true);
|
|
37
|
+
let option = (dbiInter.options as any[]).find(i => i.name == focussed.name);
|
|
38
|
+
if (option?.onComplete) {
|
|
39
|
+
let response = await option.onComplete({
|
|
40
|
+
value: focussed.value,
|
|
41
|
+
interaction: inter,
|
|
42
|
+
dbi
|
|
43
|
+
});
|
|
44
|
+
await inter.respond(response);
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let userLocaleName = inter.locale.split("-")[0];
|
|
50
|
+
let userLocale = dbi.data.locales.has(userLocaleName) ? dbi.data.locales.get(userLocaleName) : dbi.data.locales.get(dbi.config.defaults.locale);
|
|
51
|
+
|
|
52
|
+
let guildLocaleName = inter.guild ? inter.guild.preferredLocale.split("-")[0] : null;
|
|
53
|
+
let guildLocale = guildLocaleName ? (dbi.data.locales.has(guildLocaleName) ? dbi.data.locales.get(guildLocaleName) : dbi.data.locales.get(dbi.config.defaults.locale)) : null;
|
|
54
|
+
|
|
55
|
+
let locale = {
|
|
56
|
+
user: userLocale,
|
|
57
|
+
guild: guildLocale
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
let data = (inter.isButton() || inter.isSelectMenu() || inter.isModalSubmit()) ? parseCustomId(dbi, inter.customId).data : undefined;
|
|
61
|
+
|
|
62
|
+
let rateLimitKeyMap = {
|
|
63
|
+
"User": `${inter.user.id}`,
|
|
64
|
+
"Channel": `${inter.channelId || "Channel"}`,
|
|
65
|
+
"Guild": `${inter.guildId || "Guild"}`,
|
|
66
|
+
"Member": `${inter.user.id}_${inter.guildId || "Guild"}`,
|
|
67
|
+
"Message": `${(inter as any)?.message?.id}`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const type in rateLimitKeyMap) {
|
|
71
|
+
let key = `RateLimit:${rateLimitKeyMap[type]}`;
|
|
72
|
+
let val = await dbi.config.store.get(key);
|
|
73
|
+
if (val && Date.now() > val.at + val.duration) {
|
|
74
|
+
await dbi.config.store.del(key);
|
|
75
|
+
val = null;
|
|
76
|
+
}
|
|
77
|
+
if (val) {
|
|
78
|
+
dbi.events.trigger("interactionRateLimit", {
|
|
79
|
+
dbi,
|
|
80
|
+
interaction: inter,
|
|
81
|
+
locale,
|
|
82
|
+
data,
|
|
83
|
+
rateLimit: {
|
|
84
|
+
type: key,
|
|
85
|
+
...val
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function setRateLimit(type: string, duration: number) {
|
|
93
|
+
await dbi.config.store.set(`RateLimit:${rateLimitKeyMap[type]}`, { at: Date.now(), duration });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let other = {};
|
|
97
|
+
|
|
98
|
+
if (!(await dbi.events.trigger("beforeInteraction", { dbi, interaction: inter, locale, setRateLimit, data, other }))) return;
|
|
99
|
+
|
|
100
|
+
await dbiInter.onExecute({
|
|
101
|
+
dbi,
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
interaction: inter as any,
|
|
104
|
+
locale,
|
|
105
|
+
setRateLimit,
|
|
106
|
+
data,
|
|
107
|
+
other
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
dbi.events.trigger("afterInteraction", { dbi, interaction: inter, locale, setRateLimit, data, other });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
dbi.client.on("interactionCreate", handle);
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
dbi.client.off("interactionCreate", handle);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { DBIChatInput } from "../types/ChatInput/ChatInput";
|
|
3
|
+
import { REST } from "@discordjs/rest";
|
|
4
|
+
import { Routes, RESTGetAPIUserResult, RESTPutAPIApplicationCommandsJSONBody, ApplicationCommandType, ApplicationCommandOptionType } from "discord-api-types/v9";
|
|
5
|
+
import { reducePermissions } from "../utils/permissions";
|
|
6
|
+
import snakecaseKeys from "snakecase-keys";
|
|
7
|
+
|
|
8
|
+
const PUBLISHABLE_TYPES = ["ChatInput", "UserContextMenu", "MessageContextMenu"];
|
|
9
|
+
|
|
10
|
+
export async function publishInteractions(
|
|
11
|
+
clientToken: string,
|
|
12
|
+
interactions: Discord.Collection<string, DBIChatInput>,
|
|
13
|
+
publishType: "Guild" | "Global",
|
|
14
|
+
guildId?: string
|
|
15
|
+
) {
|
|
16
|
+
interactions = interactions.filter(i => PUBLISHABLE_TYPES.includes(i.type));
|
|
17
|
+
|
|
18
|
+
const rest = new REST({ version: "9" });
|
|
19
|
+
rest.setToken(clientToken);
|
|
20
|
+
|
|
21
|
+
const me: RESTGetAPIUserResult = await rest.get(Routes.user()) as any;
|
|
22
|
+
|
|
23
|
+
const body: RESTPutAPIApplicationCommandsJSONBody =
|
|
24
|
+
interactions.reduce((all, current) => {
|
|
25
|
+
switch (current.type) {
|
|
26
|
+
case "ChatInput": {
|
|
27
|
+
let nameSplitted = current.name.split(" ");
|
|
28
|
+
switch (nameSplitted.length) {
|
|
29
|
+
case 1: {
|
|
30
|
+
all.push({
|
|
31
|
+
type: ApplicationCommandType.ChatInput,
|
|
32
|
+
description: current.description,
|
|
33
|
+
name: nameSplitted[0],
|
|
34
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
35
|
+
dm_permission: current.directMessages,
|
|
36
|
+
options: snakecaseKeys(current.options || [])
|
|
37
|
+
});
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case 2: {
|
|
41
|
+
let baseItem = all.find(i => i.name == current.name.split(" ")[0] && i.type == "ChatInput");
|
|
42
|
+
let option = {
|
|
43
|
+
type: ApplicationCommandOptionType.Subcommand,
|
|
44
|
+
name: nameSplitted[1],
|
|
45
|
+
description: current.description,
|
|
46
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
47
|
+
dm_permission: current.directMessages,
|
|
48
|
+
options: snakecaseKeys(current.options || [])
|
|
49
|
+
};
|
|
50
|
+
if (!baseItem) {
|
|
51
|
+
all.push({
|
|
52
|
+
type: ApplicationCommandType.ChatInput,
|
|
53
|
+
name: nameSplitted[0],
|
|
54
|
+
description: "...",
|
|
55
|
+
options: [
|
|
56
|
+
option
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
baseItem.options.push(option);
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case 3: {
|
|
65
|
+
let level1Item = all.find(i => i.name == current.name.split(" ")[0] && i.type == "ChatInput");
|
|
66
|
+
if (!level1Item) {
|
|
67
|
+
all.push({
|
|
68
|
+
type: ApplicationCommandType.ChatInput,
|
|
69
|
+
name: nameSplitted[0],
|
|
70
|
+
description: "...",
|
|
71
|
+
options: [
|
|
72
|
+
{
|
|
73
|
+
type: ApplicationCommandOptionType.SubcommandGroup,
|
|
74
|
+
name: nameSplitted[1],
|
|
75
|
+
description: "...",
|
|
76
|
+
options: [
|
|
77
|
+
{
|
|
78
|
+
type: ApplicationCommandOptionType.Subcommand,
|
|
79
|
+
name: nameSplitted[2],
|
|
80
|
+
description: current.description,
|
|
81
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
82
|
+
dm_permission: current.directMessages,
|
|
83
|
+
options: snakecaseKeys(current.options || [])
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
let level2Item = level1Item.options.find(i => i.name == current.name.split(" ")[1] && i.type == "ChatInput");
|
|
91
|
+
if (!level2Item) {
|
|
92
|
+
level1Item.options.push({
|
|
93
|
+
type: ApplicationCommandOptionType.SubcommandGroup,
|
|
94
|
+
name: nameSplitted[1],
|
|
95
|
+
description: "...",
|
|
96
|
+
options: [
|
|
97
|
+
{
|
|
98
|
+
type: ApplicationCommandOptionType.Subcommand,
|
|
99
|
+
name: nameSplitted[2],
|
|
100
|
+
description: current.description,
|
|
101
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
102
|
+
dm_permission: current.directMessages,
|
|
103
|
+
options: snakecaseKeys(current.options || [])
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
} else {
|
|
108
|
+
level2Item.options.push({
|
|
109
|
+
type: ApplicationCommandOptionType.Subcommand,
|
|
110
|
+
name: nameSplitted[2],
|
|
111
|
+
description: current.description,
|
|
112
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
113
|
+
dm_permission: current.directMessages,
|
|
114
|
+
options: snakecaseKeys(current.options || [])
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case "MessageContextMenu": {
|
|
124
|
+
all.push({
|
|
125
|
+
type: ApplicationCommandType.Message,
|
|
126
|
+
name: current.name,
|
|
127
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
128
|
+
dm_permission: current.directMessages
|
|
129
|
+
});
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "UserContextMenu": {
|
|
133
|
+
all.push({
|
|
134
|
+
type: ApplicationCommandType.User,
|
|
135
|
+
name: current.name,
|
|
136
|
+
default_member_permissions: reducePermissions(current.defaultMemberPermissions).toString(),
|
|
137
|
+
dm_permission: current.directMessages
|
|
138
|
+
});
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return all;
|
|
144
|
+
}, []);
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
switch (publishType) {
|
|
148
|
+
case "Global": {
|
|
149
|
+
await rest.put(Routes.applicationGuildCommands(me.id, guildId), { body });
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "Guild": {
|
|
153
|
+
await rest.put(Routes.applicationCommands(me.id), { body });
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { DBI } from "../DBI";
|
|
3
|
+
import { DBIBaseInteraction, IDBIBaseExecuteCtx } from "./Interaction";
|
|
4
|
+
import { customIdBuilder } from "../utils/customId";
|
|
5
|
+
|
|
6
|
+
export interface IDBIButtonExecuteCtx extends IDBIBaseExecuteCtx {
|
|
7
|
+
interaction: Discord.ButtonInteraction<Discord.CacheType>;
|
|
8
|
+
data: ({ [key: string]: any, $ref: string, $unRef(): boolean } | string | number)[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type TDBIButtonOmitted = Omit<DBIButton, "type" | "description" | "dbi" | "toJSON">;
|
|
12
|
+
|
|
13
|
+
export class DBIButton extends DBIBaseInteraction {
|
|
14
|
+
constructor(dbi: DBI, args: TDBIButtonOmitted) {
|
|
15
|
+
super(dbi, {
|
|
16
|
+
...(args as any),
|
|
17
|
+
type: "Button",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare options: Omit<Discord.ButtonComponentData, "customId" | "type">;
|
|
22
|
+
|
|
23
|
+
override onExecute(ctx: IDBIButtonExecuteCtx): Promise<any> | any { };
|
|
24
|
+
|
|
25
|
+
toJSON(...customData: (string | number | object)[]): Discord.ButtonComponentData {
|
|
26
|
+
return {
|
|
27
|
+
...this.options,
|
|
28
|
+
customId: customIdBuilder(this.dbi, this.name, customData),
|
|
29
|
+
type: Discord.ComponentType.Button
|
|
30
|
+
} as any;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { DBI } from "../../DBI";
|
|
3
|
+
import { DBIBaseInteraction, IDBIBaseExecuteCtx } from "../Interaction";
|
|
4
|
+
|
|
5
|
+
export interface IDBIChatInputExecuteCtx extends IDBIBaseExecuteCtx {
|
|
6
|
+
interaction: Discord.ChatInputCommandInteraction<Discord.CacheType>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type TDBIChatInputOmitted = Omit<DBIChatInput, "type" | "dbi">;
|
|
10
|
+
|
|
11
|
+
export class DBIChatInput extends DBIBaseInteraction {
|
|
12
|
+
constructor(dbi: DBI, cfg: TDBIChatInputOmitted) {
|
|
13
|
+
super(dbi, {
|
|
14
|
+
...(cfg as any),
|
|
15
|
+
type: "ChatInput",
|
|
16
|
+
name: cfg.name.toLowerCase(),
|
|
17
|
+
options: Array.isArray(cfg.options) ? cfg.options : []
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
directMessages?: boolean;
|
|
21
|
+
defaultMemberPermissions?: Discord.PermissionsString[];
|
|
22
|
+
declare options?: any[];
|
|
23
|
+
override onExecute(ctx: IDBIChatInputExecuteCtx) {}
|
|
24
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { IDBIBaseExecuteCtx } from "../Interaction";
|
|
3
|
+
|
|
4
|
+
type TValueName<T> = { value: T, name: string };
|
|
5
|
+
type TNameDescription = { name: string, description: string, required?: boolean };
|
|
6
|
+
|
|
7
|
+
type TMinMaxLength = { maxLength?: number, minLength?: number };
|
|
8
|
+
type TMinMaxValue = { maxValue?: number, minValue?: number };
|
|
9
|
+
|
|
10
|
+
export interface IDBICompleteCtx extends IDBIBaseExecuteCtx {
|
|
11
|
+
interaction: Discord.AutocompleteInteraction;
|
|
12
|
+
value: string | number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class DBIChatInputOptions {
|
|
16
|
+
static stringAutocomplete(cfg: TNameDescription & TMinMaxLength & { onComplete(ctx: IDBICompleteCtx): Promise<TValueName<string>[]> }) {
|
|
17
|
+
return {
|
|
18
|
+
type: Discord.ApplicationCommandOptionType.String,
|
|
19
|
+
name: cfg.name,
|
|
20
|
+
autocomplete: true,
|
|
21
|
+
onComplete: cfg.onComplete,
|
|
22
|
+
description: cfg.description,
|
|
23
|
+
maxLength: cfg.maxLength,
|
|
24
|
+
minLength: cfg.minLength,
|
|
25
|
+
required: cfg.required
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
static stringChoices(cfg: TNameDescription & TMinMaxLength & { choices: TValueName<string>[] }) {
|
|
29
|
+
return {
|
|
30
|
+
type: Discord.ApplicationCommandOptionType.String,
|
|
31
|
+
name: cfg.name,
|
|
32
|
+
choices: cfg.choices,
|
|
33
|
+
description: cfg.description,
|
|
34
|
+
maxLength: cfg.maxLength,
|
|
35
|
+
minLength: cfg.minLength,
|
|
36
|
+
required: cfg.required
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static string(cfg: TNameDescription & TMinMaxLength) {
|
|
41
|
+
return {
|
|
42
|
+
type: Discord.ApplicationCommandOptionType.String,
|
|
43
|
+
name: cfg.name,
|
|
44
|
+
description: cfg.description,
|
|
45
|
+
maxLength: cfg.maxLength,
|
|
46
|
+
minLength: cfg.minLength,
|
|
47
|
+
required: cfg.required
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static numberAutocomplete(cfg: TNameDescription & TMinMaxValue & { onComplete(ctx: IDBICompleteCtx): Promise<TValueName<number>[]> }) {
|
|
52
|
+
return {
|
|
53
|
+
type: Discord.ApplicationCommandOptionType.Number,
|
|
54
|
+
name: cfg.name,
|
|
55
|
+
autocomplete: true,
|
|
56
|
+
onComplete: cfg.onComplete,
|
|
57
|
+
description: cfg.description,
|
|
58
|
+
maxValue: cfg.maxValue,
|
|
59
|
+
minValue: cfg.minValue,
|
|
60
|
+
required: cfg.required
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static numberChoices(cfg: TNameDescription & TMinMaxValue & { choices: TValueName<number>[] }) {
|
|
65
|
+
return {
|
|
66
|
+
type: Discord.ApplicationCommandOptionType.Number,
|
|
67
|
+
name: cfg.name,
|
|
68
|
+
choices: cfg.choices,
|
|
69
|
+
description: cfg.description,
|
|
70
|
+
maxValue: cfg.maxValue,
|
|
71
|
+
minValue: cfg.minValue,
|
|
72
|
+
required: cfg.required
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static number(cfg: TNameDescription & TMinMaxValue) {
|
|
77
|
+
return {
|
|
78
|
+
type: Discord.ApplicationCommandOptionType.Number,
|
|
79
|
+
name: cfg.name,
|
|
80
|
+
description: cfg.description,
|
|
81
|
+
maxValue: cfg.maxValue,
|
|
82
|
+
minValue: cfg.minValue,
|
|
83
|
+
required: cfg.required
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static integerAutocomplete(cfg: TNameDescription & TMinMaxValue & { onComplete(ctx: IDBICompleteCtx): Promise<TValueName<number>[]> }) {
|
|
88
|
+
return {
|
|
89
|
+
type: Discord.ApplicationCommandOptionType.Integer,
|
|
90
|
+
name: cfg.name,
|
|
91
|
+
autocomplete: true,
|
|
92
|
+
onComplete: cfg.onComplete,
|
|
93
|
+
description: cfg.description,
|
|
94
|
+
maxValue: cfg.maxValue,
|
|
95
|
+
minValue: cfg.minValue,
|
|
96
|
+
required: cfg.required
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static integerChoices(cfg: TNameDescription & TMinMaxValue & { choices: TValueName<number>[] }) {
|
|
101
|
+
return {
|
|
102
|
+
type: Discord.ApplicationCommandOptionType.Integer,
|
|
103
|
+
name: cfg.name,
|
|
104
|
+
choices: cfg.choices,
|
|
105
|
+
description: cfg.description,
|
|
106
|
+
maxValue: cfg.maxValue,
|
|
107
|
+
minValue: cfg.minValue,
|
|
108
|
+
required: cfg.required
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static integer(cfg: TNameDescription & TMinMaxValue) {
|
|
113
|
+
return {
|
|
114
|
+
type: Discord.ApplicationCommandOptionType.Integer,
|
|
115
|
+
name: cfg.name,
|
|
116
|
+
description: cfg.description,
|
|
117
|
+
maxValue: cfg.maxValue,
|
|
118
|
+
minValue: cfg.minValue,
|
|
119
|
+
required: cfg.required
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static boolean(cfg: TNameDescription) {
|
|
124
|
+
return {
|
|
125
|
+
type: Discord.ApplicationCommandOptionType.Boolean,
|
|
126
|
+
name: cfg.name,
|
|
127
|
+
description: cfg.description,
|
|
128
|
+
required: cfg.required
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static attachment(cfg: TNameDescription) {
|
|
133
|
+
return {
|
|
134
|
+
type: Discord.ApplicationCommandOptionType.Attachment,
|
|
135
|
+
name: cfg.name,
|
|
136
|
+
description: cfg.description,
|
|
137
|
+
required: cfg.required
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static channel(cfg: TNameDescription & { channelTypes: Discord.ChannelType[] }) {
|
|
142
|
+
return {
|
|
143
|
+
type: Discord.ApplicationCommandOptionType.Channel,
|
|
144
|
+
name: cfg.name,
|
|
145
|
+
description: cfg.description,
|
|
146
|
+
channelTypes: cfg.channelTypes,
|
|
147
|
+
required: cfg.required
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static mentionable(cfg: TNameDescription) {
|
|
152
|
+
return {
|
|
153
|
+
type: Discord.ApplicationCommandOptionType.Mentionable,
|
|
154
|
+
name: cfg.name,
|
|
155
|
+
description: cfg.description,
|
|
156
|
+
required: cfg.required
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static user(cfg: TNameDescription) {
|
|
161
|
+
return {
|
|
162
|
+
type: Discord.ApplicationCommandOptionType.User,
|
|
163
|
+
name: cfg.name,
|
|
164
|
+
description: cfg.description,
|
|
165
|
+
required: cfg.required
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { DBI } from "../DBI";
|
|
3
|
+
|
|
4
|
+
export interface ClientEvents {
|
|
5
|
+
applicationCommandPermissionsUpdate: { data: Discord.ApplicationCommandPermissionsUpdateData };
|
|
6
|
+
cacheSweep: { message: string };
|
|
7
|
+
channelCreate: { channel: Discord.NonThreadGuildBasedChannel };
|
|
8
|
+
channelDelete: { channel: Discord.DMChannel | Discord.NonThreadGuildBasedChannel };
|
|
9
|
+
channelPinsUpdate: { channel: Discord.TextBasedChannel, date: Date };
|
|
10
|
+
channelUpdate: {
|
|
11
|
+
oldChannel: Discord.DMChannel | Discord.NonThreadGuildBasedChannel,
|
|
12
|
+
newChannel: Discord.DMChannel | Discord.NonThreadGuildBasedChannel,
|
|
13
|
+
};
|
|
14
|
+
debug: { message: string };
|
|
15
|
+
warn: { message: string };
|
|
16
|
+
emojiCreate: { emoji: Discord.GuildEmoji };
|
|
17
|
+
emojiDelete: { emoji: Discord.GuildEmoji };
|
|
18
|
+
emojiUpdate: { oldEmoji: Discord.GuildEmoji, newEmoji: Discord.GuildEmoji };
|
|
19
|
+
error: { error: Error };
|
|
20
|
+
guildBanAdd: { ban: Discord.GuildBan };
|
|
21
|
+
guildBanRemove: { ban: Discord.GuildBan };
|
|
22
|
+
guildCreate: { guild: Discord.Guild };
|
|
23
|
+
guildDelete: { guild: Discord.Guild };
|
|
24
|
+
guildUnavailable: { guild: Discord.Guild };
|
|
25
|
+
guildIntegrationsUpdate: { guild: Discord.Guild };
|
|
26
|
+
guildMemberAdd: { member: Discord.GuildMember };
|
|
27
|
+
guildMemberAvailable: { member: Discord.GuildMember | Discord.PartialGuildMember };
|
|
28
|
+
guildMemberRemove: { member: Discord.GuildMember | Discord.PartialGuildMember };
|
|
29
|
+
guildMembersChunk: {
|
|
30
|
+
members: Discord.Collection<Discord.Snowflake, Discord.GuildMember>,
|
|
31
|
+
guild: Discord.Guild,
|
|
32
|
+
data: { count: number; index: number; nonce: string | undefined },
|
|
33
|
+
};
|
|
34
|
+
guildMemberUpdate: { oldMember: Discord.GuildMember | Discord.PartialGuildMember, newMember: Discord.GuildMember };
|
|
35
|
+
guildUpdate: { oldGuild: Discord.Guild, newGuild: Discord.Guild };
|
|
36
|
+
inviteCreate: { invite: Discord.Invite };
|
|
37
|
+
inviteDelete: { invite: Discord.Invite };
|
|
38
|
+
messageCreate: { message: Discord.Message };
|
|
39
|
+
messageDelete: { message: Discord.Message | Discord.PartialMessage };
|
|
40
|
+
messageReactionRemoveAll: {
|
|
41
|
+
message: Discord.Message | Discord.PartialMessage,
|
|
42
|
+
reactions: Discord.Collection<string | Discord.Snowflake, Discord.MessageReaction>,
|
|
43
|
+
};
|
|
44
|
+
messageReactionRemoveEmoji: { reaction: Discord.MessageReaction | Discord.PartialMessageReaction };
|
|
45
|
+
messageDeleteBulk: { messages: Discord.Collection<Discord.Snowflake, Discord.Message | Discord.PartialMessage>, channel: Discord.TextBasedChannel };
|
|
46
|
+
messageReactionAdd: { reaction: Discord.MessageReaction | Discord.PartialMessageReaction, user: Discord.User | Discord.PartialUser };
|
|
47
|
+
messageReactionRemove: { reaction: Discord.MessageReaction | Discord.PartialMessageReaction, user: Discord.User | Discord.PartialUser };
|
|
48
|
+
messageUpdate: { oldMessage: Discord.Message | Discord.PartialMessage, newMessage: Discord.Message | Discord.PartialMessage };
|
|
49
|
+
presenceUpdate: { oldPresence: Discord.Presence | null, newPresence: Discord.Presence };
|
|
50
|
+
ready: { client: Discord.Client<true> };
|
|
51
|
+
invalidated: {};
|
|
52
|
+
roleCreate: { role: Discord.Role };
|
|
53
|
+
roleDelete: { role: Discord.Role };
|
|
54
|
+
roleUpdate: { oldRole: Discord.Role, newRole: Discord.Role };
|
|
55
|
+
threadCreate: { thread: Discord.AnyThreadChannel, newlyCreated: boolean };
|
|
56
|
+
threadDelete: { thread: Discord.AnyThreadChannel };
|
|
57
|
+
threadListSync: { threads: Discord.Collection<Discord.Snowflake, Discord.AnyThreadChannel>, guild: Discord.Guild };
|
|
58
|
+
threadMemberUpdate: { oldMember: Discord.ThreadMember, newMember: Discord.ThreadMember };
|
|
59
|
+
threadMembersUpdate: {
|
|
60
|
+
addedMembers: Discord.Collection<Discord.Snowflake, Discord.ThreadMember>,
|
|
61
|
+
removedMembers: Discord.Collection<Discord.Snowflake, Discord.ThreadMember | Discord.PartialThreadMember>,
|
|
62
|
+
thread: Discord.AnyThreadChannel,
|
|
63
|
+
};
|
|
64
|
+
threadUpdate: { oldThread: Discord.AnyThreadChannel, newThread: Discord.AnyThreadChannel };
|
|
65
|
+
typingStart: { typing: Discord.Typing };
|
|
66
|
+
userUpdate: { oldUser: Discord.User | Discord.PartialUser, newUser: Discord.User };
|
|
67
|
+
voiceStateUpdate: { oldState: Discord.VoiceState, newState: Discord.VoiceState };
|
|
68
|
+
webhookUpdate: { channel: Discord.TextChannel | Discord.NewsChannel | Discord.VoiceChannel };
|
|
69
|
+
interactionCreate: { interaction: Discord.Interaction };
|
|
70
|
+
shardDisconnect: { closeEvent: Discord.CloseEvent, shardId: number };
|
|
71
|
+
shardError: { error: Error, shardId: number };
|
|
72
|
+
shardReady: { shardId: number, unavailableGuilds: Set<Discord.Snowflake> | undefined };
|
|
73
|
+
shardReconnecting: { shardId: number };
|
|
74
|
+
shardResume: { shardId: number, replayedEvents: number };
|
|
75
|
+
stageInstanceCreate: { stageInstance: Discord.StageInstance };
|
|
76
|
+
stageInstanceUpdate: { oldStageInstance: Discord.StageInstance | null, newStageInstance: Discord.StageInstance };
|
|
77
|
+
stageInstanceDelete: { stageInstance: Discord.StageInstance };
|
|
78
|
+
stickerCreate: { sticker: Discord.Sticker };
|
|
79
|
+
stickerDelete: { sticker: Discord.Sticker };
|
|
80
|
+
stickerUpdate: { oldSticker: Discord.Sticker, newSticker: Discord.Sticker };
|
|
81
|
+
guildScheduledEventCreate: { guildScheduledEvent: Discord.GuildScheduledEvent };
|
|
82
|
+
guildScheduledEventUpdate: {
|
|
83
|
+
oldGuildScheduledEvent: Discord.GuildScheduledEvent | null,
|
|
84
|
+
newGuildScheduledEvent: Discord.GuildScheduledEvent,
|
|
85
|
+
};
|
|
86
|
+
guildScheduledEventDelete: { guildScheduledEvent: Discord.GuildScheduledEvent };
|
|
87
|
+
guildScheduledEventUserAdd: { guildScheduledEvent: Discord.GuildScheduledEvent, user: Discord.User };
|
|
88
|
+
guildScheduledEventUserRemove: { guildScheduledEvent: Discord.GuildScheduledEvent, user: Discord.User };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type DBIEventCombinations = {
|
|
92
|
+
[K in keyof ClientEvents]: {
|
|
93
|
+
name: K,
|
|
94
|
+
onExecute: (ctx: ClientEvents[K] & { other: Record<string, any> }) => Promise<any> | any
|
|
95
|
+
}
|
|
96
|
+
}[keyof ClientEvents];
|
|
97
|
+
|
|
98
|
+
export type TDBIEventOmitted = Omit<DBIEvent, "type" | "name" | "onExecute" | "client" | "dbi"> & DBIEventCombinations;
|
|
99
|
+
|
|
100
|
+
export class DBIEvent {
|
|
101
|
+
readonly type: "Event";
|
|
102
|
+
other?: Record<string, any>;
|
|
103
|
+
id?: string;
|
|
104
|
+
name: string;
|
|
105
|
+
onExecute: (...args: any[]) => any;
|
|
106
|
+
dbi: DBI;
|
|
107
|
+
constructor(dbi: DBI, cfg: TDBIEventOmitted) {
|
|
108
|
+
this.dbi = dbi;
|
|
109
|
+
this.type = "Event";
|
|
110
|
+
this.id = cfg.id;
|
|
111
|
+
this.other = cfg.other;
|
|
112
|
+
this.name = cfg.name;
|
|
113
|
+
this.onExecute = cfg.onExecute;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Discord from "discord.js";
|
|
2
|
+
import { DBI } from "../DBI";
|
|
3
|
+
import { DBILocale } from "./Locale";
|
|
4
|
+
|
|
5
|
+
export interface IDBIBaseExecuteCtx {
|
|
6
|
+
interaction:
|
|
7
|
+
| Discord.ChatInputCommandInteraction
|
|
8
|
+
| Discord.UserContextMenuCommandInteraction
|
|
9
|
+
| Discord.MessageContextMenuCommandInteraction
|
|
10
|
+
| Discord.ModalSubmitInteraction
|
|
11
|
+
| Discord.AutocompleteInteraction
|
|
12
|
+
| Discord.SelectMenuInteraction
|
|
13
|
+
| Discord.ButtonInteraction;
|
|
14
|
+
locale: {
|
|
15
|
+
user: DBILocale,
|
|
16
|
+
guild?: DBILocale
|
|
17
|
+
}
|
|
18
|
+
dbi: DBI;
|
|
19
|
+
setRateLimit(type: TDBIRateLimitTypes, duration: number): Promise<any>;
|
|
20
|
+
other: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type TDBIInteractionTypes =
|
|
24
|
+
| "ChatInput"
|
|
25
|
+
| "UserContextMenu"
|
|
26
|
+
| "MessageContextMenu"
|
|
27
|
+
| "Modal"
|
|
28
|
+
| "Autocomplete"
|
|
29
|
+
| "SelectMenu"
|
|
30
|
+
| "Button";
|
|
31
|
+
|
|
32
|
+
export type TDBIRateLimitTypes =
|
|
33
|
+
| "User"
|
|
34
|
+
| "Channel"
|
|
35
|
+
| "Guild"
|
|
36
|
+
| "Member"
|
|
37
|
+
| "Message";
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export type DBIRateLimit = {
|
|
41
|
+
type: TDBIRateLimitTypes;
|
|
42
|
+
/**
|
|
43
|
+
* Duration in milliseconds.
|
|
44
|
+
*/
|
|
45
|
+
duration: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class DBIBaseInteraction {
|
|
49
|
+
constructor(dbi: DBI, cfg: Omit<DBIBaseInteraction, "dbi">) {
|
|
50
|
+
this.dbi = dbi;
|
|
51
|
+
this.name = cfg.name;
|
|
52
|
+
this.description = cfg.description;
|
|
53
|
+
this.onExecute = cfg.onExecute;
|
|
54
|
+
this.type = cfg.type;
|
|
55
|
+
this.options = cfg.options;
|
|
56
|
+
this.other = cfg.other;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
dbi: DBI;
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
readonly type: TDBIInteractionTypes;
|
|
63
|
+
options?: any | any[];
|
|
64
|
+
other?: Record<string, any>;
|
|
65
|
+
rateLimits?: DBIRateLimit[];
|
|
66
|
+
onExecute(ctx: IDBIBaseExecuteCtx): Promise<any> | any {
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
}
|