xernerx 1.2.6 → 2.0.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 +0 -0
- package/docs/docs.md +108 -0
- package/models/Client.js +3 -2
- package/models/commands/Event.js +3 -3
- package/models/commands/InteractionCommand.js +12 -16
- package/models/data/Functions.js +14 -4
- package/models/events/interactionCreate.js +27 -29
- package/models/events/messageCreate.js +1 -0
- package/models/events/messageUpdate.js +1 -0
- package/models/events/readyOnce.js +1 -0
- package/models/handlers/CommandHandler.js +17 -12
- package/models/handlers/EventHandler.js +16 -24
- package/package.json +2 -3
package/README.md
CHANGED
|
Binary file
|
package/docs/docs.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# A lightweight class based Discord.js framework.
|
|
4
|
+
|
|
5
|
+
> - [Client](#Client)
|
|
6
|
+
> - [Handlers](#Handlers)
|
|
7
|
+
> > - [Commands](#Commands)
|
|
8
|
+
> > - [Events](#Events)
|
|
9
|
+
> - [Arguments](#Arguments)
|
|
10
|
+
> > - [Types](#Argument#Types)
|
|
11
|
+
|
|
12
|
+
## Client
|
|
13
|
+
|
|
14
|
+
> An extended discord.js client.
|
|
15
|
+
>
|
|
16
|
+
> ```js
|
|
17
|
+
> const { Client } require('xernerx');
|
|
18
|
+
>
|
|
19
|
+
> const client = new Client({intents:[0]});
|
|
20
|
+
> ```
|
|
21
|
+
>
|
|
22
|
+
> | parameter | type | default | required | description |
|
|
23
|
+
> | --------------- | -------- | ------- | -------- | --------------------------------------------------------------- |
|
|
24
|
+
> | intents | Number[] | none | true | Discord#Intents |
|
|
25
|
+
> | partials | [] | none | false | Discord#Partials |
|
|
26
|
+
> | prefix | String[] | none | false | Prefix for message commands |
|
|
27
|
+
> | ownerId | String[] | none | false | Id(s) of the bot developer(s) |
|
|
28
|
+
> | guildId | String | none | true | local guild Id |
|
|
29
|
+
> | global | Boolean | false | true | Whether the interaction commands are local or global |
|
|
30
|
+
> | ignoreOwner | Boolean | false | false | Whether the bot should ignore execute validation or not |
|
|
31
|
+
> | defaultCooldown | Number | 0 | false | The cooldown a user gets before executing another command |
|
|
32
|
+
> | color | Object | FLAGS | false | This appends colors to the bot |
|
|
33
|
+
> | config | Object | {} | false | Here you can save any info to the bot |
|
|
34
|
+
> | logging | Boolean | false | false | Whether the bot should log any events on ready |
|
|
35
|
+
> | cacheTime | Number | 300000 | false | The amount of time before a message gets deleted from the cache |
|
|
36
|
+
> | messages | Object | {} | false | The location where commands get linked with their executions |
|
|
37
|
+
|
|
38
|
+
## Handlers
|
|
39
|
+
|
|
40
|
+
> Below you can see all the different types of handlers. Each command handler needs it's own folder.
|
|
41
|
+
>
|
|
42
|
+
> ### Commands
|
|
43
|
+
>
|
|
44
|
+
> > ```js
|
|
45
|
+
> > const { Client, CommandHandler } = require("xernerx");
|
|
46
|
+
> >
|
|
47
|
+
> > const client = new Client({ intents: [0] });
|
|
48
|
+
> >
|
|
49
|
+
> > const commandHandler = new CommandHandler({ client: client });
|
|
50
|
+
> > ```
|
|
51
|
+
> >
|
|
52
|
+
> > methods
|
|
53
|
+
> >
|
|
54
|
+
> > - [.loadMessageCommands()](<#.loadMessageCommands()>)
|
|
55
|
+
> > - [.loadInteractionCommands()](<#.loadInteractionCommands()>)
|
|
56
|
+
> > - [.loadContextMenuCommands()](<#.loadContextMenuCommands()>)
|
|
57
|
+
> >
|
|
58
|
+
> > #### .loadMessageCommands()
|
|
59
|
+
> >
|
|
60
|
+
> > The message command handler.
|
|
61
|
+
> >
|
|
62
|
+
> > | parameter | type | default | required | description |
|
|
63
|
+
> > | --------- | ------- | ------- | -------- | ---------------------------------------- |
|
|
64
|
+
> > | path | String | none | true | The path of your message command folder. |
|
|
65
|
+
> > | logging | Boolean | false | false | Whether the bot logs commands on start. |
|
|
66
|
+
> >
|
|
67
|
+
> > #### .loadInteractionCommands()
|
|
68
|
+
> >
|
|
69
|
+
> > The interaction command handler.
|
|
70
|
+
> >
|
|
71
|
+
> > | parameter | type | default | required | description |
|
|
72
|
+
> > | --------- | ------- | ------- | -------- | -------------------------------------------- |
|
|
73
|
+
> > | path | String | none | true | The path of your interaction command folder. |
|
|
74
|
+
> > | logging | Boolean | false | false | Whether the bot logs commands on start. |
|
|
75
|
+
> >
|
|
76
|
+
> > #### .loadContextMenuCommands()
|
|
77
|
+
> >
|
|
78
|
+
> > The context menu command handler.
|
|
79
|
+
> >
|
|
80
|
+
> > | parameter | type | default | required | description |
|
|
81
|
+
> > | --------- | ------- | ------- | -------- | --------------------------------------------- |
|
|
82
|
+
> > | path | String | none | true | The path of your context menu command folder. |
|
|
83
|
+
> > | logging | Boolean | false | false | Whether the bot logs commands on start. |
|
|
84
|
+
>
|
|
85
|
+
> ### Events
|
|
86
|
+
>
|
|
87
|
+
> > The event handler is much simpler than the command handler.
|
|
88
|
+
> >
|
|
89
|
+
> > ```js
|
|
90
|
+
> > const { Client, EventHandler } = require("xernerx");
|
|
91
|
+
> >
|
|
92
|
+
> > const client = new Client({ intents: [0] });
|
|
93
|
+
> >
|
|
94
|
+
> > const eventHandler = new EventHandler({ client: client });
|
|
95
|
+
> > ```
|
|
96
|
+
> >
|
|
97
|
+
> > methods
|
|
98
|
+
> >
|
|
99
|
+
> > - [.loadEvents()](<#.loadEvents()>)
|
|
100
|
+
> >
|
|
101
|
+
> > #### .loadEvents()
|
|
102
|
+
> >
|
|
103
|
+
> > The context menu command handler.
|
|
104
|
+
> >
|
|
105
|
+
> > | parameter | type | default | required | description |
|
|
106
|
+
> > | --------- | ------- | ------- | -------- | ------------------------------------- |
|
|
107
|
+
> > | path | String | none | true | The path of your events folder. |
|
|
108
|
+
> > | logging | Boolean | false | false | Whether the bot logs events on start. |
|
package/models/Client.js
CHANGED
|
@@ -26,10 +26,11 @@ class Client extends Discord.Client {
|
|
|
26
26
|
ignoreOwner: s.boolean.optional,
|
|
27
27
|
defaultCooldown: s.number.optional,
|
|
28
28
|
logging: s.boolean.optional,
|
|
29
|
-
cacheTime: s.number.optional
|
|
29
|
+
cacheTime: s.number.optional,
|
|
30
|
+
dummi: s.boolean.optional
|
|
30
31
|
}).parse(options)
|
|
31
32
|
|
|
32
|
-
this.client = new Discord.Client({ intents: [
|
|
33
|
+
this.client = new Discord.Client({ intents: [options.intents], partials: [options.partials] });
|
|
33
34
|
|
|
34
35
|
this.client.messages = {};
|
|
35
36
|
|
package/models/commands/Event.js
CHANGED
|
@@ -4,21 +4,21 @@ const { s } = require('@sapphire/shapeshift')
|
|
|
4
4
|
* @param {String} id - The id of the event. @required
|
|
5
5
|
* @param {object} options - of the event. @required
|
|
6
6
|
* @param {string} name - The name of the event. @required
|
|
7
|
-
* @param {boolean} once - Whether the event should be ran once or
|
|
7
|
+
* @param {boolean} once - Whether the event should be ran once or continuously.
|
|
8
8
|
*/
|
|
9
9
|
class Event {
|
|
10
10
|
constructor(id, options = {}) {
|
|
11
11
|
s.object({
|
|
12
12
|
name: s.string,
|
|
13
13
|
once: s.boolean.optional,
|
|
14
|
-
|
|
14
|
+
type: s.string.optional
|
|
15
15
|
}).parse(options)
|
|
16
16
|
|
|
17
17
|
this.name = options.name;
|
|
18
18
|
|
|
19
19
|
this.once = options.once || false;
|
|
20
20
|
|
|
21
|
-
this.
|
|
21
|
+
this.type = options.type || 'client';
|
|
22
22
|
|
|
23
23
|
this.config = options.config;
|
|
24
24
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { s } = require('@sapphire/shapeshift');
|
|
2
|
-
const
|
|
2
|
+
const { SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandBuilder, SlashCommandBuilder } = require('discord.js');
|
|
3
3
|
const { toTitleCase } = require('dumfunctions');
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -26,7 +26,7 @@ class InteractionCommand {
|
|
|
26
26
|
inVoice: s.boolean.optional
|
|
27
27
|
}).parse(options);
|
|
28
28
|
|
|
29
|
-
this.data = new
|
|
29
|
+
this.data = new SlashCommandBuilder()
|
|
30
30
|
.setName(options.name)
|
|
31
31
|
.setDescription(options.description)
|
|
32
32
|
|
|
@@ -75,27 +75,23 @@ class InteractionCommand {
|
|
|
75
75
|
const types = ["boolean", "integer", "number", "string", "user", "role", "channel", "mentionable"];
|
|
76
76
|
|
|
77
77
|
for (const argument of args) {
|
|
78
|
-
|
|
79
78
|
if (!types.includes(argument.type.toLowerCase())) throw new Error(`Expected one of ${types.join(', ')}, received ${argument.type} instead.`);
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
else build[`set${toTitleCase(key, true)}`](value);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
80
|
+
where[`add${toTitleCase(argument.type, true)}Option`](option => {
|
|
81
|
+
option
|
|
82
|
+
.setName(argument.name)
|
|
83
|
+
.setDescription(argument.description)
|
|
84
|
+
.setRequired(argument.required || false)
|
|
85
|
+
if (argument.choices) option.setChoices(...argument?.choices);
|
|
91
86
|
|
|
92
|
-
|
|
87
|
+
return option;
|
|
88
|
+
})
|
|
93
89
|
}
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
addSubcommands(where, subs) {
|
|
97
93
|
for (const sub of subs) {
|
|
98
|
-
let subCommand = new
|
|
94
|
+
let subCommand = new SlashCommandSubcommandBuilder()
|
|
99
95
|
.setName(sub.name)
|
|
100
96
|
.setDescription(sub.description);
|
|
101
97
|
if (sub?.args?.length > 0) {
|
|
@@ -107,7 +103,7 @@ class InteractionCommand {
|
|
|
107
103
|
|
|
108
104
|
addSubcommandGroups(groups) {
|
|
109
105
|
for (const group of groups) {
|
|
110
|
-
let subcommandGroup = new
|
|
106
|
+
let subcommandGroup = new SlashCommandSubcommandGroupBuilder()
|
|
111
107
|
.setName(group.name)
|
|
112
108
|
.setDescription(group.description)
|
|
113
109
|
|
package/models/data/Functions.js
CHANGED
|
@@ -77,7 +77,7 @@ class Functions {
|
|
|
77
77
|
|
|
78
78
|
for (const argument of command.args) {
|
|
79
79
|
|
|
80
|
-
let content = message.content.split(separator).slice(i + 1);
|
|
80
|
+
let content = message.content.replace(new RegExp(`${separator}${separator}+`, "g"), separator).split(separator).slice(i + 1);
|
|
81
81
|
|
|
82
82
|
if (content.join(separator) != '') {
|
|
83
83
|
|
|
@@ -85,6 +85,10 @@ class Functions {
|
|
|
85
85
|
args[argument.name] = content[0];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
else if (argument.type == 'string') {
|
|
89
|
+
args[argument.name] = content[0];
|
|
90
|
+
}
|
|
91
|
+
|
|
88
92
|
else if (argument.type == 'number') {
|
|
89
93
|
args[argument.name] = parseInt(content[0]);
|
|
90
94
|
}
|
|
@@ -96,19 +100,25 @@ class Functions {
|
|
|
96
100
|
|
|
97
101
|
else if (argument.type == 'user') {
|
|
98
102
|
let user;
|
|
99
|
-
try { user = await message.client.users.fetch(content[0].replace(
|
|
103
|
+
try { user = await message.client.users.fetch(content[0].replace(/<?@?!?|>?/g, "")) } catch (e) { user = e }
|
|
100
104
|
args[argument.name] = user;
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
else if (argument.type == 'role') {
|
|
108
|
+
let role;
|
|
109
|
+
try { role = await message.guild.roles.fetch(content[0].replace(/<?@?&?|>?/g, "")) } catch (e) { role = e }
|
|
110
|
+
args[argument.name] = role;
|
|
111
|
+
}
|
|
112
|
+
|
|
103
113
|
else if (argument.type == 'member') {
|
|
104
114
|
let member;
|
|
105
|
-
try { member = await message.guild.members.fetch(content[0].replace(
|
|
115
|
+
try { member = await message.guild.members.fetch(content[0].replace(/<?@?!?|>?/g, "")) } catch (e) { member = e }
|
|
106
116
|
args[argument.name] = member;
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
else if (argument.type == 'channel') {
|
|
110
120
|
let channel;
|
|
111
|
-
try { channel = await message.client.channels.fetch(content[0].replace(
|
|
121
|
+
try { channel = await message.client.channels.fetch(content[0].replace(/<?#\?|>?/g, "")) } catch (e) { channel = e }
|
|
112
122
|
args[argument.name] = channel;
|
|
113
123
|
}
|
|
114
124
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const { Event } = require('../commands/Event.js');
|
|
2
2
|
const { interactionArgs, access } = require('./../data/Functions.js');
|
|
3
|
-
const
|
|
4
|
-
|
|
3
|
+
const { InteractionType } = require('discord.js')
|
|
5
4
|
/**
|
|
6
5
|
* @returns interaction command executor.
|
|
7
6
|
*/
|
|
@@ -9,50 +8,49 @@ class BuildInInteractionEvent extends Event {
|
|
|
9
8
|
constructor() {
|
|
10
9
|
super('interactionCreate', {
|
|
11
10
|
name: 'interactionCreate',
|
|
11
|
+
type: 'client',
|
|
12
12
|
once: false,
|
|
13
13
|
})
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
async run(interaction) {
|
|
17
|
-
if (interaction.
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
let command = interaction.client.interactionCommands.get(interaction.commandName);
|
|
17
|
+
if (interaction.type == InteractionType.ApplicationCommand) {
|
|
18
|
+
if (interaction.client.interactionCommands.has(interaction.commandName)) {
|
|
19
|
+
let command = interaction.client.interactionCommands.get(interaction.commandName);
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
command.client = interaction.client;
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
const group = interactionArgs(interaction).group;
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
const subcommand = interactionArgs(interaction).sub;
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
const args = interactionArgs(interaction).options;
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
if (access(interaction, command)) return;
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
try {
|
|
32
|
+
await command.exec(interaction, { group: group, subcommand: subcommand, args: args });
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
return interaction.client.emit('commandRun', interaction, "interaction", command)
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return interaction.client.emit("error", interaction, error);
|
|
38
|
+
}
|
|
39
39
|
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (interaction.isContextMenu()) {
|
|
43
|
-
if (!interaction.client.contextMenuCommands.has(interaction.commandName)) return;
|
|
44
40
|
|
|
45
|
-
|
|
41
|
+
if (interaction.client.contextMenuCommands.has(interaction.commandName)) {
|
|
42
|
+
let command = interaction.client.contextMenuCommands.get(interaction.commandName);
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
command.client = interaction.client;
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
try {
|
|
47
|
+
await command.exec(interaction);
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
return interaction.client.emit('commandRun', interaction, 'contextMenu', command);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return interaction.client.emit("error", interaction, error);
|
|
53
|
+
}
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const Discord = require('discord.js');
|
|
3
3
|
const { REST } = require('@discordjs/rest');
|
|
4
|
-
const { Routes } = require('discord-api-types/
|
|
4
|
+
const { Routes, GatewayVersion } = require('discord-api-types/v10');
|
|
5
5
|
const { delay, logStyle } = require('dumfunctions')
|
|
6
6
|
const paths = require("path")
|
|
7
7
|
|
|
@@ -91,20 +91,25 @@ class CommandHandler {
|
|
|
91
91
|
|
|
92
92
|
#deployCommands(type, logging = false) {
|
|
93
93
|
this.client.once('ready', client => {
|
|
94
|
-
const rest = new REST({ version:
|
|
94
|
+
const rest = new REST({ version: GatewayVersion }).setToken(client.token);
|
|
95
95
|
|
|
96
96
|
(async () => {
|
|
97
|
-
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
try {
|
|
98
|
+
if (client.global == true) {
|
|
99
|
+
if (logging || this.client.logging) console.info(logStyle(`Loaded ${type} in ${(await client.guilds.fetch()).size} server(s) globally.`, 'text', 'purple'));
|
|
100
|
+
rest.put(Routes.applicationCommands(client.user.id), {
|
|
101
|
+
body: this.commands
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
if (logging || this.client.logging) console.info(logStyle(`Loaded ${type} locally.`, 'text', 'purple'));
|
|
106
|
+
rest.put(Routes.applicationGuildCommands(client.user.id, client.guildId), {
|
|
107
|
+
body: this.commands
|
|
108
|
+
})
|
|
109
|
+
}
|
|
102
110
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
rest.put(Routes.applicationGuildCommands(client.user.id, client.guildId), {
|
|
106
|
-
body: this.commands
|
|
107
|
-
})
|
|
111
|
+
catch (e) {
|
|
112
|
+
throw new Error(e)
|
|
108
113
|
}
|
|
109
114
|
})();
|
|
110
115
|
})
|
|
@@ -23,26 +23,19 @@ class EventHandler {
|
|
|
23
23
|
|
|
24
24
|
events.push(event.name);
|
|
25
25
|
|
|
26
|
-
if (event.
|
|
27
|
-
|
|
28
|
-
event.run(...args)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
else if (event.once) {
|
|
33
|
-
this.client.once(event.name, (...args) => {
|
|
34
|
-
event.run(...args);
|
|
26
|
+
if (event.once) {
|
|
27
|
+
this.emitter(event.type).once(event.name, (...args) => {
|
|
28
|
+
event.run(...args)
|
|
35
29
|
})
|
|
36
30
|
}
|
|
37
|
-
|
|
38
31
|
else {
|
|
39
|
-
this.
|
|
32
|
+
this.emitter(event.type).on(event.name, (...args) => {
|
|
40
33
|
event.run(...args)
|
|
41
34
|
})
|
|
42
35
|
}
|
|
43
36
|
}
|
|
44
37
|
|
|
45
|
-
if (logging) console.info(logStyle(`Loaded events: ${events.join(', ')}`, 'text', 'purple'));
|
|
38
|
+
if (logging || this.client.logging) console.info(logStyle(`Loaded events: ${events.join(', ')}`, 'text', 'purple'));
|
|
46
39
|
|
|
47
40
|
const builderFiles = fs.readdirSync(`${__dirname}/../events`).filter(file => file.endsWith('.js'))
|
|
48
41
|
|
|
@@ -51,25 +44,24 @@ class EventHandler {
|
|
|
51
44
|
|
|
52
45
|
event = new event;
|
|
53
46
|
|
|
54
|
-
if (event.
|
|
55
|
-
|
|
56
|
-
event.run(...args)
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
else if (event.once) {
|
|
61
|
-
this.client.once(event.name, (...args) => {
|
|
62
|
-
event.run(...args);
|
|
47
|
+
if (event.once) {
|
|
48
|
+
this.emitter(event.type).once(event.name, (...args) => {
|
|
49
|
+
event.run(...args)
|
|
63
50
|
})
|
|
64
51
|
}
|
|
65
|
-
|
|
66
52
|
else {
|
|
67
|
-
this.
|
|
68
|
-
event.run(...args)
|
|
53
|
+
this.emitter(event.type).on(event.name, (...args) => {
|
|
54
|
+
event.run(...args)
|
|
69
55
|
})
|
|
70
56
|
}
|
|
71
57
|
}
|
|
72
58
|
}
|
|
59
|
+
|
|
60
|
+
emitter(type) {
|
|
61
|
+
if (type == 'client') return this.client;
|
|
62
|
+
if (type == 'rest') return this.client.rest;
|
|
63
|
+
else return eval(type)
|
|
64
|
+
}
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
module.exports = { EventHandler };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xernerx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A bot framework for discord.js. [BETA]",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
},
|
|
18
18
|
"homepage": "https://github.com/TheDummi/xernerx#readme",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@discordjs/builders": "1.0.0",
|
|
21
20
|
"@discordjs/rest": "1.0.0",
|
|
22
21
|
"@sapphire/shapeshift": "3.5.1",
|
|
23
22
|
"discord-api-types": "^0.36.3",
|
|
24
|
-
"discord.js": "^
|
|
23
|
+
"discord.js": "^14.0.3",
|
|
25
24
|
"dumdiscord.js": "^1.0.5",
|
|
26
25
|
"dumfunctions": "^1.0.5",
|
|
27
26
|
"i18next": "^21.8.14"
|