zumito-framework 1.1.55 → 1.1.56
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/dist/TranslationManager.d.ts +1 -1
- package/dist/TranslationManager.js +1 -1
- package/dist/ZumitoFramework.d.ts +6 -6
- package/dist/ZumitoFramework.js +44 -33
- package/dist/baseModule/events/discord/interactionCreate.d.ts +4 -4
- package/dist/baseModule/events/discord/interactionCreate.js +58 -17
- package/dist/baseModule/events/discord/messageCreate.d.ts +3 -3
- package/dist/baseModule/events/discord/messageCreate.js +88 -61
- package/dist/baseModule/index.d.ts +2 -2
- package/dist/baseModule/index.js +4 -4
- package/dist/definitions/ApiResponse.js +2 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/managers/EmojiManager.d.ts +1 -1
- package/dist/types/Command.d.ts +7 -7
- package/dist/types/Command.js +4 -5
- package/dist/types/CommandArguments.d.ts +1 -1
- package/dist/types/CommandParameters.d.ts +3 -3
- package/dist/types/Commands/ButtonPressed.d.ts +1 -1
- package/dist/types/Commands/ButtonPressedParams.d.ts +2 -2
- package/dist/types/EventParameters.d.ts +2 -2
- package/dist/types/Module.d.ts +3 -3
- package/dist/types/Module.js +78 -40
- package/dist/types/SelectMenuParameters.d.ts +2 -2
- package/dist/types/Translation.js +1 -1
- package/dist/utils/EmojiFallback.d.ts +1 -1
- package/dist/utils/EmojiFallback.js +2 -2
- package/package.json +3 -9
- package/plop-templates/command.js.hbs +0 -17
- package/plop-templates/translation.json.hbs +0 -8
- package/plopfile.js +0 -116
- package/templateGenerator.mjs +0 -26
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { GuildMember, TextChannel } from
|
|
2
|
-
import { Command } from
|
|
3
|
-
import { FrameworkSettings } from
|
|
4
|
-
import { Module } from
|
|
5
|
-
import { FrameworkEvent } from
|
|
6
|
-
import { TranslationManager } from
|
|
1
|
+
import { GuildMember, TextChannel } from 'discord.js';
|
|
2
|
+
import { Command } from './types/Command.js';
|
|
3
|
+
import { FrameworkSettings } from './types/FrameworkSettings.js';
|
|
4
|
+
import { Module } from './types/Module.js';
|
|
5
|
+
import { FrameworkEvent } from './types/FrameworkEvent.js';
|
|
6
|
+
import { TranslationManager } from './TranslationManager.js';
|
|
7
7
|
/**
|
|
8
8
|
* @class ZumitoFramework
|
|
9
9
|
* @classdesc The main class of the framework.
|
package/dist/ZumitoFramework.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { SlashCommandBuilder } from
|
|
2
|
-
import { Module } from
|
|
1
|
+
import { SlashCommandBuilder, } from 'discord.js';
|
|
2
|
+
import { Module } from './types/Module.js';
|
|
3
3
|
import { ApiResponse } from './definitions/ApiResponse.js';
|
|
4
|
-
import { baseModule } from
|
|
5
|
-
import { TranslationManager } from
|
|
4
|
+
import { baseModule } from './baseModule/index.js';
|
|
5
|
+
import { TranslationManager } from './TranslationManager.js';
|
|
6
6
|
import express from 'express';
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
|
-
import { Client } from
|
|
9
|
+
import { Client } from 'discord.js';
|
|
10
10
|
// import better-logging
|
|
11
|
-
import { betterLogging } from
|
|
11
|
+
import { betterLogging } from 'better-logging';
|
|
12
12
|
betterLogging(console);
|
|
13
13
|
import { REST } from '@discordjs/rest';
|
|
14
14
|
import { Routes } from 'discord-api-types/v9';
|
|
15
|
-
import mongoose from
|
|
15
|
+
import mongoose from 'mongoose';
|
|
16
16
|
import cookieParser from 'cookie-parser';
|
|
17
17
|
import cors from 'cors';
|
|
18
18
|
import http from 'http';
|
|
19
19
|
import * as url from 'url';
|
|
20
|
-
import { CommandType } from
|
|
20
|
+
import { CommandType } from './types/CommandType.js';
|
|
21
21
|
/**
|
|
22
22
|
* @class ZumitoFramework
|
|
23
23
|
* @classdesc The main class of the framework.
|
|
@@ -62,10 +62,12 @@ export class ZumitoFramework {
|
|
|
62
62
|
if (settings.logLevel) {
|
|
63
63
|
console.logLevel = settings.logLevel;
|
|
64
64
|
}
|
|
65
|
-
this.initialize()
|
|
65
|
+
this.initialize()
|
|
66
|
+
.then(() => {
|
|
66
67
|
if (callback)
|
|
67
68
|
callback(this);
|
|
68
|
-
})
|
|
69
|
+
})
|
|
70
|
+
.catch((err) => {
|
|
69
71
|
console.error(err, err.message, err.stack, err.name);
|
|
70
72
|
});
|
|
71
73
|
}
|
|
@@ -75,7 +77,7 @@ export class ZumitoFramework {
|
|
|
75
77
|
await mongoose.connect(this.settings.mongoQueryString);
|
|
76
78
|
}
|
|
77
79
|
catch (err) {
|
|
78
|
-
console.error(
|
|
80
|
+
console.error('[🗄️🔴] Database connection error:', err.message);
|
|
79
81
|
process.exit(1);
|
|
80
82
|
}
|
|
81
83
|
finally {
|
|
@@ -89,9 +91,9 @@ export class ZumitoFramework {
|
|
|
89
91
|
}
|
|
90
92
|
startApiServer() {
|
|
91
93
|
this.app = express();
|
|
92
|
-
|
|
94
|
+
const port = process.env.PORT || '80';
|
|
93
95
|
this.app.set('port', port);
|
|
94
|
-
|
|
96
|
+
const server = http.createServer(this.app);
|
|
95
97
|
server.listen(port);
|
|
96
98
|
server.on('error', (err) => {
|
|
97
99
|
console.log('[🌐🔴] Error starting API web server: ' + err);
|
|
@@ -109,12 +111,12 @@ export class ZumitoFramework {
|
|
|
109
111
|
//this.app.use("/", indexRouter);
|
|
110
112
|
//this.app.use("/api/", apiRouter);
|
|
111
113
|
// throw 404 if URL not found
|
|
112
|
-
this.app.all(
|
|
113
|
-
return ApiResponse.notFoundResponse(res,
|
|
114
|
+
this.app.all('*', function (req, res) {
|
|
115
|
+
return ApiResponse.notFoundResponse(res, 'Page not found');
|
|
114
116
|
});
|
|
115
117
|
this.app.use(function (err, req, res) {
|
|
116
118
|
if (err.name === 'UnauthorizedError') {
|
|
117
|
-
return ApiResponse.unauthorizedResponse(res,
|
|
119
|
+
return ApiResponse.unauthorizedResponse(res, 'Invalid token');
|
|
118
120
|
}
|
|
119
121
|
});
|
|
120
122
|
}
|
|
@@ -130,8 +132,8 @@ export class ZumitoFramework {
|
|
|
130
132
|
return;
|
|
131
133
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
132
134
|
await this.registerModule(__dirname, 'baseModule', baseModule);
|
|
133
|
-
|
|
134
|
-
for (
|
|
135
|
+
const files = fs.readdirSync(modulesFolder);
|
|
136
|
+
for (const file of files) {
|
|
135
137
|
await this.registerModule(modulesFolder, file);
|
|
136
138
|
}
|
|
137
139
|
this.models.forEach((modelDefinition, modelName) => {
|
|
@@ -152,7 +154,6 @@ export class ZumitoFramework {
|
|
|
152
154
|
else {
|
|
153
155
|
module = Module;
|
|
154
156
|
}
|
|
155
|
-
;
|
|
156
157
|
}
|
|
157
158
|
// Create module instance
|
|
158
159
|
let moduleInstance;
|
|
@@ -171,7 +172,10 @@ export class ZumitoFramework {
|
|
|
171
172
|
this.commands.set(command.name, command);
|
|
172
173
|
});
|
|
173
174
|
}
|
|
174
|
-
this.commands = new Map([
|
|
175
|
+
this.commands = new Map([
|
|
176
|
+
...this.commands,
|
|
177
|
+
...moduleInstance.getCommands(),
|
|
178
|
+
]);
|
|
175
179
|
// Register module events
|
|
176
180
|
this.events = new Map([...this.events, ...moduleInstance.getEvents()]);
|
|
177
181
|
// Register models
|
|
@@ -192,7 +196,7 @@ export class ZumitoFramework {
|
|
|
192
196
|
}
|
|
193
197
|
initializeDiscordClient() {
|
|
194
198
|
this.client = new Client({
|
|
195
|
-
intents: this.settings.discordClientOptions.intents
|
|
199
|
+
intents: this.settings.discordClientOptions.intents,
|
|
196
200
|
});
|
|
197
201
|
this.client.login(this.settings.discordClientOptions.token);
|
|
198
202
|
this.client.on('ready', () => {
|
|
@@ -204,7 +208,7 @@ export class ZumitoFramework {
|
|
|
204
208
|
//log( 'commandLine', commandLine ) ;
|
|
205
209
|
// Find a unique marker for the space character.
|
|
206
210
|
// Start with '<SP>' and repeatedly append '@' if necessary to make it unique.
|
|
207
|
-
|
|
211
|
+
let spaceMarker = '<SP>';
|
|
208
212
|
while (commandLine.indexOf(spaceMarker) > -1)
|
|
209
213
|
spaceMarker += '@';
|
|
210
214
|
// Protect double-quoted strings.
|
|
@@ -213,19 +217,19 @@ export class ZumitoFramework {
|
|
|
213
217
|
// o Replace each double-quoted-string with what's inside the qouble-quotes,
|
|
214
218
|
// after each space character has been replaced with the space-marker above.
|
|
215
219
|
// o The outer double-quotes will not be present.
|
|
216
|
-
|
|
220
|
+
const noSpacesInQuotes = commandLine.replace(/"([^"]*)"?/g, (fullMatch, capture) => {
|
|
217
221
|
return capture.replace(/ /g, spaceMarker);
|
|
218
222
|
});
|
|
219
223
|
// Now that it is safe to do so, split the command-line at one-or-more spaces.
|
|
220
|
-
|
|
224
|
+
const mangledParamArray = noSpacesInQuotes.split(/ +/);
|
|
221
225
|
// Create a new array by restoring spaces from any space-markers.
|
|
222
|
-
|
|
226
|
+
const paramArray = mangledParamArray.map((mangledParam) => {
|
|
223
227
|
return mangledParam.replace(RegExp(spaceMarker, 'g'), ' ');
|
|
224
228
|
});
|
|
225
229
|
return paramArray;
|
|
226
230
|
}
|
|
227
231
|
async memberHasPermission(member, channel, permission) {
|
|
228
|
-
|
|
232
|
+
const memberPermission = await channel.permissionsFor(member);
|
|
229
233
|
return memberPermission.has(permission);
|
|
230
234
|
}
|
|
231
235
|
async getGuildSettings(guildId) {
|
|
@@ -241,10 +245,12 @@ export class ZumitoFramework {
|
|
|
241
245
|
}
|
|
242
246
|
async refreshSlashCommands() {
|
|
243
247
|
const rest = new REST({ version: '10' }).setToken(this.settings.discordClientOptions.token);
|
|
244
|
-
|
|
245
|
-
.filter((command) => command.type == CommandType.slash ||
|
|
248
|
+
const commands = Array.from(this.commands.values())
|
|
249
|
+
.filter((command) => command.type == CommandType.slash ||
|
|
250
|
+
command.type == CommandType.separated ||
|
|
251
|
+
command.type == CommandType.any)
|
|
246
252
|
.map((command) => {
|
|
247
|
-
|
|
253
|
+
const slashCommand = new SlashCommandBuilder()
|
|
248
254
|
.setName(command.name)
|
|
249
255
|
.setDescription(this.translations.get('command.' + command.name + '.description', 'en'));
|
|
250
256
|
if (command.args) {
|
|
@@ -269,17 +275,22 @@ export class ZumitoFramework {
|
|
|
269
275
|
}
|
|
270
276
|
slashCommand[method]((option) => {
|
|
271
277
|
option.setName(arg.name);
|
|
272
|
-
option.setDescription(this.translations.get('command.' +
|
|
278
|
+
option.setDescription(this.translations.get('command.' +
|
|
279
|
+
command.name +
|
|
280
|
+
'.args.' +
|
|
281
|
+
arg.name +
|
|
282
|
+
'.description', 'en'));
|
|
273
283
|
option.setRequired(!arg.optional);
|
|
274
284
|
if (arg.choices) {
|
|
275
285
|
// if arg.choices is function, call it
|
|
276
286
|
if (typeof arg.choices == 'function') {
|
|
277
|
-
arg.choices =
|
|
287
|
+
arg.choices =
|
|
288
|
+
arg.choices();
|
|
278
289
|
}
|
|
279
290
|
arg.choices.forEach((choice) => {
|
|
280
291
|
option.addChoices({
|
|
281
292
|
name: choice.name,
|
|
282
|
-
value: choice.value
|
|
293
|
+
value: choice.value,
|
|
283
294
|
});
|
|
284
295
|
});
|
|
285
296
|
}
|
|
@@ -294,7 +305,7 @@ export class ZumitoFramework {
|
|
|
294
305
|
}
|
|
295
306
|
}
|
|
296
307
|
function MergeRecursive(obj1, obj2) {
|
|
297
|
-
for (
|
|
308
|
+
for (const p in obj2) {
|
|
298
309
|
try {
|
|
299
310
|
// Property in destination object set; update its value.
|
|
300
311
|
if (obj2[p].constructor == Object) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { EventParameters } from
|
|
3
|
-
import { FrameworkEvent } from
|
|
1
|
+
import { Command } from '../../../types/Command.js';
|
|
2
|
+
import { EventParameters } from '../../../types/EventParameters.js';
|
|
3
|
+
import { FrameworkEvent } from '../../../types/FrameworkEvent.js';
|
|
4
4
|
export declare class InteractionCreate extends FrameworkEvent {
|
|
5
5
|
once: boolean;
|
|
6
|
-
execute({ interaction, client, framework }: EventParameters): Promise<void>;
|
|
6
|
+
execute({ interaction, client, framework, }: EventParameters): Promise<void>;
|
|
7
7
|
getTransMethod(commandInstance: Command, framework: any, guildSettings: any): (key: string, params?: any) => any;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CommandType } from
|
|
2
|
-
import { FrameworkEvent } from
|
|
1
|
+
import { CommandType } from '../../../types/CommandType.js';
|
|
2
|
+
import { FrameworkEvent } from '../../../types/FrameworkEvent.js';
|
|
3
3
|
export class InteractionCreate extends FrameworkEvent {
|
|
4
4
|
once = false;
|
|
5
|
-
async execute({ interaction, client, framework }) {
|
|
5
|
+
async execute({ interaction, client, framework, }) {
|
|
6
6
|
let guildSettings;
|
|
7
7
|
if (interaction.guildId) {
|
|
8
8
|
guildSettings = await framework.getGuildSettings(interaction.guildId);
|
|
@@ -11,46 +11,80 @@ export class InteractionCreate extends FrameworkEvent {
|
|
|
11
11
|
if (!framework.commands.has(interaction.commandName))
|
|
12
12
|
return;
|
|
13
13
|
const commandInstance = framework.commands.get(interaction.commandName);
|
|
14
|
-
|
|
15
|
-
commandInstance.args.forEach(arg => {
|
|
16
|
-
|
|
14
|
+
const args = new Map();
|
|
15
|
+
commandInstance.args.forEach((arg) => {
|
|
16
|
+
const option = interaction.options.get(arg.name);
|
|
17
17
|
if (option) {
|
|
18
18
|
switch (arg.type) {
|
|
19
|
-
case
|
|
19
|
+
case 'user':
|
|
20
20
|
args.set(arg.name, option.user);
|
|
21
21
|
break;
|
|
22
|
-
case
|
|
22
|
+
case 'member':
|
|
23
23
|
args.set(arg.name, option.member);
|
|
24
24
|
break;
|
|
25
25
|
default:
|
|
26
|
-
args.set(arg.name, option.value ||
|
|
26
|
+
args.set(arg.name, option.value ||
|
|
27
|
+
option.user ||
|
|
28
|
+
option.role ||
|
|
29
|
+
option.channel ||
|
|
30
|
+
option.options ||
|
|
31
|
+
option.message ||
|
|
32
|
+
option.member ||
|
|
33
|
+
option.focused ||
|
|
34
|
+
option.autocomplete ||
|
|
35
|
+
option.attachment);
|
|
27
36
|
break;
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
});
|
|
31
|
-
if (![
|
|
40
|
+
if (![
|
|
41
|
+
CommandType.any,
|
|
42
|
+
CommandType.separated,
|
|
43
|
+
CommandType.slash,
|
|
44
|
+
].includes(commandInstance.type))
|
|
32
45
|
return;
|
|
33
46
|
const trans = this.getTransMethod(commandInstance, guildSettings, framework);
|
|
34
|
-
if (commandInstance.type === CommandType.separated ||
|
|
35
|
-
|
|
47
|
+
if (commandInstance.type === CommandType.separated ||
|
|
48
|
+
commandInstance.type === CommandType.slash) {
|
|
49
|
+
await commandInstance.executeSlashCommand({
|
|
50
|
+
client,
|
|
51
|
+
interaction,
|
|
52
|
+
args,
|
|
53
|
+
framework,
|
|
54
|
+
guildSettings,
|
|
55
|
+
trans,
|
|
56
|
+
});
|
|
36
57
|
}
|
|
37
58
|
else {
|
|
38
|
-
await commandInstance.execute({
|
|
59
|
+
await commandInstance.execute({
|
|
60
|
+
client,
|
|
61
|
+
interaction,
|
|
62
|
+
args,
|
|
63
|
+
framework,
|
|
64
|
+
guildSettings,
|
|
65
|
+
trans,
|
|
66
|
+
});
|
|
39
67
|
}
|
|
40
68
|
}
|
|
41
69
|
else if (interaction.isButton()) {
|
|
42
70
|
interaction = interaction;
|
|
43
|
-
|
|
71
|
+
const path = interaction.customId.split('.');
|
|
44
72
|
const commandInstance = framework.commands.get(path[0]);
|
|
45
73
|
if (!commandInstance)
|
|
46
74
|
throw new Error(`Command ${path[0]} not found or button id bad formatted`);
|
|
47
75
|
// If the command has impements ButtonPress class then execute the method
|
|
48
76
|
if (commandInstance.constructor.prototype.hasOwnProperty('buttonPressed')) {
|
|
49
|
-
commandInstance.buttonPressed({
|
|
77
|
+
commandInstance.buttonPressed({
|
|
78
|
+
path,
|
|
79
|
+
interaction,
|
|
80
|
+
client,
|
|
81
|
+
framework,
|
|
82
|
+
guildSettings,
|
|
83
|
+
});
|
|
50
84
|
}
|
|
51
85
|
}
|
|
52
86
|
else if (interaction.isSelectMenu()) {
|
|
53
|
-
|
|
87
|
+
const path = interaction.customId.split('.');
|
|
54
88
|
const commandInstance = framework.commands.get(path[0]);
|
|
55
89
|
if (!commandInstance)
|
|
56
90
|
throw new Error(`Command ${path[0]} not found or select menu id bad formatted`);
|
|
@@ -63,7 +97,14 @@ export class InteractionCreate extends FrameworkEvent {
|
|
|
63
97
|
}
|
|
64
98
|
};
|
|
65
99
|
if (commandInstance.selectMenu) {
|
|
66
|
-
commandInstance.selectMenu({
|
|
100
|
+
commandInstance.selectMenu({
|
|
101
|
+
path,
|
|
102
|
+
interaction,
|
|
103
|
+
client,
|
|
104
|
+
framework,
|
|
105
|
+
guildSettings,
|
|
106
|
+
trans,
|
|
107
|
+
});
|
|
67
108
|
}
|
|
68
109
|
}
|
|
69
110
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ActionRowBuilder, EmbedBuilder } from
|
|
2
|
-
import { EventParameters } from
|
|
3
|
-
import { FrameworkEvent } from
|
|
1
|
+
import { ActionRowBuilder, EmbedBuilder } from 'discord.js';
|
|
2
|
+
import { EventParameters } from '../../../types/EventParameters.js';
|
|
3
|
+
import { FrameworkEvent } from '../../../types/FrameworkEvent.js';
|
|
4
4
|
export declare class MessageCreate extends FrameworkEvent {
|
|
5
5
|
once: boolean;
|
|
6
6
|
execute({ message, client, framework }: EventParameters): Promise<import("discord.js").Message<boolean>>;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import * as url from 'url';
|
|
2
|
-
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionsBitField } from
|
|
2
|
+
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionsBitField, } from 'discord.js';
|
|
3
3
|
import ErrorStackParser from 'error-stack-parser';
|
|
4
|
-
import { FrameworkEvent } from
|
|
5
|
-
import { ZumitoFramework } from
|
|
4
|
+
import { FrameworkEvent } from '../../../types/FrameworkEvent.js';
|
|
5
|
+
import { ZumitoFramework } from '../../../ZumitoFramework.js';
|
|
6
6
|
import leven from 'leven';
|
|
7
|
-
import path from
|
|
7
|
+
import path from 'path';
|
|
8
8
|
export class MessageCreate extends FrameworkEvent {
|
|
9
9
|
once = false;
|
|
10
10
|
async execute({ message, client, framework }) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const channel = message.channel;
|
|
12
|
+
const prefix = framework.settings.defaultPrefix;
|
|
13
13
|
const args = ZumitoFramework.splitCommandLine(message.content.slice(prefix.length));
|
|
14
14
|
const command = args.shift().toLowerCase();
|
|
15
15
|
let commandInstance;
|
|
16
16
|
if (message.content.startsWith(prefix)) {
|
|
17
17
|
if (!framework.commands.has(command)) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const commandNames = Array.from(framework.commands.keys());
|
|
19
|
+
const correctedCommand = this.autocorrect(command, commandNames);
|
|
20
20
|
if (framework.commands.has(correctedCommand)) {
|
|
21
21
|
commandInstance = framework.commands.get(correctedCommand);
|
|
22
22
|
}
|
|
@@ -29,11 +29,13 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
29
29
|
}
|
|
30
30
|
if (message.guild == null && commandInstance.dm == false)
|
|
31
31
|
return;
|
|
32
|
-
if (commandInstance.adminOnly ||
|
|
32
|
+
if (commandInstance.adminOnly ||
|
|
33
|
+
commandInstance.userPermissions.length > 0) {
|
|
33
34
|
let denied = false;
|
|
34
|
-
if (framework.memberHasPermission(message.member, message.channel, PermissionsBitField.Flags.Administrator) ||
|
|
35
|
+
if (framework.memberHasPermission(message.member, message.channel, PermissionsBitField.Flags.Administrator) ||
|
|
36
|
+
message.member.id != message.guild.ownerId) {
|
|
35
37
|
if (commandInstance.userPermissions.length > 0) {
|
|
36
|
-
commandInstance.userPermissions.forEach(permission => {
|
|
38
|
+
commandInstance.userPermissions.forEach((permission) => {
|
|
37
39
|
if (!framework.memberHasPermission(message.member, message.channel, permission)) {
|
|
38
40
|
denied = true;
|
|
39
41
|
}
|
|
@@ -45,29 +47,34 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
45
47
|
content: 'You do not have permission to use this command.',
|
|
46
48
|
allowedMentions: {
|
|
47
49
|
repliedUser: false,
|
|
48
|
-
}
|
|
50
|
+
},
|
|
49
51
|
});
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
if (message.channel.isTextBased) {
|
|
53
|
-
|
|
55
|
+
const channel = message.channel;
|
|
54
56
|
// Check command is nsfw and if channel is allowed
|
|
55
|
-
if (commandInstance.nsfw &&
|
|
57
|
+
if (commandInstance.nsfw &&
|
|
58
|
+
!channel.nsfw &&
|
|
59
|
+
!channel
|
|
60
|
+
.permissionsFor(message.member)
|
|
61
|
+
.has(PermissionsBitField.Flags.Administrator) &&
|
|
62
|
+
message.member.id != message.guild.ownerId) {
|
|
56
63
|
return message.reply({
|
|
57
64
|
content: 'This command is nsfw and this channel is not nsfw.',
|
|
58
65
|
allowedMentions: {
|
|
59
66
|
repliedUser: false,
|
|
60
|
-
}
|
|
67
|
+
},
|
|
61
68
|
});
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
const guildSettings = await framework.getGuildSettings(message.guildId);
|
|
73
|
+
const parsedArgs = new Map();
|
|
74
|
+
const userMentionCount = 0;
|
|
68
75
|
for (let i = 0; i < args.length; i++) {
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
const arg = args[i];
|
|
77
|
+
const type = commandInstance.args[i]?.type;
|
|
71
78
|
if (type) {
|
|
72
79
|
if (type == 'member' || type == 'user') {
|
|
73
80
|
const member = await message.guild.members.cache.get(arg.replace(/[<@!>]/g, ''));
|
|
@@ -84,7 +91,7 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
84
91
|
content: 'Invalid user.',
|
|
85
92
|
allowedMentions: {
|
|
86
93
|
repliedUser: false,
|
|
87
|
-
}
|
|
94
|
+
},
|
|
88
95
|
});
|
|
89
96
|
}
|
|
90
97
|
}
|
|
@@ -106,14 +113,15 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
106
113
|
else {
|
|
107
114
|
return framework.translations.get('command.' + commandInstance.name + '.' + key, guildSettings.lang, params);
|
|
108
115
|
}
|
|
109
|
-
}
|
|
116
|
+
},
|
|
110
117
|
});
|
|
111
|
-
if (!message.channel.isDMBased && !message.deletable &&
|
|
118
|
+
if (!message.channel.isDMBased && !message.deletable && false) {
|
|
119
|
+
// false = settings.deleteCommands
|
|
112
120
|
try {
|
|
113
121
|
message.delete().catch(function () {
|
|
114
|
-
console.error(
|
|
122
|
+
console.error("can't delete user command");
|
|
115
123
|
});
|
|
116
|
-
const metadata = await fetch('https://tulipo.ga/api/last_command/' + command).then(res => res.json());
|
|
124
|
+
const metadata = await fetch('https://tulipo.ga/api/last_command/' + command).then((res) => res.json());
|
|
117
125
|
}
|
|
118
126
|
catch (err) {
|
|
119
127
|
console.error(err.name, err.message);
|
|
@@ -121,7 +129,7 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
131
|
catch (error) {
|
|
124
|
-
|
|
132
|
+
const content = await this.getErrorEmbed({
|
|
125
133
|
name: error.name,
|
|
126
134
|
message: error.message,
|
|
127
135
|
command: commandInstance,
|
|
@@ -138,9 +146,9 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
138
146
|
}
|
|
139
147
|
}
|
|
140
148
|
autocorrect(str, words) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
let distance, bestWord, i, word, min;
|
|
150
|
+
const dictionary = words || [];
|
|
151
|
+
const len = dictionary.length;
|
|
144
152
|
for (i = 0; i < len; i++) {
|
|
145
153
|
word = dictionary[i];
|
|
146
154
|
distance = leven(str, word);
|
|
@@ -162,60 +170,77 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
162
170
|
else {
|
|
163
171
|
parsedError = error;
|
|
164
172
|
}
|
|
165
|
-
|
|
173
|
+
const embed = new EmbedBuilder()
|
|
166
174
|
.setTitle('Error')
|
|
167
175
|
.setDescription('An error has occured while executing this command.')
|
|
168
176
|
.setTimestamp()
|
|
169
|
-
.addFields([
|
|
177
|
+
.addFields([
|
|
178
|
+
{
|
|
170
179
|
name: 'Command:',
|
|
171
|
-
value:
|
|
172
|
-
}
|
|
173
|
-
|
|
180
|
+
value: error.command.name || 'Not defined',
|
|
181
|
+
},
|
|
182
|
+
])
|
|
183
|
+
.addFields([
|
|
184
|
+
{
|
|
174
185
|
name: 'Arguments:',
|
|
175
|
-
value:
|
|
176
|
-
}
|
|
177
|
-
|
|
186
|
+
value: error.args.toString() || 'None',
|
|
187
|
+
},
|
|
188
|
+
])
|
|
189
|
+
.addFields([
|
|
190
|
+
{
|
|
178
191
|
name: 'Error name:',
|
|
179
|
-
value:
|
|
180
|
-
}
|
|
181
|
-
|
|
192
|
+
value: error.name || 'Not defined',
|
|
193
|
+
},
|
|
194
|
+
])
|
|
195
|
+
.addFields([
|
|
196
|
+
{
|
|
182
197
|
name: 'Error message:',
|
|
183
|
-
value:
|
|
184
|
-
}
|
|
198
|
+
value: error.message || 'Not defined',
|
|
199
|
+
},
|
|
200
|
+
]);
|
|
185
201
|
if (error.possibleSolutions !== undefined) {
|
|
186
202
|
error.possibleSolutions.forEach((solution) => {
|
|
187
|
-
embed.addFields([
|
|
203
|
+
embed.addFields([
|
|
204
|
+
{
|
|
188
205
|
name: 'Posible solution:',
|
|
189
|
-
value: solution
|
|
190
|
-
}
|
|
206
|
+
value: solution,
|
|
207
|
+
},
|
|
208
|
+
]);
|
|
191
209
|
});
|
|
192
210
|
}
|
|
193
|
-
|
|
211
|
+
const stackFrames = ErrorStackParser.parse(error).filter((e) => !e.fileName.includes('node_modules') &&
|
|
212
|
+
!e.fileName.includes('node:internal'));
|
|
194
213
|
let stack = '';
|
|
195
214
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
196
|
-
|
|
197
|
-
|
|
215
|
+
const path1 = path.resolve('./');
|
|
216
|
+
const path2 = path1.replaceAll('\\', '/');
|
|
198
217
|
stackFrames.forEach((frame) => {
|
|
199
|
-
stack += `[${frame.fileName
|
|
218
|
+
stack += `[${frame.fileName
|
|
219
|
+
.replace(path1, '')
|
|
220
|
+
.replace(path2, '')
|
|
221
|
+
.replace('file://', '')}:${frame.lineNumber}](https://zumito.ga/redirect?url=vscode://file/${frame.fileName.replace('file://', '')}:${frame.lineNumber}) ${frame.functionName}()\n`;
|
|
200
222
|
});
|
|
201
223
|
if (error.stack !== undefined) {
|
|
202
|
-
embed.addFields([
|
|
224
|
+
embed.addFields([
|
|
225
|
+
{
|
|
203
226
|
name: 'Call stack:',
|
|
204
|
-
value: stack || error.stack || error.stack.toString()
|
|
205
|
-
}
|
|
227
|
+
value: stack || error.stack || error.stack.toString(),
|
|
228
|
+
},
|
|
229
|
+
]);
|
|
206
230
|
}
|
|
207
231
|
if (error.details !== undefined) {
|
|
208
232
|
error.details.forEach((detail) => {
|
|
209
|
-
embed.addFields([
|
|
233
|
+
embed.addFields([
|
|
234
|
+
{
|
|
210
235
|
name: 'Detail:',
|
|
211
|
-
value: detail
|
|
212
|
-
}
|
|
236
|
+
value: detail,
|
|
237
|
+
},
|
|
238
|
+
]);
|
|
213
239
|
});
|
|
214
240
|
}
|
|
215
241
|
const body = `\n\n\n---\nComand:\`\`\`${error.command.name || 'not defined'}\`\`\`\nArguments:\`\`\`${error.args.toString() || 'none'}\`\`\`\nError:\`\`\`${error.name || 'not defined'}\`\`\`\nError message:\`\`\`${error.message || 'not defined'}\`\`\`\n`;
|
|
216
242
|
const requestUrl = `https://github.com/ZumitoTeam/Zumito/issues/new?body=${encodeURIComponent(body)}`;
|
|
217
|
-
const row = new ActionRowBuilder()
|
|
218
|
-
.addComponents(new ButtonBuilder()
|
|
243
|
+
const row = new ActionRowBuilder().addComponents(new ButtonBuilder()
|
|
219
244
|
.setStyle(ButtonStyle.Link)
|
|
220
245
|
.setLabel('Report error')
|
|
221
246
|
.setEmoji('975645505302437978')
|
|
@@ -224,17 +249,19 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
224
249
|
embeds: [embed],
|
|
225
250
|
components: [row],
|
|
226
251
|
allowedMentions: {
|
|
227
|
-
repliedUser: false
|
|
228
|
-
}
|
|
252
|
+
repliedUser: false,
|
|
253
|
+
},
|
|
229
254
|
};
|
|
230
255
|
}
|
|
231
256
|
parseError(error) {
|
|
232
257
|
error.possibleSolutions = [];
|
|
233
258
|
if (/(?:^|(?<= ))(EmbedBuilder|Discord|ActionRowBuilder|ButtonBuilder|MessageSelectMenu)(?:(?= )|$) is not defined/gm.test(error.message)) {
|
|
234
|
-
error.possibleSolutions.push('const { ' +
|
|
259
|
+
error.possibleSolutions.push('const { ' +
|
|
260
|
+
error.message.split(' ')[0] +
|
|
261
|
+
" } = require('discord.js');");
|
|
235
262
|
}
|
|
236
263
|
else if (error.message.includes('A custom id and url cannot both be specified')) {
|
|
237
|
-
error.possibleSolutions.push(
|
|
264
|
+
error.possibleSolutions.push('Remove .setCustomId(...) or .setURL(...)');
|
|
238
265
|
}
|
|
239
266
|
return error;
|
|
240
267
|
}
|