@stelliajs/framework 1.3.0-dev-1 → 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 +41 -28
- 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 +68 -51
- package/dist/managers/EventManager.d.ts +5 -0
- package/dist/managers/EventManager.js +58 -26
- package/dist/structures/Event.d.ts +13 -8
- package/dist/structures/Interaction.d.ts +25 -25
- 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 +6 -5
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## About
|
|
4
4
|
|
|
5
5
|
StelliaJS is built using Discord JS V14 and TypeScript. It allows you to quickly set up a new bot with a simple and complete architecture.
|
|
6
|
-
A CLI is
|
|
6
|
+
A CLI is available to help you set up a project with StelliaJS : [link to the CLI](https://github.com/StelliaJS/cli)
|
|
7
7
|
|
|
8
8
|
## Architecture
|
|
9
9
|
Recommended architecture for StelliaJS project.
|
|
@@ -19,6 +19,10 @@ Recommended architecture for StelliaJS project.
|
|
|
19
19
|
│ │ │ ├── ban.ts
|
|
20
20
|
│ │ │ └── mute.ts
|
|
21
21
|
│ │ └── ping.ts
|
|
22
|
+
│ ├── environments/
|
|
23
|
+
│ │ ├── environment.development.ts
|
|
24
|
+
│ │ ├── environment.model.ts
|
|
25
|
+
│ │ └── environment.ts
|
|
22
26
|
│ ├── events/
|
|
23
27
|
│ │ ├── ready.ts
|
|
24
28
|
│ │ └── interactionCreate.ts
|
|
@@ -36,16 +40,17 @@ Recommended architecture for StelliaJS project.
|
|
|
36
40
|
├── .env
|
|
37
41
|
├── package.json
|
|
38
42
|
├── package-lock.json
|
|
43
|
+
├── stellia.json
|
|
39
44
|
└── tsconfig.json
|
|
40
45
|
```
|
|
46
|
+
|
|
41
47
|
## Examples
|
|
42
48
|
|
|
43
|
-
### Simple client
|
|
49
|
+
### Simple client with environment
|
|
44
50
|
|
|
45
51
|
```js
|
|
46
52
|
import { StelliaClient } from "@stelliajs/framework";
|
|
47
|
-
import { GatewayIntentBits } from "discord
|
|
48
|
-
import { Partials } from "discord.js";
|
|
53
|
+
import { GatewayIntentBits, Partials } from "discord.js";
|
|
49
54
|
|
|
50
55
|
const client = new StelliaClient({
|
|
51
56
|
intents: [
|
|
@@ -56,26 +61,31 @@ const client = new StelliaClient({
|
|
|
56
61
|
],
|
|
57
62
|
partials: [Partials.Message, Partials.GuildMember]
|
|
58
63
|
}, {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
managers: {
|
|
65
|
+
autoCompletes: {
|
|
66
|
+
directoryPath: "./interactions/autoCompletes"
|
|
67
|
+
},
|
|
68
|
+
buttons: {
|
|
69
|
+
directoryPath: "./interactions/buttons"
|
|
70
|
+
},
|
|
71
|
+
commands: {
|
|
72
|
+
directoryPath: "./commands/slash"
|
|
73
|
+
},
|
|
74
|
+
contextMenus: {
|
|
75
|
+
directoryPath: "./commands/contextMenus"
|
|
76
|
+
},
|
|
77
|
+
events: {
|
|
78
|
+
directoryPath: "./events"
|
|
79
|
+
},
|
|
80
|
+
modals: {
|
|
81
|
+
directoryPath: "./interactions/modals"
|
|
82
|
+
},
|
|
83
|
+
selectMenus: {
|
|
84
|
+
directoryPath: "./interactions/selectMenus"
|
|
85
|
+
}
|
|
76
86
|
},
|
|
77
|
-
|
|
78
|
-
|
|
87
|
+
environment: {
|
|
88
|
+
areGuildsConfigurationEnabled: true
|
|
79
89
|
}
|
|
80
90
|
});
|
|
81
91
|
|
|
@@ -84,34 +94,36 @@ await client.connect(process.env.TOKEN);
|
|
|
84
94
|
|
|
85
95
|
### Simple event
|
|
86
96
|
|
|
87
|
-
#### Ready event
|
|
97
|
+
#### Ready event with environment
|
|
88
98
|
```js
|
|
89
99
|
import { type StelliaClient, type EventStructure } from "@stelliajs/framework";
|
|
90
100
|
import { Events } from "discord.js";
|
|
101
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
91
102
|
|
|
92
103
|
export default {
|
|
93
104
|
data: {
|
|
94
105
|
name: Events.ClientReady,
|
|
95
106
|
once: true
|
|
96
107
|
},
|
|
97
|
-
async execute(client: StelliaClient<true
|
|
108
|
+
async execute(client: StelliaClient<true>, environment: CustomGuildsConfiguration) { // <true> ensures that the client is Ready
|
|
98
109
|
console.log(`Logged in as ${client.user.tag}`);
|
|
99
110
|
await client.initializeCommands(); // Used to initialise registered commands
|
|
100
111
|
}
|
|
101
112
|
} as EventStructure;
|
|
102
113
|
```
|
|
103
114
|
|
|
104
|
-
#### InteractionCreate event
|
|
115
|
+
#### InteractionCreate event with environment
|
|
105
116
|
```js
|
|
106
117
|
import { type StelliaClient, type EventStructure } from "@stelliajs/framework";
|
|
107
118
|
import { Events, type Interaction } from "discord.js";
|
|
119
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
108
120
|
|
|
109
121
|
export default {
|
|
110
122
|
data: {
|
|
111
123
|
name: Events.InteractionCreate,
|
|
112
124
|
once: false
|
|
113
125
|
},
|
|
114
|
-
async execute(client: StelliaClient<true>, interaction: Interaction) {
|
|
126
|
+
async execute(client: StelliaClient<true>, environment: CustomGuildsConfiguration, interaction: Interaction) {
|
|
115
127
|
if (interaction.inCachedGuild()) {
|
|
116
128
|
await client.handleInteraction(interaction); // Automatic interaction handling
|
|
117
129
|
}
|
|
@@ -124,11 +136,12 @@ export default {
|
|
|
124
136
|
```js
|
|
125
137
|
import { type CommandStructure, ephemeralFollowUpResponse, type StelliaClient } from "@stelliajs/framework";
|
|
126
138
|
import { type ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
|
139
|
+
import { type CustomGuildsConfiguration } from "@environments/environment.model.ts";
|
|
127
140
|
|
|
128
141
|
export default {
|
|
129
142
|
data: new SlashCommandBuilder()
|
|
130
143
|
.setName("ping"),
|
|
131
|
-
async execute(client: StelliaClient, interaction: ChatInputCommandInteraction<"cached">) { // All interactions are cached
|
|
144
|
+
async execute(client: StelliaClient, environment: CustomGuildsConfiguration, interaction: ChatInputCommandInteraction<"cached">) { // All interactions are cached
|
|
132
145
|
await ephemeralFollowUpResponse(interaction, "Pong!", true); // Response is ephemeral and deleted after 60 seconds
|
|
133
146
|
}
|
|
134
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);
|
|
@@ -59,17 +69,18 @@ export class StelliaUtils {
|
|
|
59
69
|
const autoComplete = autoCompleteManager.getByCustomId(autoCompleteInteraction.commandName);
|
|
60
70
|
if (!autoComplete)
|
|
61
71
|
return;
|
|
62
|
-
if (this.client.environment.
|
|
63
|
-
const
|
|
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);
|
|
65
76
|
}
|
|
66
77
|
else {
|
|
67
|
-
const
|
|
68
|
-
await
|
|
78
|
+
const autoCompleteWithoutGuildConfiguration = autoComplete;
|
|
79
|
+
await autoCompleteWithoutGuildConfiguration.execute(this.client, autoCompleteInteraction);
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
82
|
catch (error) {
|
|
72
|
-
|
|
83
|
+
logger.error(`Error while handling autocomplete interaction: ${error}`);
|
|
73
84
|
}
|
|
74
85
|
};
|
|
75
86
|
handleButtonInteraction = async (interaction) => {
|
|
@@ -81,17 +92,18 @@ export class StelliaUtils {
|
|
|
81
92
|
const button = buttonManager.getByCustomId(buttonInteraction.customId) || buttonManager.getByRegex(buttonInteraction.customId);
|
|
82
93
|
if (!button)
|
|
83
94
|
return;
|
|
84
|
-
if (this.client.environment.
|
|
85
|
-
const
|
|
86
|
-
|
|
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);
|
|
87
99
|
}
|
|
88
100
|
else {
|
|
89
|
-
const
|
|
90
|
-
await
|
|
101
|
+
const buttonWithoutGuildConfiguration = button;
|
|
102
|
+
await buttonWithoutGuildConfiguration.execute(this.client, buttonInteraction);
|
|
91
103
|
}
|
|
92
104
|
}
|
|
93
105
|
catch (error) {
|
|
94
|
-
|
|
106
|
+
logger.error(`Error while handling button interaction: ${error}`);
|
|
95
107
|
}
|
|
96
108
|
};
|
|
97
109
|
handleCommandInteraction = async (interaction) => {
|
|
@@ -103,17 +115,18 @@ export class StelliaUtils {
|
|
|
103
115
|
let command = commandManager.getByCustomId(commandInteraction.commandName);
|
|
104
116
|
if (!command)
|
|
105
117
|
return;
|
|
106
|
-
if (this.client.environment.
|
|
107
|
-
const
|
|
108
|
-
|
|
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);
|
|
109
122
|
}
|
|
110
123
|
else {
|
|
111
|
-
const
|
|
112
|
-
await
|
|
124
|
+
const commandWithoutGuildConfiguration = command;
|
|
125
|
+
await commandWithoutGuildConfiguration.execute(this.client, commandInteraction);
|
|
113
126
|
}
|
|
114
127
|
}
|
|
115
128
|
catch (error) {
|
|
116
|
-
|
|
129
|
+
logger.error(`Error while handling command interaction: ${error}`);
|
|
117
130
|
}
|
|
118
131
|
};
|
|
119
132
|
handleContextMenuInteraction = async (interaction) => {
|
|
@@ -129,7 +142,7 @@ export class StelliaUtils {
|
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
144
|
catch (error) {
|
|
132
|
-
|
|
145
|
+
logger.error(`Error while handling context menu interaction: ${error}`);
|
|
133
146
|
}
|
|
134
147
|
};
|
|
135
148
|
handleModalInteraction = async (interaction) => {
|
|
@@ -141,17 +154,18 @@ export class StelliaUtils {
|
|
|
141
154
|
const modal = modalManager.getByCustomId(modalInteraction.customId) || modalManager.getByRegex(modalInteraction.customId);
|
|
142
155
|
if (!modal)
|
|
143
156
|
return;
|
|
144
|
-
if (this.client.environment.
|
|
145
|
-
const
|
|
146
|
-
|
|
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);
|
|
147
161
|
}
|
|
148
162
|
else {
|
|
149
|
-
const
|
|
150
|
-
await
|
|
163
|
+
const modalWithoutGuildConfiguration = modal;
|
|
164
|
+
await modalWithoutGuildConfiguration.execute(this.client, modalInteraction);
|
|
151
165
|
}
|
|
152
166
|
}
|
|
153
167
|
catch (error) {
|
|
154
|
-
|
|
168
|
+
logger.error(`Error while handling modal interaction: ${error}`);
|
|
155
169
|
}
|
|
156
170
|
};
|
|
157
171
|
handleSelectMenuInteraction = async (interaction) => {
|
|
@@ -163,17 +177,18 @@ export class StelliaUtils {
|
|
|
163
177
|
const selectMenu = selectMenuManager.getByCustomId(selectMenuInteraction.customId) || selectMenuManager.getByRegex(selectMenuInteraction.customId);
|
|
164
178
|
if (!selectMenu)
|
|
165
179
|
return;
|
|
166
|
-
if (this.client.environment.
|
|
167
|
-
const
|
|
168
|
-
|
|
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);
|
|
169
184
|
}
|
|
170
185
|
else {
|
|
171
|
-
const
|
|
172
|
-
await
|
|
186
|
+
const modalWithoutGuildConfiguration = selectMenu;
|
|
187
|
+
await modalWithoutGuildConfiguration.execute(this.client, selectMenuInteraction);
|
|
173
188
|
}
|
|
174
189
|
}
|
|
175
190
|
catch (error) {
|
|
176
|
-
|
|
191
|
+
logger.error(`Error while handling select menu interaction: ${error}`);
|
|
177
192
|
}
|
|
178
193
|
};
|
|
179
194
|
handleMessageContextMenuInteraction = async (interaction) => {
|
|
@@ -184,17 +199,18 @@ export class StelliaUtils {
|
|
|
184
199
|
const messageContextMenu = contextMenuManager.getByCustomId(interaction.commandName);
|
|
185
200
|
if (!messageContextMenu)
|
|
186
201
|
return;
|
|
187
|
-
if (this.client.environment.
|
|
188
|
-
const
|
|
189
|
-
|
|
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);
|
|
190
206
|
}
|
|
191
207
|
else {
|
|
192
|
-
const
|
|
193
|
-
await
|
|
208
|
+
const messageContextMenuWithoutGuildConfiguration = messageContextMenu;
|
|
209
|
+
await messageContextMenuWithoutGuildConfiguration.execute(this.client, interaction);
|
|
194
210
|
}
|
|
195
211
|
}
|
|
196
212
|
catch (error) {
|
|
197
|
-
|
|
213
|
+
logger.error(`Error while handling message context menu interaction: ${error}`);
|
|
198
214
|
}
|
|
199
215
|
};
|
|
200
216
|
handleUserContextMenuInteraction = async (interaction) => {
|
|
@@ -205,17 +221,18 @@ export class StelliaUtils {
|
|
|
205
221
|
const userContextMenu = contextMenuManager.getByCustomId(interaction.commandName);
|
|
206
222
|
if (!userContextMenu)
|
|
207
223
|
return;
|
|
208
|
-
if (this.client.environment.
|
|
209
|
-
const
|
|
210
|
-
|
|
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);
|
|
211
228
|
}
|
|
212
229
|
else {
|
|
213
|
-
const
|
|
214
|
-
await
|
|
230
|
+
const userContextMenuWithoutGuildConfiguration = userContextMenu;
|
|
231
|
+
await userContextMenuWithoutGuildConfiguration.execute(this.client, interaction);
|
|
215
232
|
}
|
|
216
233
|
}
|
|
217
234
|
catch (error) {
|
|
218
|
-
|
|
235
|
+
logger.error(`Error while handling user context menu interaction: ${error}`);
|
|
219
236
|
}
|
|
220
237
|
};
|
|
221
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,45 +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
22
|
for (const eventStructure of this.interactions.values()) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const environment = await this.client.getEnvironment();
|
|
16
|
-
const event = eventStructure;
|
|
17
|
-
if (name == Events.ClientReady) {
|
|
18
|
-
this.client.once(Events.ClientReady, () => event.execute(this.client, environment));
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
if (once) {
|
|
22
|
-
this.client.once(name, (...args) => event.execute(this.client, environment, ...args));
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
this.client.on(name, (...args) => event.execute(this.client, environment, ...args));
|
|
26
|
-
}
|
|
23
|
+
if (this.client.environment.areGuildsConfigurationEnabled) {
|
|
24
|
+
await this.loadEventWithGuildConfiguration(eventStructure);
|
|
27
25
|
}
|
|
28
26
|
else {
|
|
29
|
-
|
|
30
|
-
if (name == Events.ClientReady) {
|
|
31
|
-
this.client.once(name, () => event.execute(this.client));
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
if (once) {
|
|
35
|
-
this.client.once(name, (...args) => event.execute(this.client, ...args));
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
this.client.on(name, (...args) => event.execute(this.client, ...args));
|
|
39
|
-
}
|
|
27
|
+
await this.loadEventWithoutGuildConfiguration(eventStructure);
|
|
40
28
|
}
|
|
41
29
|
}
|
|
42
|
-
this.client.on(Events.Error, (error) =>
|
|
30
|
+
this.client.on(Events.Error, (error) => logger.error(`Client error: ${error}`));
|
|
43
31
|
this.setManagerLoaded();
|
|
44
32
|
}
|
|
45
33
|
getByCustomId(id) {
|
|
@@ -53,4 +41,48 @@ export class EventManager extends BaseManager {
|
|
|
53
41
|
const events = this.interactions;
|
|
54
42
|
return events;
|
|
55
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
|
+
}
|
|
56
88
|
}
|
|
@@ -1,19 +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
|
-
execute(client: StelliaClient,
|
|
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>;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
8
|
-
execute(client: StelliaClient, ...args:
|
|
7
|
+
export interface EventStructureWithAllGuildsConfiguration extends EventInteractionStructure {
|
|
8
|
+
execute(client: StelliaClient, guildsConfiguration: GuildsConfiguration, ...args: ClientEventsArgs): Awaitable<unknown>;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
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;
|
|
11
15
|
interface EventInteractionStructure {
|
|
12
16
|
data: EventDataStructure;
|
|
13
17
|
}
|
|
14
18
|
interface EventDataStructure {
|
|
15
|
-
name:
|
|
19
|
+
name: EventKeys;
|
|
16
20
|
once: boolean;
|
|
17
21
|
}
|
|
18
|
-
type
|
|
22
|
+
export type ClientEventsArgs = ClientEvents[keyof ClientEvents];
|
|
23
|
+
export type EventKeys = keyof ClientEvents;
|
|
19
24
|
export {};
|
|
@@ -1,49 +1,49 @@
|
|
|
1
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
|
-
execute(client: StelliaClient,
|
|
5
|
+
export interface AutoCompleteStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
6
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: AutocompleteInteraction<"cached">): Awaitable<unknown>;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface AutoCompleteStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
9
9
|
execute(client: StelliaClient, interaction: AutocompleteInteraction<"cached">): Awaitable<unknown>;
|
|
10
10
|
}
|
|
11
|
-
export type AutoCompleteStructure =
|
|
12
|
-
export interface
|
|
13
|
-
execute(client: StelliaClient,
|
|
11
|
+
export type AutoCompleteStructure = AutoCompleteStructureWithGuildConfiguration | AutoCompleteStructureWithoutGuildConfiguration;
|
|
12
|
+
export interface ButtonStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
13
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ButtonInteraction<"cached">): Awaitable<unknown>;
|
|
14
14
|
}
|
|
15
|
-
export interface
|
|
15
|
+
export interface ButtonStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
16
16
|
execute(client: StelliaClient, interaction: ButtonInteraction<"cached">): Awaitable<unknown>;
|
|
17
17
|
}
|
|
18
|
-
export type ButtonStructure =
|
|
19
|
-
export interface
|
|
20
|
-
execute(client: StelliaClient,
|
|
18
|
+
export type ButtonStructure = ButtonStructureWithGuildConfiguration | ButtonStructureWithoutGuildConfiguration;
|
|
19
|
+
export interface CommandStructureWithGuildConfiguration extends CommandInteractionStructure {
|
|
20
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ChatInputCommandInteraction<"cached">): Awaitable<unknown>;
|
|
21
21
|
}
|
|
22
|
-
export interface
|
|
22
|
+
export interface CommandStructureWithoutGuildConfiguration extends CommandInteractionStructure {
|
|
23
23
|
execute(client: StelliaClient, interaction: ChatInputCommandInteraction<"cached">): Awaitable<unknown>;
|
|
24
24
|
}
|
|
25
|
-
export type CommandStructure =
|
|
26
|
-
export interface
|
|
27
|
-
execute(client: StelliaClient,
|
|
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
28
|
}
|
|
29
|
-
export interface
|
|
29
|
+
export interface ContextMenuStructureWithoutGuildConfiguration extends ContextMenuInteractionStructure {
|
|
30
30
|
execute(client: StelliaClient, interaction: MessageContextMenuCommandInteraction<"cached"> | UserContextMenuCommandInteraction<"cached">): Awaitable<unknown>;
|
|
31
31
|
}
|
|
32
|
-
export type ContextMenuStructure =
|
|
33
|
-
export interface
|
|
34
|
-
execute(client: StelliaClient,
|
|
32
|
+
export type ContextMenuStructure = ContextMenuStructureWithGuildConfiguration | ContextMenuStructureWithoutGuildConfiguration;
|
|
33
|
+
export interface ModalStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
34
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: ModalSubmitInteraction<"cached">): Awaitable<unknown>;
|
|
35
35
|
}
|
|
36
|
-
export interface
|
|
36
|
+
export interface ModalStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
37
37
|
execute(client: StelliaClient, interaction: ModalSubmitInteraction<"cached">): Awaitable<unknown>;
|
|
38
38
|
}
|
|
39
|
-
export type ModalStructure =
|
|
40
|
-
export interface
|
|
41
|
-
execute(client: StelliaClient,
|
|
39
|
+
export type ModalStructure = ModalStructureWithGuildConfiguration | ModalStructureWithoutGuildConfiguration;
|
|
40
|
+
export interface SelectMenuStructureWithGuildConfiguration extends MessageInteractionStructure {
|
|
41
|
+
execute(client: StelliaClient, guildConfiguration: GuildConfigurationType, interaction: AnySelectMenuInteraction<"cached">): Awaitable<unknown>;
|
|
42
42
|
}
|
|
43
|
-
export interface
|
|
43
|
+
export interface SelectMenuStructureWithoutGuildConfiguration extends MessageInteractionStructure {
|
|
44
44
|
execute(client: StelliaClient, interaction: AnySelectMenuInteraction<"cached">): Awaitable<unknown>;
|
|
45
45
|
}
|
|
46
|
-
export type SelectMenuStructure =
|
|
46
|
+
export type SelectMenuStructure = SelectMenuStructureWithGuildConfiguration | SelectMenuStructureWithoutGuildConfiguration;
|
|
47
47
|
export type AnyInteractionStructure = AutoCompleteStructure | ButtonStructure | CommandStructure | ContextMenuStructure | EventStructure | ModalStructure | SelectMenuStructure;
|
|
48
48
|
interface CommandInteractionStructure {
|
|
49
49
|
data: SlashCommandOptionsOnlyBuilder;
|
|
@@ -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.3.0-dev-
|
|
3
|
+
"version": "1.3.0-dev-2",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -15,13 +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.38.
|
|
19
|
-
"discord.js": "^14.19.3"
|
|
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
26
|
"type": "module",
|
|
26
|
-
"packageManager": "pnpm@10.
|
|
27
|
+
"packageManager": "pnpm@10.11.1"
|
|
27
28
|
}
|