@stelliajs/framework 1.2.3 → 1.3.0-dev-2
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/README.md +7 -7
- package/dist/client/StelliaClient.d.ts +5 -4
- package/dist/client/StelliaClient.js +8 -4
- package/dist/client/StelliaUtils.d.ts +3 -1
- package/dist/client/StelliaUtils.js +90 -52
- package/dist/managers/EventManager.d.ts +5 -0
- package/dist/managers/EventManager.js +59 -25
- package/dist/structures/Event.d.ts +21 -11
- package/dist/structures/Interaction.d.ts +46 -21
- package/dist/typescript/types.d.ts +20 -3
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +15 -0
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ const client = new StelliaClient({
|
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
environment: {
|
|
88
|
-
|
|
88
|
+
areGuildsConfigurationEnabled: true
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
|
|
@@ -98,14 +98,14 @@ await client.connect(process.env.TOKEN);
|
|
|
98
98
|
```js
|
|
99
99
|
import { type StelliaClient, type EventStructure } from "@stelliajs/framework";
|
|
100
100
|
import { Events } from "discord.js";
|
|
101
|
-
import { type
|
|
101
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
102
102
|
|
|
103
103
|
export default {
|
|
104
104
|
data: {
|
|
105
105
|
name: Events.ClientReady,
|
|
106
106
|
once: true
|
|
107
107
|
},
|
|
108
|
-
async execute(client: StelliaClient<true>, environment:
|
|
108
|
+
async execute(client: StelliaClient<true>, environment: CustomGuildsConfiguration) { // <true> ensures that the client is Ready
|
|
109
109
|
console.log(`Logged in as ${client.user.tag}`);
|
|
110
110
|
await client.initializeCommands(); // Used to initialise registered commands
|
|
111
111
|
}
|
|
@@ -116,14 +116,14 @@ export default {
|
|
|
116
116
|
```js
|
|
117
117
|
import { type StelliaClient, type EventStructure } from "@stelliajs/framework";
|
|
118
118
|
import { Events, type Interaction } from "discord.js";
|
|
119
|
-
import { type
|
|
119
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
120
120
|
|
|
121
121
|
export default {
|
|
122
122
|
data: {
|
|
123
123
|
name: Events.InteractionCreate,
|
|
124
124
|
once: false
|
|
125
125
|
},
|
|
126
|
-
async execute(client: StelliaClient<true>, environment:
|
|
126
|
+
async execute(client: StelliaClient<true>, environment: CustomGuildsConfiguration, interaction: Interaction) {
|
|
127
127
|
if (interaction.inCachedGuild()) {
|
|
128
128
|
await client.handleInteraction(interaction); // Automatic interaction handling
|
|
129
129
|
}
|
|
@@ -136,12 +136,12 @@ export default {
|
|
|
136
136
|
```js
|
|
137
137
|
import { type CommandStructure, ephemeralFollowUpResponse, type StelliaClient } from "@stelliajs/framework";
|
|
138
138
|
import { type ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
|
139
|
-
import { type
|
|
139
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
140
140
|
|
|
141
141
|
export default {
|
|
142
142
|
data: new SlashCommandBuilder()
|
|
143
143
|
.setName("ping"),
|
|
144
|
-
async execute(client: StelliaClient, environment:
|
|
144
|
+
async execute(client: StelliaClient, environment: CustomGuildsConfiguration, interaction: ChatInputCommandInteraction<"cached">) { // All interactions are cached
|
|
145
145
|
await ephemeralFollowUpResponse(interaction, "Pong!", true); // Response is ephemeral and deleted after 60 seconds
|
|
146
146
|
}
|
|
147
147
|
} as CommandStructure;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { Client, type ClientOptions, type Interaction } from "discord.js";
|
|
2
2
|
import { type ManagerOptions } from "../managers/index.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type ClientEnvironment, type GuildConfigurationType, type GuildsConfiguration, type Managers } from "../typescript/index.js";
|
|
4
4
|
export declare class StelliaClient<Ready extends boolean = boolean> extends Client<Ready> {
|
|
5
5
|
private readonly utils;
|
|
6
6
|
readonly managers: Managers;
|
|
7
|
-
readonly environment:
|
|
7
|
+
readonly environment: ClientEnvironment;
|
|
8
8
|
constructor(clientOptions: ClientOptions, stelliaOptions?: StelliaOptions);
|
|
9
9
|
connect: (token: string) => Promise<void>;
|
|
10
10
|
initializeCommands: () => Promise<void>;
|
|
11
|
-
|
|
11
|
+
getGuildsConfiguration: <CustomGuildsConfiguration extends GuildsConfiguration>() => Promise<CustomGuildsConfiguration>;
|
|
12
|
+
getGuildConfiguration: (guildId: string) => GuildConfigurationType;
|
|
12
13
|
handleInteraction: (interaction: Interaction<"cached">) => Promise<void>;
|
|
13
14
|
private areManagersLoaded;
|
|
14
15
|
private static convertFilePathToProduction;
|
|
@@ -23,6 +24,6 @@ interface StelliaOptions {
|
|
|
23
24
|
selectMenus?: ManagerOptions;
|
|
24
25
|
modals?: ManagerOptions;
|
|
25
26
|
};
|
|
26
|
-
environment?:
|
|
27
|
+
environment?: ClientEnvironment;
|
|
27
28
|
}
|
|
28
29
|
export {};
|
|
@@ -4,6 +4,7 @@ import { StelliaUtils } from "./index.js";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import * as fs from "node:fs";
|
|
6
6
|
import { pathToFileURL } from "url";
|
|
7
|
+
import { logger } from "../utils/logger.js";
|
|
7
8
|
export class StelliaClient extends Client {
|
|
8
9
|
utils;
|
|
9
10
|
managers = {};
|
|
@@ -36,24 +37,24 @@ export class StelliaClient extends Client {
|
|
|
36
37
|
}
|
|
37
38
|
this.utils = new StelliaUtils(this);
|
|
38
39
|
process.on("unhandledRejection", (error) => {
|
|
39
|
-
|
|
40
|
+
logger.error(`Unhandled promise rejection: ${error}`);
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
43
|
connect = async (token) => {
|
|
43
44
|
if (!this.areManagersLoaded()) {
|
|
44
45
|
setTimeout(() => {
|
|
45
|
-
|
|
46
|
+
logger.warn("Managers are not loaded yet, retrying in 500ms...");
|
|
46
47
|
this.connect(token);
|
|
47
48
|
}, 500);
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
+
logger.success("Managers are loaded, connecting to Discord...");
|
|
51
52
|
await this.login(token);
|
|
52
53
|
};
|
|
53
54
|
initializeCommands = async () => {
|
|
54
55
|
await this.utils.initializeCommands();
|
|
55
56
|
};
|
|
56
|
-
|
|
57
|
+
getGuildsConfiguration = async () => {
|
|
57
58
|
const chosenEnvironment = process.argv.find(arg => arg.startsWith("--config"))?.split("=")[1];
|
|
58
59
|
if (!chosenEnvironment) {
|
|
59
60
|
throw new Error("Environment not provided");
|
|
@@ -82,6 +83,9 @@ export class StelliaClient extends Client {
|
|
|
82
83
|
});
|
|
83
84
|
});
|
|
84
85
|
};
|
|
86
|
+
getGuildConfiguration = (guildId) => {
|
|
87
|
+
return this.utils.getGuildConfiguration(guildId);
|
|
88
|
+
};
|
|
85
89
|
handleInteraction = async (interaction) => {
|
|
86
90
|
await this.utils.handleInteraction(interaction);
|
|
87
91
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type StelliaClient } from "./index.js";
|
|
2
2
|
import { type Interaction } from "discord.js";
|
|
3
|
+
import { type GuildConfiguration } from "../typescript/index.js";
|
|
3
4
|
export declare class StelliaUtils {
|
|
4
5
|
readonly client: StelliaClient;
|
|
5
6
|
private readonly interactionHandlers;
|
|
6
|
-
private
|
|
7
|
+
private guildsConfiguration;
|
|
7
8
|
constructor(client: StelliaClient);
|
|
8
9
|
initializeCommands: () => Promise<void>;
|
|
10
|
+
getGuildConfiguration: (guildId: string) => GuildConfiguration | undefined;
|
|
9
11
|
handleInteraction: (interaction: Interaction<"cached">) => Promise<void>;
|
|
10
12
|
private handleAutoCompleteInteraction;
|
|
11
13
|
private handleButtonInteraction;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ApplicationCommandType, REST, Routes } from "discord.js";
|
|
2
2
|
import { DISCORD_API_VERSION } from "../constants/index.js";
|
|
3
3
|
import { InteractionType } from "../typescript/index.js";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
4
5
|
export class StelliaUtils {
|
|
5
6
|
client;
|
|
6
7
|
interactionHandlers;
|
|
7
|
-
|
|
8
|
+
guildsConfiguration;
|
|
8
9
|
constructor(client) {
|
|
9
10
|
this.client = client;
|
|
10
11
|
this.interactionHandlers = new Map([
|
|
@@ -15,13 +16,13 @@ export class StelliaUtils {
|
|
|
15
16
|
[InteractionType.ModalSubmit, this.handleModalInteraction],
|
|
16
17
|
[InteractionType.SelectMenu, this.handleSelectMenuInteraction]
|
|
17
18
|
]);
|
|
18
|
-
if (this.client.environment.
|
|
19
|
-
this.client.
|
|
20
|
-
.then((
|
|
21
|
-
this.
|
|
22
|
-
|
|
19
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
20
|
+
this.client.getGuildsConfiguration()
|
|
21
|
+
.then((guildsConfiguration) => {
|
|
22
|
+
this.guildsConfiguration = guildsConfiguration;
|
|
23
|
+
logger.success("Guilds configuration loaded successfully for interactions");
|
|
23
24
|
})
|
|
24
|
-
.catch((error) =>
|
|
25
|
+
.catch((error) => logger.error(`Error while loading guilds configuration: ${error}`));
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
initializeCommands = async () => {
|
|
@@ -32,12 +33,21 @@ export class StelliaUtils {
|
|
|
32
33
|
const rest = new REST({ version: DISCORD_API_VERSION }).setToken(this.client.token);
|
|
33
34
|
try {
|
|
34
35
|
await rest.put(Routes.applicationCommands(this.client.user.id), { body: applicationCommands });
|
|
36
|
+
logger.success("Application commands registered successfully");
|
|
35
37
|
}
|
|
36
38
|
catch (error) {
|
|
37
|
-
|
|
39
|
+
logger.error(`Error while registering application commands: ${error}`);
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
};
|
|
43
|
+
getGuildConfiguration = (guildId) => {
|
|
44
|
+
if (!this.client.environment.areGuildsConfigurationEnabled || !this.guildsConfiguration) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const { guilds, ...general } = this.guildsConfiguration;
|
|
48
|
+
const guildConfiguration = guilds[guildId];
|
|
49
|
+
return { general, guild: guildConfiguration };
|
|
50
|
+
};
|
|
41
51
|
handleInteraction = async (interaction) => {
|
|
42
52
|
if (interaction.inCachedGuild()) {
|
|
43
53
|
const interactionType = this.getInteractionType(interaction);
|
|
@@ -52,21 +62,25 @@ export class StelliaUtils {
|
|
|
52
62
|
};
|
|
53
63
|
handleAutoCompleteInteraction = async (interaction) => {
|
|
54
64
|
try {
|
|
55
|
-
const
|
|
65
|
+
const autoCompleteInteraction = interaction;
|
|
56
66
|
const autoCompleteManager = this.client.managers.autoCompletes;
|
|
57
67
|
if (!autoCompleteManager)
|
|
58
68
|
return;
|
|
59
|
-
const autoComplete = autoCompleteManager.getByCustomId(
|
|
69
|
+
const autoComplete = autoCompleteManager.getByCustomId(autoCompleteInteraction.commandName);
|
|
60
70
|
if (!autoComplete)
|
|
61
71
|
return;
|
|
62
|
-
if (this.client.environment.
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
73
|
+
const autoCompleteWithGuildConfiguration = autoComplete;
|
|
74
|
+
const guildConfiguration = this.getGuildConfiguration(autoCompleteInteraction.guildId);
|
|
75
|
+
await autoCompleteWithGuildConfiguration.execute(this.client, guildConfiguration, autoCompleteInteraction);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const autoCompleteWithoutGuildConfiguration = autoComplete;
|
|
79
|
+
await autoCompleteWithoutGuildConfiguration.execute(this.client, autoCompleteInteraction);
|
|
65
80
|
}
|
|
66
|
-
await autoComplete.execute(this.client, interactionAutoComplete);
|
|
67
81
|
}
|
|
68
82
|
catch (error) {
|
|
69
|
-
|
|
83
|
+
logger.error(`Error while handling autocomplete interaction: ${error}`);
|
|
70
84
|
}
|
|
71
85
|
};
|
|
72
86
|
handleButtonInteraction = async (interaction) => {
|
|
@@ -78,33 +92,41 @@ export class StelliaUtils {
|
|
|
78
92
|
const button = buttonManager.getByCustomId(buttonInteraction.customId) || buttonManager.getByRegex(buttonInteraction.customId);
|
|
79
93
|
if (!button)
|
|
80
94
|
return;
|
|
81
|
-
if (this.client.environment.
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
96
|
+
const buttonWithGuildConfiguration = button;
|
|
97
|
+
const guildConfiguration = this.getGuildConfiguration(buttonInteraction.guildId);
|
|
98
|
+
await buttonWithGuildConfiguration.execute(this.client, guildConfiguration, buttonInteraction);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const buttonWithoutGuildConfiguration = button;
|
|
102
|
+
await buttonWithoutGuildConfiguration.execute(this.client, buttonInteraction);
|
|
84
103
|
}
|
|
85
|
-
await button.execute(this.client, buttonInteraction);
|
|
86
104
|
}
|
|
87
105
|
catch (error) {
|
|
88
|
-
|
|
106
|
+
logger.error(`Error while handling button interaction: ${error}`);
|
|
89
107
|
}
|
|
90
108
|
};
|
|
91
109
|
handleCommandInteraction = async (interaction) => {
|
|
92
110
|
try {
|
|
93
|
-
const
|
|
111
|
+
const commandInteraction = interaction;
|
|
94
112
|
const commandManager = this.client.managers.commands;
|
|
95
113
|
if (!commandManager)
|
|
96
114
|
return;
|
|
97
|
-
|
|
115
|
+
let command = commandManager.getByCustomId(commandInteraction.commandName);
|
|
98
116
|
if (!command)
|
|
99
117
|
return;
|
|
100
|
-
if (this.client.environment.
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
119
|
+
const commandWithGuildConfiguration = command;
|
|
120
|
+
const guildConfiguration = this.getGuildConfiguration(commandInteraction.guildId);
|
|
121
|
+
await commandWithGuildConfiguration.execute(this.client, guildConfiguration, commandInteraction);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const commandWithoutGuildConfiguration = command;
|
|
125
|
+
await commandWithoutGuildConfiguration.execute(this.client, commandInteraction);
|
|
103
126
|
}
|
|
104
|
-
await command.execute(this.client, interactionCommand);
|
|
105
127
|
}
|
|
106
128
|
catch (error) {
|
|
107
|
-
|
|
129
|
+
logger.error(`Error while handling command interaction: ${error}`);
|
|
108
130
|
}
|
|
109
131
|
};
|
|
110
132
|
handleContextMenuInteraction = async (interaction) => {
|
|
@@ -120,45 +142,53 @@ export class StelliaUtils {
|
|
|
120
142
|
}
|
|
121
143
|
}
|
|
122
144
|
catch (error) {
|
|
123
|
-
|
|
145
|
+
logger.error(`Error while handling context menu interaction: ${error}`);
|
|
124
146
|
}
|
|
125
147
|
};
|
|
126
148
|
handleModalInteraction = async (interaction) => {
|
|
127
149
|
try {
|
|
128
|
-
const
|
|
150
|
+
const modalInteraction = interaction;
|
|
129
151
|
const modalManager = this.client.managers.modals;
|
|
130
152
|
if (!modalManager)
|
|
131
153
|
return;
|
|
132
|
-
const modal = modalManager.getByCustomId(
|
|
154
|
+
const modal = modalManager.getByCustomId(modalInteraction.customId) || modalManager.getByRegex(modalInteraction.customId);
|
|
133
155
|
if (!modal)
|
|
134
156
|
return;
|
|
135
|
-
if (this.client.environment.
|
|
136
|
-
|
|
137
|
-
|
|
157
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
158
|
+
const modalWithGuildConfiguration = modal;
|
|
159
|
+
const guildConfiguration = this.getGuildConfiguration(modalInteraction.guildId);
|
|
160
|
+
await modalWithGuildConfiguration.execute(this.client, guildConfiguration, modalInteraction);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const modalWithoutGuildConfiguration = modal;
|
|
164
|
+
await modalWithoutGuildConfiguration.execute(this.client, modalInteraction);
|
|
138
165
|
}
|
|
139
|
-
await modal.execute(this.client, interactionModal);
|
|
140
166
|
}
|
|
141
167
|
catch (error) {
|
|
142
|
-
|
|
168
|
+
logger.error(`Error while handling modal interaction: ${error}`);
|
|
143
169
|
}
|
|
144
170
|
};
|
|
145
171
|
handleSelectMenuInteraction = async (interaction) => {
|
|
146
172
|
try {
|
|
147
|
-
const
|
|
173
|
+
const selectMenuInteraction = interaction;
|
|
148
174
|
const selectMenuManager = this.client.managers.selectMenus;
|
|
149
175
|
if (!selectMenuManager)
|
|
150
176
|
return;
|
|
151
|
-
const selectMenu = selectMenuManager.getByCustomId(
|
|
177
|
+
const selectMenu = selectMenuManager.getByCustomId(selectMenuInteraction.customId) || selectMenuManager.getByRegex(selectMenuInteraction.customId);
|
|
152
178
|
if (!selectMenu)
|
|
153
179
|
return;
|
|
154
|
-
if (this.client.environment.
|
|
155
|
-
|
|
156
|
-
|
|
180
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
181
|
+
const selectMenuWithGuildConfiguration = selectMenu;
|
|
182
|
+
const guildConfiguration = this.getGuildConfiguration(selectMenuInteraction.guildId);
|
|
183
|
+
await selectMenuWithGuildConfiguration.execute(this.client, guildConfiguration, selectMenuInteraction);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const modalWithoutGuildConfiguration = selectMenu;
|
|
187
|
+
await modalWithoutGuildConfiguration.execute(this.client, selectMenuInteraction);
|
|
157
188
|
}
|
|
158
|
-
await selectMenu.execute(this.client, interactionSelectMenu);
|
|
159
189
|
}
|
|
160
190
|
catch (error) {
|
|
161
|
-
|
|
191
|
+
logger.error(`Error while handling select menu interaction: ${error}`);
|
|
162
192
|
}
|
|
163
193
|
};
|
|
164
194
|
handleMessageContextMenuInteraction = async (interaction) => {
|
|
@@ -169,14 +199,18 @@ export class StelliaUtils {
|
|
|
169
199
|
const messageContextMenu = contextMenuManager.getByCustomId(interaction.commandName);
|
|
170
200
|
if (!messageContextMenu)
|
|
171
201
|
return;
|
|
172
|
-
if (this.client.environment.
|
|
173
|
-
|
|
174
|
-
|
|
202
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
203
|
+
const messageContextMenuWithGuildConfiguration = messageContextMenu;
|
|
204
|
+
const guildConfiguration = this.getGuildConfiguration(interaction.guildId);
|
|
205
|
+
await messageContextMenuWithGuildConfiguration.execute(this.client, guildConfiguration, interaction);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const messageContextMenuWithoutGuildConfiguration = messageContextMenu;
|
|
209
|
+
await messageContextMenuWithoutGuildConfiguration.execute(this.client, interaction);
|
|
175
210
|
}
|
|
176
|
-
await messageContextMenu.execute(this.client, interaction);
|
|
177
211
|
}
|
|
178
212
|
catch (error) {
|
|
179
|
-
|
|
213
|
+
logger.error(`Error while handling message context menu interaction: ${error}`);
|
|
180
214
|
}
|
|
181
215
|
};
|
|
182
216
|
handleUserContextMenuInteraction = async (interaction) => {
|
|
@@ -187,14 +221,18 @@ export class StelliaUtils {
|
|
|
187
221
|
const userContextMenu = contextMenuManager.getByCustomId(interaction.commandName);
|
|
188
222
|
if (!userContextMenu)
|
|
189
223
|
return;
|
|
190
|
-
if (this.client.environment.
|
|
191
|
-
|
|
192
|
-
|
|
224
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
225
|
+
const userContextMenuWithGuildConfiguration = userContextMenu;
|
|
226
|
+
const guildConfiguration = this.getGuildConfiguration(interaction.guildId);
|
|
227
|
+
await userContextMenuWithGuildConfiguration.execute(this.client, guildConfiguration, interaction);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
const userContextMenuWithoutGuildConfiguration = userContextMenu;
|
|
231
|
+
await userContextMenuWithoutGuildConfiguration.execute(this.client, interaction);
|
|
193
232
|
}
|
|
194
|
-
await userContextMenu.execute(this.client, interaction);
|
|
195
233
|
}
|
|
196
234
|
catch (error) {
|
|
197
|
-
|
|
235
|
+
logger.error(`Error while handling user context menu interaction: ${error}`);
|
|
198
236
|
}
|
|
199
237
|
};
|
|
200
238
|
getInteractionType(interaction) {
|
|
@@ -4,9 +4,14 @@ import { BaseManager } from "./index.js";
|
|
|
4
4
|
import { type StructureCustomId, type InteractionCustomId } from "../typescript/index.js";
|
|
5
5
|
export declare class EventManager extends BaseManager {
|
|
6
6
|
private interactions;
|
|
7
|
+
private guildsConfiguration;
|
|
7
8
|
constructor(client: StelliaClient, directoryPath: string);
|
|
8
9
|
loadData(): Promise<void>;
|
|
9
10
|
getByCustomId<EventStructure>(id: InteractionCustomId): EventStructure | undefined;
|
|
10
11
|
getByRegex<EventStructure>(id: InteractionCustomId): EventStructure | undefined;
|
|
11
12
|
getAll<EventStructure>(): Collection<StructureCustomId, EventStructure>;
|
|
13
|
+
private loadEventWithGuildConfiguration;
|
|
14
|
+
private eventHandler;
|
|
15
|
+
private loadEventWithoutGuildConfiguration;
|
|
16
|
+
private getGuildConfiguration;
|
|
12
17
|
}
|
|
@@ -1,43 +1,33 @@
|
|
|
1
1
|
import { Collection, Events } from "discord.js";
|
|
2
2
|
import { BaseManager } from "./index.js";
|
|
3
3
|
import { requiredFiles } from "../utils/index.js";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
4
5
|
export class EventManager extends BaseManager {
|
|
5
6
|
interactions = new Collection();
|
|
7
|
+
guildsConfiguration;
|
|
6
8
|
constructor(client, directoryPath) {
|
|
7
9
|
super(client, directoryPath);
|
|
10
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
11
|
+
this.client.getGuildsConfiguration()
|
|
12
|
+
.then((guildsConfiguration) => {
|
|
13
|
+
this.guildsConfiguration = guildsConfiguration;
|
|
14
|
+
logger.success("Guilds configuration loaded successfully for event manager");
|
|
15
|
+
})
|
|
16
|
+
.catch((error) => logger.error(`Error while loading guilds configuration: ${error}`));
|
|
17
|
+
}
|
|
8
18
|
}
|
|
9
19
|
async loadData() {
|
|
10
20
|
const events = await requiredFiles(this.directoryPath);
|
|
11
21
|
this.interactions = events;
|
|
12
|
-
for (const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const environment = await this.client.getEnvironment();
|
|
16
|
-
if (name == Events.ClientReady) {
|
|
17
|
-
this.client.once(name, () => event.execute(this.client, environment));
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (once) {
|
|
21
|
-
this.client.once(name, (...args) => event.execute(this.client, environment, ...args));
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
this.client.on(name, (...args) => event.execute(this.client, environment, ...args));
|
|
25
|
-
}
|
|
22
|
+
for (const eventStructure of this.interactions.values()) {
|
|
23
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
24
|
+
await this.loadEventWithGuildConfiguration(eventStructure);
|
|
26
25
|
}
|
|
27
26
|
else {
|
|
28
|
-
|
|
29
|
-
this.client.once(name, () => event.execute(this.client));
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
if (once) {
|
|
33
|
-
this.client.once(name, (...args) => event.execute(this.client, ...args));
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
this.client.on(name, (...args) => event.execute(this.client, ...args));
|
|
37
|
-
}
|
|
27
|
+
await this.loadEventWithoutGuildConfiguration(eventStructure);
|
|
38
28
|
}
|
|
39
29
|
}
|
|
40
|
-
this.client.on(Events.Error, (error) =>
|
|
30
|
+
this.client.on(Events.Error, (error) => logger.error(`Client error: ${error}`));
|
|
41
31
|
this.setManagerLoaded();
|
|
42
32
|
}
|
|
43
33
|
getByCustomId(id) {
|
|
@@ -51,4 +41,48 @@ export class EventManager extends BaseManager {
|
|
|
51
41
|
const events = this.interactions;
|
|
52
42
|
return events;
|
|
53
43
|
}
|
|
44
|
+
async loadEventWithGuildConfiguration(eventStructure) {
|
|
45
|
+
const { name, once } = eventStructure.data;
|
|
46
|
+
const event = eventStructure;
|
|
47
|
+
if (once) {
|
|
48
|
+
this.client.once(name, (...args) => this.eventHandler(event, ...args));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.client.on(name, (...args) => this.eventHandler(event, ...args));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
eventHandler = (event, ...args) => {
|
|
55
|
+
const mainArgument = args[0];
|
|
56
|
+
if (!mainArgument) {
|
|
57
|
+
const eventStructure = event;
|
|
58
|
+
return eventStructure.execute(this.client, this.guildsConfiguration);
|
|
59
|
+
}
|
|
60
|
+
const guildConfiguration = this.getGuildConfiguration(mainArgument);
|
|
61
|
+
if (guildConfiguration) {
|
|
62
|
+
const eventStructure = event;
|
|
63
|
+
return eventStructure.execute(this.client, guildConfiguration, ...args);
|
|
64
|
+
}
|
|
65
|
+
logger.warn(`No guild configuration found for event ${event.data.name} with main argument ${mainArgument}`);
|
|
66
|
+
};
|
|
67
|
+
async loadEventWithoutGuildConfiguration(eventStructure) {
|
|
68
|
+
const { name, once } = eventStructure.data;
|
|
69
|
+
const event = eventStructure;
|
|
70
|
+
if (once) {
|
|
71
|
+
this.client.once(name, (...args) => event.execute(this.client, ...args));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.client.on(name, (...args) => event.execute(this.client, ...args));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
getGuildConfiguration(mainArgument) {
|
|
78
|
+
if (mainArgument && typeof mainArgument === "object") {
|
|
79
|
+
if ("guildId" in mainArgument && mainArgument.guildId) {
|
|
80
|
+
return this.client.getGuildConfiguration(mainArgument.guildId);
|
|
81
|
+
}
|
|
82
|
+
if ("guild" in mainArgument && mainArgument.guild) {
|
|
83
|
+
return this.client.getGuildConfiguration(mainArgument.guild.id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
54
88
|
}
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { type Awaitable, type ClientEvents } from "discord.js";
|
|
2
2
|
import { type StelliaClient } from "../client/index.js";
|
|
3
|
-
import type
|
|
4
|
-
export interface
|
|
5
|
-
|
|
6
|
-
name: Event;
|
|
7
|
-
once: boolean;
|
|
8
|
-
};
|
|
9
|
-
execute(client: StelliaClient): Awaitable<unknown>;
|
|
10
|
-
execute(...args: ClientEvents[Event]): Awaitable<unknown>;
|
|
11
|
-
execute(client: StelliaClient, ...args: ClientEvents[Event]): Awaitable<unknown>;
|
|
12
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment): Awaitable<unknown>;
|
|
13
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, ...args: ClientEvents[Event]): Awaitable<unknown>;
|
|
3
|
+
import { type GuildConfigurationType, type GuildsConfiguration } from "../typescript/types.js";
|
|
4
|
+
export interface EventStructureWithGuildConfiguration extends EventInteractionStructure {
|
|
5
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, ...args: ClientEventsArgs): Awaitable<unknown>;
|
|
14
6
|
}
|
|
7
|
+
export interface EventStructureWithAllGuildsConfiguration extends EventInteractionStructure {
|
|
8
|
+
execute(client: StelliaClient, guildsConfiguration: GuildsConfiguration, ...args: ClientEventsArgs): Awaitable<unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface EventStructureWithoutGuildConfiguration extends EventInteractionStructure {
|
|
11
|
+
execute(client: StelliaClient, ...args: ClientEventsArgs): Awaitable<unknown>;
|
|
12
|
+
}
|
|
13
|
+
export type EventStructureWithConfiguration = EventStructureWithGuildConfiguration | EventStructureWithAllGuildsConfiguration;
|
|
14
|
+
export type EventStructure = EventStructureWithGuildConfiguration | EventStructureWithAllGuildsConfiguration | EventStructureWithoutGuildConfiguration;
|
|
15
|
+
interface EventInteractionStructure {
|
|
16
|
+
data: EventDataStructure;
|
|
17
|
+
}
|
|
18
|
+
interface EventDataStructure {
|
|
19
|
+
name: EventKeys;
|
|
20
|
+
once: boolean;
|
|
21
|
+
}
|
|
22
|
+
export type ClientEventsArgs = ClientEvents[keyof ClientEvents];
|
|
23
|
+
export type EventKeys = keyof ClientEvents;
|
|
24
|
+
export {};
|
|
@@ -1,39 +1,64 @@
|
|
|
1
|
-
import { type AnySelectMenuInteraction, type AutocompleteInteraction, type Awaitable, type ButtonInteraction, type ChatInputCommandInteraction, type
|
|
1
|
+
import { type AnySelectMenuInteraction, type AutocompleteInteraction, type Awaitable, type ButtonInteraction, type ChatInputCommandInteraction, type ContextMenuCommandType, type MessageContextMenuCommandInteraction, type ModalSubmitInteraction, type SlashCommandOptionsOnlyBuilder, type UserContextMenuCommandInteraction } from "discord.js";
|
|
2
2
|
import { type StelliaClient } from "../client/index.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type GuildConfigurationType } from "../typescript/index.js";
|
|
4
4
|
import { type EventStructure } from "./Event.js";
|
|
5
|
-
export interface
|
|
6
|
-
|
|
5
|
+
export interface AutoCompleteStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
6
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: AutocompleteInteraction<"cached">): Awaitable<unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface AutoCompleteStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
7
9
|
execute(client: StelliaClient, interaction: AutocompleteInteraction<"cached">): Awaitable<unknown>;
|
|
8
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: AutocompleteInteraction<"cached">): Awaitable<unknown>;
|
|
9
10
|
}
|
|
10
|
-
export
|
|
11
|
-
|
|
11
|
+
export type AutoCompleteStructure = AutoCompleteStructureWithGuildConfiguration | AutoCompleteStructureWithoutGuildConfiguration;
|
|
12
|
+
export interface ButtonStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
13
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ButtonInteraction<"cached">): Awaitable<unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface ButtonStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
12
16
|
execute(client: StelliaClient, interaction: ButtonInteraction<"cached">): Awaitable<unknown>;
|
|
13
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: ButtonInteraction<"cached">): Awaitable<unknown>;
|
|
14
17
|
}
|
|
15
|
-
export
|
|
16
|
-
|
|
18
|
+
export type ButtonStructure = ButtonStructureWithGuildConfiguration | ButtonStructureWithoutGuildConfiguration;
|
|
19
|
+
export interface CommandStructureWithGuildConfiguration extends CommandInteractionStructure {
|
|
20
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ChatInputCommandInteraction<"cached">): Awaitable<unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface CommandStructureWithoutGuildConfiguration extends CommandInteractionStructure {
|
|
17
23
|
execute(client: StelliaClient, interaction: ChatInputCommandInteraction<"cached">): Awaitable<unknown>;
|
|
18
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: ChatInputCommandInteraction<"cached">): Awaitable<unknown>;
|
|
19
24
|
}
|
|
20
|
-
export
|
|
21
|
-
|
|
25
|
+
export type CommandStructure = CommandStructureWithGuildConfiguration | CommandStructureWithoutGuildConfiguration;
|
|
26
|
+
export interface ContextMenuStructureWithGuildConfiguration extends ContextMenuInteractionStructure {
|
|
27
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: MessageContextMenuCommandInteraction<"cached"> | UserContextMenuCommandInteraction<"cached">): Awaitable<unknown>;
|
|
28
|
+
}
|
|
29
|
+
export interface ContextMenuStructureWithoutGuildConfiguration extends ContextMenuInteractionStructure {
|
|
22
30
|
execute(client: StelliaClient, interaction: MessageContextMenuCommandInteraction<"cached"> | UserContextMenuCommandInteraction<"cached">): Awaitable<unknown>;
|
|
23
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: MessageContextMenuCommandInteraction<"cached"> | UserContextMenuCommandInteraction<"cached">): Awaitable<unknown>;
|
|
24
31
|
}
|
|
25
|
-
export
|
|
26
|
-
|
|
32
|
+
export type ContextMenuStructure = ContextMenuStructureWithGuildConfiguration | ContextMenuStructureWithoutGuildConfiguration;
|
|
33
|
+
export interface ModalStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
34
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ModalSubmitInteraction<"cached">): Awaitable<unknown>;
|
|
35
|
+
}
|
|
36
|
+
export interface ModalStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
27
37
|
execute(client: StelliaClient, interaction: ModalSubmitInteraction<"cached">): Awaitable<unknown>;
|
|
28
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: ModalSubmitInteraction<"cached">): Awaitable<unknown>;
|
|
29
38
|
}
|
|
30
|
-
export
|
|
31
|
-
|
|
39
|
+
export type ModalStructure = ModalStructureWithGuildConfiguration | ModalStructureWithoutGuildConfiguration;
|
|
40
|
+
export interface SelectMenuStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
41
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: AnySelectMenuInteraction<"cached">): Awaitable<unknown>;
|
|
42
|
+
}
|
|
43
|
+
export interface SelectMenuStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
32
44
|
execute(client: StelliaClient, interaction: AnySelectMenuInteraction<"cached">): Awaitable<unknown>;
|
|
33
|
-
execute<CustomEnvironment extends EnvironmentConfiguration>(client: StelliaClient, environment: CustomEnvironment, interaction: AnySelectMenuInteraction<"cached">): Awaitable<unknown>;
|
|
34
45
|
}
|
|
46
|
+
export type SelectMenuStructure = SelectMenuStructureWithGuildConfiguration | SelectMenuStructureWithoutGuildConfiguration;
|
|
35
47
|
export type AnyInteractionStructure = AutoCompleteStructure | ButtonStructure | CommandStructure | ContextMenuStructure | EventStructure | ModalStructure | SelectMenuStructure;
|
|
36
|
-
interface
|
|
48
|
+
interface CommandInteractionStructure {
|
|
49
|
+
data: SlashCommandOptionsOnlyBuilder;
|
|
50
|
+
}
|
|
51
|
+
interface ContextMenuInteractionStructure {
|
|
52
|
+
data: ContextMenuDataStructure;
|
|
53
|
+
}
|
|
54
|
+
interface ContextMenuDataStructure {
|
|
55
|
+
name: string;
|
|
56
|
+
type: ContextMenuCommandType;
|
|
57
|
+
}
|
|
58
|
+
interface MessageInteractionStructure {
|
|
59
|
+
data: MessageDataStructure;
|
|
60
|
+
}
|
|
61
|
+
interface MessageDataStructure {
|
|
37
62
|
name: string | RegExp;
|
|
38
63
|
once: boolean;
|
|
39
64
|
}
|
|
@@ -20,9 +20,26 @@ export interface Managers {
|
|
|
20
20
|
selectMenus?: SelectMenuManager;
|
|
21
21
|
modals?: ModalManager;
|
|
22
22
|
}
|
|
23
|
-
export interface
|
|
24
|
-
|
|
23
|
+
export interface ClientEnvironment {
|
|
24
|
+
areGuildsConfigurationEnabled: boolean;
|
|
25
25
|
}
|
|
26
|
-
export interface
|
|
26
|
+
export interface BaseGuildConfiguration {
|
|
27
|
+
locale: string;
|
|
27
28
|
[key: string]: unknown;
|
|
28
29
|
}
|
|
30
|
+
export interface BaseGeneralConfiguration {
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface GuildsConfiguration {
|
|
34
|
+
general: {
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
};
|
|
37
|
+
guilds: {
|
|
38
|
+
[guildId: string]: BaseGuildConfiguration;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface GuildConfiguration {
|
|
42
|
+
general: BaseGeneralConfiguration;
|
|
43
|
+
guild: BaseGuildConfiguration;
|
|
44
|
+
}
|
|
45
|
+
export type GuildConfigurationType = GuildConfiguration | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import logSymbols from "log-symbols";
|
|
2
|
+
export const logger = {
|
|
3
|
+
info: (message) => {
|
|
4
|
+
console.log(`${logSymbols.info} ${message}`);
|
|
5
|
+
},
|
|
6
|
+
success: (message) => {
|
|
7
|
+
console.log(`${logSymbols.success} ${message}`);
|
|
8
|
+
},
|
|
9
|
+
warn: (message) => {
|
|
10
|
+
console.warn(`${logSymbols.warning} ${message}`);
|
|
11
|
+
},
|
|
12
|
+
error: (message) => {
|
|
13
|
+
console.error(`${logSymbols.error} ${message}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stelliajs/framework",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.0-dev-2",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -15,12 +15,14 @@
|
|
|
15
15
|
"description": "A framework for simplify the creation of discord bots",
|
|
16
16
|
"keywords": ["discord", "bot", "discordjs", "typescript", "framework"],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"discord-api-types": "^0.
|
|
19
|
-
"discord.js": "^14.
|
|
18
|
+
"discord-api-types": "^0.38.10",
|
|
19
|
+
"discord.js": "^14.19.3",
|
|
20
|
+
"log-symbols": "^7.0.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"ts-node": "^10.9.2",
|
|
23
|
-
"tsc-alias": "^1.8.
|
|
24
|
+
"tsc-alias": "^1.8.16"
|
|
24
25
|
},
|
|
25
|
-
"type": "module"
|
|
26
|
+
"type": "module",
|
|
27
|
+
"packageManager": "pnpm@10.11.1"
|
|
26
28
|
}
|