create-djskit 0.0.0-stage → 1.0.0

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.
@@ -0,0 +1,17 @@
1
+ import { ApplicationCommandType, Client, ContextMenuCommandBuilder, MessageContextMenuCommandInteraction, MessageFlags } from "discord.js";
2
+
3
+ export default {
4
+
5
+ data: new ContextMenuCommandBuilder()
6
+ .setName("Quote Message")
7
+ .setType(ApplicationCommandType.Message),
8
+
9
+ async execute( interaction: MessageContextMenuCommandInteraction, client: Client ) {
10
+
11
+ const message = interaction.targetMessage;
12
+
13
+ await interaction.reply({ content: `> ${message.content || "*No text content*"}\n— ${message.author.displayName}`, flags: [MessageFlags.Ephemeral] });
14
+
15
+ }
16
+
17
+ }
@@ -0,0 +1,17 @@
1
+ import { ApplicationCommandType, Client, ContextMenuCommandBuilder, MessageFlags, UserContextMenuCommandInteraction } from "discord.js";
2
+
3
+ export default {
4
+
5
+ data: new ContextMenuCommandBuilder()
6
+ .setName("Show Avatar")
7
+ .setType(ApplicationCommandType.User),
8
+
9
+ async execute( interaction: UserContextMenuCommandInteraction, client: Client ) {
10
+
11
+ const user = interaction.targetUser;
12
+
13
+ await interaction.reply({ content: `${user.displayName}'s avatar: ${user.displayAvatarURL({ size: 1024 })}`, flags: [MessageFlags.Ephemeral] });
14
+
15
+ }
16
+
17
+ }
@@ -0,0 +1,16 @@
1
+ import { Events, Client, Message } from "discord.js";
2
+
3
+ export default {
4
+
5
+ data: {
6
+ event: Events.MessageCreate,
7
+ once: false,
8
+ },
9
+
10
+ async execute(client: Client, message: Message) {
11
+
12
+ console.log(message.content)
13
+
14
+ }
15
+
16
+ }
@@ -0,0 +1,9 @@
1
+ import DotDB from "dotdatabase";
2
+
3
+ const database = {
4
+
5
+ config: new DotDB("src/database/config.json")
6
+
7
+ }
8
+
9
+ export default database;
@@ -0,0 +1,17 @@
1
+ import "dotenv/config";
2
+ import chalk from "chalk";
3
+ import config from "../config";
4
+
5
+ // DEV_MODE=true -> commands are registered to (and message commands only respond in) config.devGuildId
6
+ // DEV_MODE=false -> commands are registered globally, even if a devGuildId is set
7
+
8
+ let devMode = process.env.DEV_MODE?.trim().toLowerCase() === "true";
9
+
10
+ if ( devMode && config.devGuildId === "" ) {
11
+
12
+ console.log(chalk.yellow.bold("[🌿]") + " " + chalk.yellow("DEV_MODE is enabled but no devGuildId is set in src/config.ts. Registering commands globally."));
13
+ devMode = false;
14
+
15
+ }
16
+
17
+ export default devMode;
@@ -0,0 +1,49 @@
1
+ import { Client, Events } from "discord.js";
2
+ import fs from "fs";
3
+ import chalk from "chalk";
4
+
5
+ const eventHandler = async (client: Client) => {
6
+
7
+ if (!client.isReady()) {
8
+ await new Promise((resolve) => client.once(Events.ClientReady, resolve));
9
+ }
10
+
11
+ for (const directory of fs.readdirSync("./src/events")) {
12
+
13
+ if ( directory == ".DS_Store" ) continue;
14
+ if ( directory.startsWith("src") ) continue;
15
+
16
+ for (const file of fs.readdirSync("./src/events/" + directory).filter((f) => f.endsWith(".ts"))) {
17
+
18
+ try {
19
+
20
+ const module = await import(`../events/${directory}/${file}`);
21
+ const event = module.default;
22
+
23
+ if (event.data.once) {
24
+ client.once(event.data.event, (...args) => event.execute(client, ...args));
25
+ }
26
+
27
+ if (!event.data.once) {
28
+ client.on(event.data.event, (...args) => event.execute(client, ...args));
29
+ }
30
+
31
+ } catch ( err ) {
32
+
33
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while registering an event."));
34
+ console.log()
35
+ console.log(chalk.grey("------------------------------"))
36
+ console.log()
37
+ console.log(err);
38
+ console.log()
39
+ console.log(chalk.grey("------------------------------"))
40
+
41
+ }
42
+
43
+ }
44
+
45
+ }
46
+
47
+ }
48
+
49
+ export default eventHandler;
@@ -0,0 +1,62 @@
1
+ import { Client, Events, Interaction, MessageFlags } from "discord.js";
2
+ import chalk from "chalk";
3
+
4
+ const listenerComponents = async (client: Client, components: Map<string, any>) => {
5
+ client.on(Events.InteractionCreate, async (interaction: Interaction) => {
6
+ if (!interaction.isMessageComponent() && !interaction.isModalSubmit()) return;
7
+
8
+ const cId = interaction.customId.split(":")[0]
9
+
10
+ const componentHandler = components.get(cId);
11
+
12
+ if (!componentHandler) {
13
+ return;
14
+ }
15
+
16
+ if ( interaction.customId.split(":").length >= 3 ) {
17
+ return;
18
+ }
19
+
20
+ let componentArgs: Record<string, string> = {};
21
+ const componentArgsString = interaction.customId.split(":")[1]
22
+
23
+ if (componentArgsString) {
24
+ const componentArgPairs = componentArgsString.includes("_")
25
+ ? componentArgsString.split("_")
26
+ : [componentArgsString];
27
+
28
+ for (const argPair of componentArgPairs) {
29
+ const [argKey, argVal] = argPair.split("=");
30
+ if (argKey && argVal !== undefined) {
31
+ componentArgs[argKey] = argVal;
32
+ }
33
+ }
34
+ }
35
+
36
+ try {
37
+ await componentHandler.execute(interaction, client, componentArgs);
38
+ } catch (err) {
39
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red(`Error executing component handler for customId: ${interaction.customId}`));
40
+ console.log();
41
+ console.log(chalk.grey("------------------------------"));
42
+ console.log();
43
+ console.log(err);
44
+ console.log();
45
+ console.log(chalk.grey("------------------------------"));
46
+
47
+ if (interaction.isRepliable()) {
48
+ try {
49
+ await interaction.reply({ content: "There was an error while executing this component interaction!", flags: [MessageFlags.Ephemeral] });
50
+ } catch (replyError) {
51
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("Failed to send error reply to interaction."));
52
+ console.log(replyError);
53
+ }
54
+ }
55
+ }
56
+
57
+ }
58
+
59
+ );
60
+ };
61
+
62
+ export default listenerComponents;
@@ -0,0 +1,74 @@
1
+ import "dotenv/config";
2
+ import { Client, Events, Message } from "discord.js";
3
+ import chalk from "chalk";
4
+ import config from "../config";
5
+
6
+ const listenerMsgCommands = async (client: Client, commands: Map<any, any>, guildOnly: boolean) => {
7
+
8
+ client.on(Events.MessageCreate, async (message: Message) => {
9
+
10
+ if (message.author.bot) return;
11
+
12
+ if ( guildOnly ) {
13
+
14
+ if ( message.guild?.id !== config.devGuildId ) return;
15
+
16
+ }
17
+
18
+ if ( message.content.startsWith(config.messageCommandPrefix) ) {
19
+
20
+ const commandName = message.content.slice(config.messageCommandPrefix.length).split(" ")[0];
21
+ const commandKey = `${config.messageCommandPrefix}${commandName}`;
22
+ const command = commands.get(commandKey);
23
+
24
+ if ( !command ) return;
25
+
26
+ try {
27
+
28
+ await command.execute(message, client, message.content.split(" ").slice(1));
29
+
30
+ } catch ( err ) {
31
+
32
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while executing " + message.content.split(" ")[0]));
33
+ console.log()
34
+ console.log(chalk.grey("------------------------------"))
35
+ console.log()
36
+ console.log(err);
37
+ console.log()
38
+ console.log(chalk.grey("------------------------------"))
39
+
40
+ return;
41
+
42
+ }
43
+
44
+ return;
45
+
46
+ };
47
+
48
+ for (const [commandKey, cmd] of commands.entries()) {
49
+
50
+ if (cmd.data.customPrefix && message.content.startsWith(cmd.data.customPrefix)) {
51
+ const commandName = message.content.slice(cmd.data.customPrefix.length).split(" ")[0];
52
+
53
+ if (commandKey === `${cmd.data.customPrefix}${commandName}`) {
54
+ try {
55
+ await cmd.execute( message, client, message.content.slice(cmd.data.customPrefix.length).trim().split(" ") );
56
+ } catch (err) {
57
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while executing " + message.content.split(" ")[0]));
58
+ console.log();
59
+ console.log(chalk.grey("------------------------------"));
60
+ console.log();
61
+ console.log(err);
62
+ console.log();
63
+ console.log(chalk.grey("------------------------------"));
64
+ }
65
+ return;
66
+ }
67
+ }
68
+ }
69
+
70
+ });
71
+
72
+ }
73
+
74
+ export default listenerMsgCommands;
@@ -0,0 +1,89 @@
1
+ import "dotenv/config";
2
+ import { Client, Events, Interaction } from "discord.js";
3
+ import chalk from "chalk";
4
+
5
+ const listenerSlashCommands = async (client: Client, commands: Map<any, any>, contextCommands: Map<any, any>) => {
6
+
7
+ client.on(Events.InteractionCreate, async (interaction: Interaction) => {
8
+
9
+ if ( interaction.isAutocomplete() ) {
10
+
11
+ const command = commands.get(interaction.commandName);
12
+
13
+ if ( !command?.autocomplete ) return;
14
+
15
+ try {
16
+
17
+ await command.autocomplete(interaction, client);
18
+
19
+ } catch ( err ) {
20
+
21
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while autocompleting /" + interaction.commandName));
22
+ console.log()
23
+ console.log(chalk.grey("------------------------------"))
24
+ console.log()
25
+ console.log(err);
26
+ console.log()
27
+ console.log(chalk.grey("------------------------------"))
28
+
29
+ }
30
+
31
+ return;
32
+
33
+ }
34
+
35
+ if ( interaction.isContextMenuCommand() ) {
36
+
37
+ const command = contextCommands.get(`${interaction.commandType}:${interaction.commandName}`);
38
+
39
+ if ( !command ) return;
40
+
41
+ try {
42
+
43
+ await command.execute(interaction, client);
44
+
45
+ } catch ( err ) {
46
+
47
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while executing context menu command " + interaction.commandName));
48
+ console.log()
49
+ console.log(chalk.grey("------------------------------"))
50
+ console.log()
51
+ console.log(err);
52
+ console.log()
53
+ console.log(chalk.grey("------------------------------"))
54
+
55
+ }
56
+
57
+ return;
58
+
59
+ }
60
+
61
+ if ( !interaction.isChatInputCommand() ) return;
62
+
63
+ const command = commands.get(interaction.commandName);
64
+
65
+ if ( !command ) return;
66
+
67
+ try {
68
+
69
+ await command.execute(interaction, client);
70
+
71
+ } catch ( err ) {
72
+
73
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while executing /" + interaction.commandName));
74
+ console.log()
75
+ console.log(chalk.grey("------------------------------"))
76
+ console.log()
77
+ console.log(err);
78
+ console.log()
79
+ console.log(chalk.grey("------------------------------"))
80
+
81
+ return;
82
+
83
+ }
84
+
85
+ });
86
+
87
+ }
88
+
89
+ export default listenerSlashCommands;
@@ -0,0 +1,50 @@
1
+ import "dotenv/config";
2
+ import { Client, Events } from "discord.js";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import chalk from "chalk";
6
+
7
+ import listenerComponents from "./listenerComponents";
8
+
9
+ const handlerRegisterComponents = async (client: Client) => {
10
+ if (!client.isReady()) {
11
+ await new Promise((resolve) => client.once(Events.ClientReady, resolve));
12
+ }
13
+
14
+ const components = new Map<string, any>();
15
+ const componentsBaseDir = path.join("./src/components");
16
+
17
+ for ( const typeDir of fs.readdirSync(componentsBaseDir) ) {
18
+
19
+ if ( typeDir == ".DS_Store" ) continue;
20
+ if ( typeDir.startsWith("src") ) continue;
21
+
22
+ const typeDirPath = path.join(componentsBaseDir, typeDir);
23
+ if (!fs.statSync(typeDirPath).isDirectory()) continue;
24
+
25
+ for ( const componentFile of fs.readdirSync(typeDirPath).filter(file => file.endsWith(".js") || file.endsWith(".ts")) ) { // e.g., componentFile = "testButton.ts"
26
+ try {
27
+ const importPath = `../components/${typeDir}/${componentFile}`;
28
+ const module = await import(importPath);
29
+ const component = module.default;
30
+
31
+ if (component && typeof component.customId === 'string' && typeof component.execute === 'function') {
32
+ components.set(component.customId, component);
33
+ } else {
34
+ console.log(chalk.yellow.bold("[🌿]") + " " + chalk.yellow(`Skipping component file due to missing customId or execute function: ${componentFile}`));
35
+ }
36
+ } catch (err) {
37
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red(`Error registering component from file: ${componentFile}`));
38
+ console.log();
39
+ console.log(chalk.grey("------------------------------"));
40
+ console.log(err);
41
+ console.log();
42
+ console.log(chalk.grey("------------------------------"));
43
+ }
44
+ }
45
+ }
46
+
47
+ listenerComponents(client, components);
48
+ };
49
+
50
+ export default handlerRegisterComponents;
@@ -0,0 +1,62 @@
1
+ import "dotenv/config";
2
+ import { Client, Events } from "discord.js";
3
+ import config from "../config";
4
+ import devMode from "./devMode";
5
+ import fs from "fs";
6
+ import chalk from "chalk";
7
+
8
+ import listenerMsgCommands from "./listenerMsgCommands";
9
+
10
+ const handlerRegisterMsgCommands = async (client: Client) => {
11
+
12
+ if (!client.isReady()) {
13
+ await new Promise((resolve) => client.once(Events.ClientReady, resolve));
14
+ }
15
+
16
+ const commands = new Map();
17
+
18
+ for (const directory of fs.readdirSync("./src/commands")) {
19
+
20
+ if ( directory == ".DS_Store" ) continue;
21
+ if ( directory.startsWith("src") ) continue;
22
+
23
+ for (const file of fs.readdirSync("./src/commands/" + directory).filter((f) => f.endsWith(".ts"))) {
24
+
25
+ try {
26
+
27
+ const module = await import(`../commands/${directory}/${file}`);
28
+ const command = module.default;
29
+
30
+ if (
31
+ typeof command.data?.toJSON === "function" &&
32
+ command.data.constructor.name === "SlashCommandBuilder"
33
+ ) {
34
+ continue;
35
+ }
36
+
37
+ const commandPrefix = command.data.customPrefix || config.messageCommandPrefix;
38
+ const commandKey = `${commandPrefix}${command.data.name}`;
39
+
40
+ commands.set(commandKey, command);
41
+
42
+ } catch ( err ) {
43
+
44
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while registering a message command."));
45
+ console.log()
46
+ console.log(chalk.grey("------------------------------"))
47
+ console.log()
48
+ console.log(err);
49
+ console.log()
50
+ console.log(chalk.grey("------------------------------"))
51
+
52
+ }
53
+
54
+ }
55
+
56
+ }
57
+
58
+ listenerMsgCommands(client, commands, devMode);
59
+
60
+ }
61
+
62
+ export default handlerRegisterMsgCommands;
@@ -0,0 +1,148 @@
1
+ import "dotenv/config";
2
+ import { Client, Events, REST, Routes } from "discord.js";
3
+ import config from "../config";
4
+ import devMode from "./devMode";
5
+ import fs from "fs";
6
+ import chalk from "chalk";
7
+
8
+ import listenerSlashCommands from "./listenerSlashCommands";
9
+
10
+ // REST ----------------------------------------------------------------------------
11
+
12
+ const restApi = new REST({ version: "10" }).setToken(process.env.CLIENT_TOKEN as string);
13
+
14
+ // Register slash commands ---------------------------------------------------------
15
+
16
+ const handlerRegisterSlashCommands = async (client: Client) => {
17
+
18
+ if (!client.isReady()) {
19
+ await new Promise((resolve) => client.once(Events.ClientReady, resolve));
20
+ }
21
+
22
+ const commands = new Map();
23
+ const contextCommands = new Map();
24
+ const slashCommandsData = [];
25
+
26
+ for (const directory of fs.readdirSync("./src/commands")) {
27
+
28
+ if ( directory == ".DS_Store" ) continue;
29
+ if ( directory.startsWith("src") ) continue;
30
+
31
+ for (const file of fs.readdirSync("./src/commands/" + directory).filter((f) => f.endsWith(".ts"))) {
32
+
33
+ try {
34
+
35
+ const module = await import(`../commands/${directory}/${file}`);
36
+ const command = module.default;
37
+
38
+ if (
39
+ typeof command.data?.toJSON !== "function" ||
40
+ command.data.constructor.name !== "SlashCommandBuilder"
41
+ ) {
42
+ continue;
43
+ }
44
+
45
+ commands.set(command.data.name, command);
46
+ slashCommandsData.push(command.data);
47
+
48
+ } catch (err) {
49
+
50
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while processing a slash command."));
51
+ console.log();
52
+ console.log(chalk.grey("------------------------------"));
53
+ console.log();
54
+ console.log(err);
55
+ console.log();
56
+ console.log(chalk.grey("------------------------------"));
57
+
58
+ }
59
+
60
+ }
61
+
62
+ }
63
+
64
+ for (const directory of fs.readdirSync("./src/context")) {
65
+
66
+ if ( directory == ".DS_Store" ) continue;
67
+ if ( directory.startsWith("src") ) continue;
68
+
69
+ for (const file of fs.readdirSync("./src/context/" + directory).filter((f) => f.endsWith(".ts"))) {
70
+
71
+ try {
72
+
73
+ const module = await import(`../context/${directory}/${file}`);
74
+ const command = module.default;
75
+
76
+ if (
77
+ typeof command.data?.toJSON !== "function" ||
78
+ command.data.constructor.name !== "ContextMenuCommandBuilder"
79
+ ) {
80
+ continue;
81
+ }
82
+
83
+ contextCommands.set(`${command.data.type}:${command.data.name}`, command);
84
+ slashCommandsData.push(command.data);
85
+
86
+ } catch (err) {
87
+
88
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while processing a context menu command."));
89
+ console.log();
90
+ console.log(chalk.grey("------------------------------"));
91
+ console.log();
92
+ console.log(err);
93
+ console.log();
94
+ console.log(chalk.grey("------------------------------"));
95
+
96
+ }
97
+
98
+ }
99
+
100
+ }
101
+
102
+ try {
103
+
104
+ if (!client.user?.id) return;
105
+
106
+ if (devMode) {
107
+
108
+ await restApi.put(
109
+ Routes.applicationGuildCommands(client.user.id, config.devGuildId),
110
+ { body: slashCommandsData }
111
+ );
112
+
113
+ } else {
114
+
115
+ await restApi.put(
116
+ Routes.applicationCommands(client.user.id),
117
+ { body: slashCommandsData }
118
+ );
119
+
120
+ // Clear leftover dev server commands, so they don't show up twice next to the global ones
121
+ if (config.devGuildId !== "") {
122
+
123
+ await restApi.put(
124
+ Routes.applicationGuildCommands(client.user.id, config.devGuildId),
125
+ { body: [] }
126
+ );
127
+
128
+ }
129
+
130
+ }
131
+
132
+ } catch (err) {
133
+
134
+ console.log(chalk.red.bold("[🌿]") + " " + chalk.red("There was an error while registering slash commands."));
135
+ console.log();
136
+ console.log(chalk.grey("------------------------------"));
137
+ console.log();
138
+ console.log(err);
139
+ console.log();
140
+ console.log(chalk.grey("------------------------------"));
141
+
142
+ }
143
+
144
+ listenerSlashCommands(client, commands, contextCommands);
145
+
146
+ };
147
+
148
+ export default handlerRegisterSlashCommands;