zumito-framework 1.1.32 → 1.1.34

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.
@@ -1,4 +1,4 @@
1
- import { Translation } from "./types/Translation";
1
+ import { Translation } from "./types/Translation.js";
2
2
  export declare class TranslationManager {
3
3
  private translations;
4
4
  private defaultLanguage;
@@ -1,17 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TranslationManager = void 0;
4
- const Translation_1 = require("./types/Translation");
5
- class TranslationManager {
1
+ import { Translation } from "./types/Translation.js";
2
+ export class TranslationManager {
6
3
  translations = new Map();
7
4
  defaultLanguage = 'en';
8
5
  constructor() { }
9
6
  get(key, language, params) {
10
- return this.translations.get(key).get(language, params);
7
+ if (this.translations.has(key)) {
8
+ return this.translations.get(key).get(language, params);
9
+ }
10
+ else {
11
+ return key;
12
+ }
11
13
  }
12
14
  set(key, language, text) {
13
15
  if (!this.translations.has(key)) {
14
- this.translations.set(key, new Translation_1.Translation());
16
+ this.translations.set(key, new Translation());
15
17
  }
16
18
  this.translations.get(key).set(language, text);
17
19
  }
@@ -31,4 +33,3 @@ class TranslationManager {
31
33
  this.defaultLanguage = language;
32
34
  }
33
35
  }
34
- exports.TranslationManager = TranslationManager;
@@ -1,9 +1,9 @@
1
1
  import { GuildMember, TextChannel } from "discord.js";
2
- import { Command } from "./types/Commands";
3
- import { FrameworkSettings } from "./types/FrameworkSettings";
4
- import { Module } from "./types/Module";
5
- import { FrameworkEvent } from "./types/FrameworkEvent";
6
- import { TranslationManager } from "./TranslationManager";
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.
@@ -1,21 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ZumitoFramework = void 0;
4
- const Module_1 = require("./types/Module");
5
- const ApiResponse_1 = require("./definitions/ApiResponse");
6
- const baseModule_1 = require("./baseModule");
7
- const TranslationManager_1 = require("./TranslationManager");
8
- const express = require("express");
9
- const fs = require('fs');
10
- const path = require('path');
11
- const { Collection, Client } = require('discord.js');
12
- require('better-logging')(console);
13
- const { REST } = require('@discordjs/rest');
14
- const { Routes } = require('discord-api-types/v9');
15
- var mongoose = require("mongoose");
16
- var cookieParser = require("cookie-parser");
17
- var cors = require("cors");
18
- var http = require('http');
1
+ import { Module } from "./types/Module.js";
2
+ import { ApiResponse } from './definitions/ApiResponse.js';
3
+ import { baseModule } from "./baseModule/index.js";
4
+ import { TranslationManager } from "./TranslationManager.js";
5
+ import express from 'express';
6
+ import * as fs from 'fs';
7
+ import path from 'path';
8
+ import { Client } from "discord.js";
9
+ // import better-logging
10
+ import { betterLogging } from "better-logging";
11
+ betterLogging(console);
12
+ import mongoose from "mongoose";
13
+ import cookieParser from 'cookie-parser';
14
+ import cors from 'cors';
15
+ import http from 'http';
16
+ import * as url from 'url';
19
17
  /**
20
18
  * @class ZumitoFramework
21
19
  * @classdesc The main class of the framework.
@@ -25,13 +23,13 @@ var http = require('http');
25
23
  * @property {Collection<string, Module>} modules - The modules loaded in the framework.
26
24
  * @property {Collection<string, Command>} commands - The commands loaded in the framework.
27
25
  */
28
- class ZumitoFramework {
26
+ export class ZumitoFramework {
29
27
  client;
30
28
  settings;
31
29
  modules;
32
30
  commands;
33
31
  events;
34
- translations = new TranslationManager_1.TranslationManager();
32
+ translations;
35
33
  routes;
36
34
  models;
37
35
  database;
@@ -55,30 +53,33 @@ class ZumitoFramework {
55
53
  this.modules = new Map();
56
54
  this.commands = new Map();
57
55
  this.events = new Map();
58
- this.translations = new TranslationManager_1.TranslationManager();
56
+ this.translations = new TranslationManager();
59
57
  this.models = new Map();
58
+ if (settings.logLevel) {
59
+ console.logLevel = settings.logLevel;
60
+ }
60
61
  this.initialize().then(() => {
61
62
  if (callback)
62
- callback();
63
+ callback(this);
63
64
  }).catch(err => {
64
- console.error(err);
65
+ console.error(err, err.message, err.stack, err.name);
65
66
  });
66
67
  }
67
68
  async initialize() {
68
69
  try {
69
- await mongoose.connect(this.settings.mongoQueryString, { useNewUrlParser: true, useUnifiedTopology: true });
70
+ await mongoose.connect(this.settings.mongoQueryString);
70
71
  }
71
72
  catch (err) {
72
- console.error("[] Database connection error:", err.message);
73
+ console.error("[🗄️🔴] Database connection error:", err.message);
73
74
  process.exit(1);
74
75
  }
75
76
  finally {
76
- console.log('[] Database connection successful');
77
+ console.log('[🗄️🟢] Database connection successful');
77
78
  this.database = mongoose.connection;
78
79
  }
79
80
  this.initializeDiscordClient();
80
81
  this.startApiServer();
81
- this.registerModules();
82
+ await this.registerModules();
82
83
  }
83
84
  startApiServer() {
84
85
  this.app = express();
@@ -87,10 +88,10 @@ class ZumitoFramework {
87
88
  var server = http.createServer(this.app);
88
89
  server.listen(port);
89
90
  server.on('error', (err) => {
90
- console.log('[] Error starting API web server: ' + err);
91
+ console.log('[🌐🔴] Error starting API web server: ' + err);
91
92
  });
92
93
  server.on('listening', () => {
93
- console.log('[] API web server listening on port ' + port);
94
+ console.log('[🌐🟢] API web server listening on port ' + port);
94
95
  });
95
96
  this.app.use(express.json());
96
97
  this.app.use(express.urlencoded({ extended: false }));
@@ -103,15 +104,15 @@ class ZumitoFramework {
103
104
  //this.app.use("/api/", apiRouter);
104
105
  // throw 404 if URL not found
105
106
  this.app.all("*", function (req, res) {
106
- return ApiResponse_1.ApiResponse.notFoundResponse(res, "Page not found");
107
+ return ApiResponse.notFoundResponse(res, "Page not found");
107
108
  });
108
109
  this.app.use(function (err, req, res) {
109
110
  if (err.name === 'UnauthorizedError') {
110
- return ApiResponse_1.ApiResponse.unauthorizedResponse(res, "Invalid token");
111
+ return ApiResponse.unauthorizedResponse(res, "Invalid token");
111
112
  }
112
113
  });
113
114
  }
114
- registerModules() {
115
+ async registerModules() {
115
116
  let modulesFolder;
116
117
  if (fs.existsSync(`${process.cwd()}/modules`)) {
117
118
  modulesFolder = `${process.cwd()}/modules`;
@@ -121,34 +122,49 @@ class ZumitoFramework {
121
122
  }
122
123
  else
123
124
  return;
124
- this.registerModule(__dirname, 'baseModule', baseModule_1.baseModule);
125
- fs.readdirSync(modulesFolder).forEach(file => {
126
- this.registerModule(modulesFolder, file);
127
- });
125
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
126
+ await this.registerModule(__dirname, 'baseModule', baseModule);
127
+ let files = fs.readdirSync(modulesFolder);
128
+ for (let file of files) {
129
+ await this.registerModule(modulesFolder, file);
130
+ }
128
131
  this.models.forEach((modelDefiniton, modelName) => {
129
132
  const schema = new mongoose.Schema(modelDefiniton);
130
133
  this.models.set(modelName, mongoose.model(modelName, schema));
131
134
  });
132
135
  }
133
- registerModule(modulesFolder, moduleName, module) {
136
+ async registerModule(modulesFolder, moduleName, module) {
134
137
  if (!module) {
135
138
  if (fs.existsSync(path.join(modulesFolder, moduleName, 'index.js'))) {
136
- module = require(path.join(modulesFolder, moduleName, 'index.js'));
139
+ module = await import(path.join(modulesFolder, moduleName, 'index.js'));
137
140
  module = Object.values(module)[0];
138
141
  }
139
142
  else if (fs.existsSync(path.join(modulesFolder, moduleName, 'index.ts'))) {
140
- module = require(path.join(modulesFolder, moduleName, 'index.ts'));
143
+ module = await import(path.join(modulesFolder, moduleName, 'index.ts'));
141
144
  module = Object.values(module)[0];
142
145
  }
143
146
  else {
144
- module = Module_1.Module;
147
+ module = Module;
145
148
  }
146
149
  ;
147
150
  }
148
151
  // Create module instance
149
- let moduleInstance = new module(path.join(modulesFolder, moduleName), this);
150
- this.modules.set(moduleInstance.constructor.name, moduleInstance);
152
+ let moduleInstance;
153
+ try {
154
+ moduleInstance = new module(path.join(modulesFolder, moduleName), this);
155
+ await moduleInstance.initialize();
156
+ this.modules.set(moduleName || moduleInstance.constructor.name, moduleInstance);
157
+ }
158
+ catch (err) {
159
+ console.error(`[📦🔴] Error loading module ${moduleName}: ${err.message}`);
160
+ console.error(err.stack);
161
+ }
151
162
  // Register module commands
163
+ if (moduleInstance.getCommands()) {
164
+ moduleInstance.getCommands().forEach((command) => {
165
+ this.commands.set(command.name, command);
166
+ });
167
+ }
152
168
  this.commands = new Map([...this.commands, ...moduleInstance.getCommands()]);
153
169
  // Register module events
154
170
  this.events = new Map([...this.events, ...moduleInstance.getEvents()]);
@@ -173,6 +189,10 @@ class ZumitoFramework {
173
189
  intents: this.settings.discordClientOptions.intents
174
190
  });
175
191
  this.client.login(this.settings.discordClientOptions.token);
192
+ this.client.on('ready', () => {
193
+ // Bot emoji
194
+ console.log('[🤖🟢] Discord client ready');
195
+ });
176
196
  }
177
197
  static splitCommandLine(commandLine) {
178
198
  //log( 'commandLine', commandLine ) ;
@@ -203,7 +223,6 @@ class ZumitoFramework {
203
223
  return memberPermission.has(permission);
204
224
  }
205
225
  }
206
- exports.ZumitoFramework = ZumitoFramework;
207
226
  function MergeRecursive(obj1, obj2) {
208
227
  for (var p in obj2) {
209
228
  try {
@@ -1,5 +1,5 @@
1
- import { EventParameters } from "../../../types/EventParameters";
2
- import { FrameworkEvent } from "../../../types/FrameworkEvent";
1
+ import { EventParameters } from "../../../types/EventParameters.js";
2
+ import { FrameworkEvent } from "../../../types/FrameworkEvent.js";
3
3
  export declare class InteractionCreate extends FrameworkEvent {
4
4
  once: boolean;
5
5
  execute({ interaction, client, framework }: EventParameters): Promise<void>;
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InteractionCreate = void 0;
4
- const CommandType_1 = require("../../../types/CommandType");
5
- const FrameworkEvent_1 = require("../../../types/FrameworkEvent");
6
- class InteractionCreate extends FrameworkEvent_1.FrameworkEvent {
1
+ import { CommandType } from "../../../types/CommandType.js";
2
+ import { FrameworkEvent } from "../../../types/FrameworkEvent.js";
3
+ export class InteractionCreate extends FrameworkEvent {
7
4
  once = false;
8
5
  async execute({ interaction, client, framework }) {
9
6
  if (interaction.isCommand()) {
@@ -17,9 +14,9 @@ class InteractionCreate extends FrameworkEvent_1.FrameworkEvent {
17
14
  args.set(arg.name, option.value || option.user || option.role || option.channel || option.options || option.message || option.member || option.focused || option.autocomplete || option.attachment);
18
15
  }
19
16
  });
20
- if (![CommandType_1.CommandType.any, CommandType_1.CommandType.separated, CommandType_1.CommandType.slash].includes(commandInstance.type))
17
+ if (![CommandType.any, CommandType.separated, CommandType.slash].includes(commandInstance.type))
21
18
  return;
22
- if (commandInstance.type === CommandType_1.CommandType.separated || commandInstance.type === CommandType_1.CommandType.slash) {
19
+ if (commandInstance.type === CommandType.separated || commandInstance.type === CommandType.slash) {
23
20
  await commandInstance.executeSlashCommand({ client, interaction, args, framework });
24
21
  }
25
22
  else {
@@ -37,4 +34,3 @@ class InteractionCreate extends FrameworkEvent_1.FrameworkEvent {
37
34
  }
38
35
  }
39
36
  }
40
- exports.InteractionCreate = InteractionCreate;
@@ -1,6 +1,16 @@
1
- import { EventParameters } from "../../../types/EventParameters";
2
- import { FrameworkEvent } from "../../../types/FrameworkEvent";
1
+ import { ActionRowBuilder, EmbedBuilder } from "discord.js";
2
+ import { EventParameters } from "../../../types/EventParameters.js";
3
+ import { FrameworkEvent } from "../../../types/FrameworkEvent.js";
3
4
  export declare class MessageCreate extends FrameworkEvent {
4
5
  once: boolean;
5
6
  execute({ message, client, framework }: EventParameters): Promise<import("discord.js").Message<boolean>>;
7
+ autocorrect(str: string, words: string[]): any;
8
+ getErrorEmbed(error: any, parse: any): {
9
+ embeds: EmbedBuilder[];
10
+ components: ActionRowBuilder<import("discord.js").AnyComponentBuilder>[];
11
+ allowedMentions: {
12
+ repliedUser: boolean;
13
+ };
14
+ };
15
+ parseError(error: any): any;
6
16
  }
@@ -1,22 +1,22 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageCreate = void 0;
4
- const discord_js_1 = require("discord.js");
5
- const FrameworkEvent_1 = require("../../../types/FrameworkEvent");
6
- const ZumitoFramework_1 = require("../../../ZumitoFramework");
7
- class MessageCreate extends FrameworkEvent_1.FrameworkEvent {
1
+ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionsBitField } from "discord.js";
2
+ import { FrameworkEvent } from "../../../types/FrameworkEvent.js";
3
+ import { ZumitoFramework } from "../../../ZumitoFramework.js";
4
+ import leven from 'leven';
5
+ import ErrorStackParser from 'error-stack-parser';
6
+ import * as url from 'url';
7
+ import path from "path";
8
+ export class MessageCreate extends FrameworkEvent {
8
9
  once = false;
9
10
  async execute({ message, client, framework }) {
10
11
  let channel = message.channel;
11
12
  let prefix = framework.settings.defaultPrefix;
12
- const args = ZumitoFramework_1.ZumitoFramework.splitCommandLine(message.content.slice(prefix.length));
13
+ const args = ZumitoFramework.splitCommandLine(message.content.slice(prefix.length));
13
14
  const command = args.shift().toLowerCase();
14
15
  let commandInstance;
15
16
  if (message.content.startsWith(prefix)) {
16
17
  if (!framework.commands.has(command)) {
17
18
  let commandNames = Array.from(framework.commands.keys());
18
- var autocorrect = require('autocorrect')({ words: commandNames });
19
- var correctedCommand = autocorrect(command);
19
+ var correctedCommand = this.autocorrect(command, commandNames);
20
20
  if (framework.commands.has(correctedCommand)) {
21
21
  commandInstance = framework.commands.get(correctedCommand);
22
22
  }
@@ -29,11 +29,11 @@ class MessageCreate extends FrameworkEvent_1.FrameworkEvent {
29
29
  }
30
30
  if (message.guild == null && commandInstance.dm == false)
31
31
  return;
32
- if (commandInstance.adminOnly || commandInstance.permissions.length > 0) {
32
+ if (commandInstance.adminOnly || commandInstance.userPermissions.length > 0) {
33
33
  let denied = false;
34
- if (framework.memberHasPermission(message.member, message.channel, discord_js_1.PermissionsBitField.Flags.Administrator) || message.member.id != message.guild.ownerId) {
35
- if (commandInstance.permissions.length > 0) {
36
- commandInstance.permissions.forEach(permission => {
34
+ if (framework.memberHasPermission(message.member, message.channel, PermissionsBitField.Flags.Administrator) || message.member.id != message.guild.ownerId) {
35
+ if (commandInstance.userPermissions.length > 0) {
36
+ commandInstance.userPermissions.forEach(permission => {
37
37
  if (!framework.memberHasPermission(message.member, message.channel, permission)) {
38
38
  denied = true;
39
39
  }
@@ -52,7 +52,7 @@ class MessageCreate extends FrameworkEvent_1.FrameworkEvent {
52
52
  if (message.channel.isTextBased) {
53
53
  let channel = message.channel;
54
54
  // Check command is nsfw and if channel is allowed
55
- if (commandInstance.nsfw && !channel.nsfw && !channel.permissionsFor(message.member).has(discord_js_1.PermissionsBitField.Flags.Administrator) && message.member.id != message.guild.ownerId) {
55
+ if (commandInstance.nsfw && !channel.nsfw && !channel.permissionsFor(message.member).has(PermissionsBitField.Flags.Administrator) && message.member.id != message.guild.ownerId) {
56
56
  return message.reply({
57
57
  content: 'This command is nsfw and this channel is not nsfw.',
58
58
  allowedMentions: {
@@ -64,10 +64,7 @@ class MessageCreate extends FrameworkEvent_1.FrameworkEvent {
64
64
  try {
65
65
  let parsedArgs = new Map();
66
66
  args.forEach(function (arg, index) {
67
- parsedArgs.set(commandInstance.args?.[index]?.name || index, {
68
- name: commandInstance.args?.[index]?.name || index,
69
- value: arg
70
- });
67
+ parsedArgs.set(commandInstance.args?.[index]?.name || index, arg);
71
68
  });
72
69
  await commandInstance.execute({
73
70
  message,
@@ -88,20 +85,121 @@ class MessageCreate extends FrameworkEvent_1.FrameworkEvent {
88
85
  }
89
86
  }
90
87
  catch (error) {
91
- // let content = await getErrorEmbed({
92
- // name: error.name,
93
- // message: error.message,
94
- // comid: com,
95
- // args: args,
96
- // stack: error.stack,
97
- // }, true);
98
- // try {
99
- // message.reply(content);
100
- // } catch (e) {
101
- // channel.send(content);
102
- // }
88
+ let content = await this.getErrorEmbed({
89
+ name: error.name,
90
+ message: error.message,
91
+ command: commandInstance,
92
+ args: args,
93
+ stack: error.stack,
94
+ }, true);
95
+ try {
96
+ message.reply(content);
97
+ }
98
+ catch (e) {
99
+ channel.send(content);
100
+ }
103
101
  }
104
102
  }
105
103
  }
104
+ autocorrect(str, words) {
105
+ var distance, bestWord, i, word, min;
106
+ var dictionary = words || [];
107
+ var len = dictionary.length;
108
+ for (i = 0; i < len; i++) {
109
+ word = dictionary[i];
110
+ distance = leven(str, word);
111
+ if (distance === 0) {
112
+ return word;
113
+ }
114
+ else if (min === undefined || distance < min) {
115
+ min = distance;
116
+ bestWord = word;
117
+ }
118
+ }
119
+ return bestWord;
120
+ }
121
+ getErrorEmbed(error, parse) {
122
+ let parsedError;
123
+ if (parse) {
124
+ parsedError = this.parseError(error);
125
+ }
126
+ else {
127
+ parsedError = error;
128
+ }
129
+ let embed = new EmbedBuilder()
130
+ .setTitle('Error')
131
+ .setDescription('An error has occured while executing this command.')
132
+ .setTimestamp()
133
+ .addFields([{
134
+ name: 'Command:',
135
+ value: (error.command.name || 'Not defined')
136
+ }])
137
+ .addFields([{
138
+ name: 'Arguments:',
139
+ value: (error.args.toString() || 'None')
140
+ }])
141
+ .addFields([{
142
+ name: 'Error name:',
143
+ value: (error.name || 'Not defined')
144
+ }])
145
+ .addFields([{
146
+ name: 'Error message:',
147
+ value: (error.message || 'Not defined')
148
+ }]);
149
+ if (error.possibleSolutions !== undefined) {
150
+ error.possibleSolutions.forEach((solution) => {
151
+ embed.addFields([{
152
+ name: 'Posible solution:',
153
+ value: solution
154
+ }]);
155
+ });
156
+ }
157
+ let stackFrames = ErrorStackParser.parse(error).filter(e => !e.fileName.includes('node_modules') && !e.fileName.includes('node:internal'));
158
+ let stack = '';
159
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
160
+ let path1 = path.resolve('./');
161
+ let path2 = path1.replaceAll('\\', '/');
162
+ stackFrames.forEach((frame) => {
163
+ stack += `[${frame.fileName.replace(path1, '').replace(path2, '').replace('file://', '')}:${frame.lineNumber}](https://zumito.ga/redirect?url=vscode://file/${frame.fileName.replace('file://', '')}:${frame.lineNumber}) ${frame.functionName}()\n`;
164
+ });
165
+ if (error.stack !== undefined) {
166
+ embed.addFields([{
167
+ name: 'Call stack:',
168
+ value: stack || error.stack || error.stack.toString()
169
+ }]);
170
+ }
171
+ if (error.details !== undefined) {
172
+ error.details.forEach((detail) => {
173
+ embed.addFields([{
174
+ name: 'Detail:',
175
+ value: detail
176
+ }]);
177
+ });
178
+ }
179
+ 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`;
180
+ const requestUrl = `https://github.com/fernandomema/Zumito/issues/new?body=${encodeURIComponent(body)}`;
181
+ const row = new ActionRowBuilder()
182
+ .addComponents(new ButtonBuilder()
183
+ .setStyle(ButtonStyle.Link)
184
+ .setLabel('Report error')
185
+ .setEmoji('975645505302437978')
186
+ .setURL(requestUrl));
187
+ return {
188
+ embeds: [embed],
189
+ components: [row],
190
+ allowedMentions: {
191
+ repliedUser: false
192
+ }
193
+ };
194
+ }
195
+ parseError(error) {
196
+ error.possibleSolutions = [];
197
+ if (/(?:^|(?<= ))(EmbedBuilder|Discord|ActionRowBuilder|ButtonBuilder|MessageSelectMenu)(?:(?= )|$) is not defined/gm.test(error.message)) {
198
+ error.possibleSolutions.push('const { ' + error.message.split(" ")[0] + ' } = require(\'discord.js\');');
199
+ }
200
+ else if (error.message.includes('A custom id and url cannot both be specified')) {
201
+ error.possibleSolutions.push("Remove .setCustomId(...) or .setURL(...)");
202
+ }
203
+ return error;
204
+ }
106
205
  }
107
- exports.MessageCreate = MessageCreate;
@@ -1,6 +1,6 @@
1
- import { Module } from "../types/Module";
2
- import { ZumitoFramework } from "../ZumitoFramework";
1
+ import { Module } from "../types/Module.js";
2
+ import { ZumitoFramework } from "../ZumitoFramework.js";
3
3
  export declare class baseModule extends Module {
4
4
  constructor(modulePath: string, framework: ZumitoFramework);
5
- registerEvents(): void;
5
+ registerEvents(): Promise<any>;
6
6
  }
@@ -1,19 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.baseModule = void 0;
4
- const Module_1 = require("../types/Module");
5
- const interactionCreate_1 = require("./events/discord/interactionCreate");
6
- const messageCreate_1 = require("./events/discord/messageCreate");
7
- class baseModule extends Module_1.Module {
1
+ import { Module } from "../types/Module.js";
2
+ import { InteractionCreate } from "./events/discord/interactionCreate.js";
3
+ import { MessageCreate } from "./events/discord/messageCreate.js";
4
+ export class baseModule extends Module {
8
5
  constructor(modulePath, framework) {
9
6
  super(modulePath, framework);
10
7
  }
11
- registerEvents() {
12
- this.events.set('interactionCreate', new interactionCreate_1.InteractionCreate());
13
- this.events.set('messageCreate', new messageCreate_1.MessageCreate());
8
+ async registerEvents() {
9
+ this.events.set('interactionCreate', new InteractionCreate());
10
+ this.events.set('messageCreate', new MessageCreate());
14
11
  this.events.forEach(event => {
15
12
  this.registerDiscordEvent(event);
16
13
  });
17
14
  }
18
15
  }
19
- exports.baseModule = baseModule;
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ApiResponse = void 0;
4
- class ApiResponse {
1
+ export class ApiResponse {
5
2
  static notFoundResponse(res, msg) {
6
3
  let data = {
7
4
  message: msg,
@@ -17,4 +14,3 @@ class ApiResponse {
17
14
  }
18
15
  ;
19
16
  }
20
- exports.ApiResponse = ApiResponse;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- export { ZumitoFramework } from './ZumitoFramework';
2
- export { FrameworkSettings } from './types/FrameworkSettings';
3
- export { Command } from './types/Commands';
4
- export { Module } from './types/Module';
5
- export { CommandParameters } from './types/CommandParameters';
6
- export { CommandArguments } from './types/CommandArguments';
1
+ import { ZumitoFramework } from './ZumitoFramework.js';
2
+ import { FrameworkSettings } from './types/FrameworkSettings.js';
3
+ import { Command } from './types/Command.js';
4
+ import { Module } from './types/Module.js';
5
+ import { CommandParameters } from './types/CommandParameters.js';
6
+ import { CommandArguments } from './types/CommandArguments.js';
7
+ import { FrameworkEvent } from './types/FrameworkEvent.js';
8
+ import { Translation } from './types/Translation.js';
9
+ import { TranslationManager } from './TranslationManager.js';
10
+ import { ApiResponse } from './definitions/ApiResponse.js';
11
+ export { ZumitoFramework, FrameworkSettings, Command, Module, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse };
package/dist/index.js CHANGED
@@ -1,11 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommandArguments = exports.Module = exports.Command = exports.ZumitoFramework = void 0;
4
- var ZumitoFramework_1 = require("./ZumitoFramework");
5
- Object.defineProperty(exports, "ZumitoFramework", { enumerable: true, get: function () { return ZumitoFramework_1.ZumitoFramework; } });
6
- var Commands_1 = require("./types/Commands");
7
- Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return Commands_1.Command; } });
8
- var Module_1 = require("./types/Module");
9
- Object.defineProperty(exports, "Module", { enumerable: true, get: function () { return Module_1.Module; } });
10
- var CommandArguments_1 = require("./types/CommandArguments");
11
- Object.defineProperty(exports, "CommandArguments", { enumerable: true, get: function () { return CommandArguments_1.CommandArguments; } });
1
+ import { ZumitoFramework } from './ZumitoFramework.js';
2
+ import { Command } from './types/Command.js';
3
+ import { Module } from './types/Module.js';
4
+ import { CommandArguments } from './types/CommandArguments.js';
5
+ import { FrameworkEvent } from './types/FrameworkEvent.js';
6
+ import { Translation } from './types/Translation.js';
7
+ import { TranslationManager } from './TranslationManager.js';
8
+ import { ApiResponse } from './definitions/ApiResponse.js';
9
+ export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse };
@@ -0,0 +1,23 @@
1
+ import { CommandParameters } from "./CommandParameters.js";
2
+ import { SelectMenuParameters } from "./SelectMenuParameters.js";
3
+ export declare abstract class Command {
4
+ name: string;
5
+ categories: string[];
6
+ aliases?: string[];
7
+ examples?: string[];
8
+ userPermissions?: bigint[];
9
+ botPermissions?: string[];
10
+ hidden?: boolean;
11
+ adminOnly?: boolean;
12
+ nsfw?: boolean;
13
+ cooldown?: number;
14
+ slashCommand?: boolean;
15
+ dm: boolean;
16
+ args: CommandArgDefinition[];
17
+ type: string;
18
+ constructor();
19
+ abstract execute({ message, interaction, args, client, framework }: CommandParameters): void;
20
+ executePrefixCommand({ message, interaction, args, client, framework }: CommandParameters): void;
21
+ executeSlashCommand({ message, interaction, args, client, framework }: CommandParameters): void;
22
+ abstract selectMenu({ path, interaction, client, framework }: SelectMenuParameters): void;
23
+ }
@@ -0,0 +1,25 @@
1
+ import { CommandType } from "./CommandType.js";
2
+ export class Command {
3
+ name = this.constructor.name.toLowerCase();
4
+ categories = [];
5
+ aliases = [];
6
+ examples = [];
7
+ userPermissions = [];
8
+ botPermissions = [];
9
+ hidden = false;
10
+ adminOnly = false;
11
+ nsfw = false;
12
+ cooldown = 0;
13
+ slashCommand = false;
14
+ dm = false;
15
+ args = [];
16
+ type = CommandType.prefix;
17
+ constructor() {
18
+ }
19
+ executePrefixCommand({ message, interaction, args, client, framework }) {
20
+ this.execute({ message, interaction, args, client, framework });
21
+ }
22
+ executeSlashCommand({ message, interaction, args, client, framework }) {
23
+ this.execute({ message, interaction, args, client, framework });
24
+ }
25
+ }
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommandArguments = void 0;
4
- class CommandArguments {
1
+ export class CommandArguments {
5
2
  args = {};
6
3
  constructor(args = {}) {
7
4
  this.args = args;
@@ -16,4 +13,3 @@ class CommandArguments {
16
13
  return new CommandArguments(interaction.options);
17
14
  }
18
15
  }
19
- exports.CommandArguments = CommandArguments;
@@ -1,5 +1,5 @@
1
1
  import { Client, Interaction, Message } from "discord.js";
2
- import { ZumitoFramework } from "../ZumitoFramework";
2
+ import { ZumitoFramework } from "../ZumitoFramework.js";
3
3
  /**
4
4
  * @class CommandParameters
5
5
  * @classdesc Parameters passed to a command execution.
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommandType = void 0;
4
- exports.CommandType = {
1
+ export const CommandType = {
5
2
  prefix: 'prefix',
6
3
  slash: 'slash',
7
4
  separated: 'separated',
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Command = void 0;
4
- const CommandType_1 = require("./CommandType");
5
- class Command {
1
+ import { CommandType } from "./CommandType.js";
2
+ export class Command {
6
3
  name = this.constructor.name.toLowerCase();
7
4
  categories = [];
8
5
  aliases = [];
@@ -16,7 +13,7 @@ class Command {
16
13
  slashCommand = false;
17
14
  dm = false;
18
15
  args = [];
19
- type = CommandType_1.CommandType.prefix;
16
+ type = CommandType.prefix;
20
17
  constructor() {
21
18
  }
22
19
  executePrefixCommand({ message, interaction, args, client, framework }) {
@@ -27,4 +24,3 @@ class Command {
27
24
  }
28
25
  selectMenu({ path, interaction, client, framework }) { }
29
26
  }
30
- exports.Command = Command;
@@ -1,5 +1,5 @@
1
1
  import { Client, Interaction, Message } from "discord.js";
2
- import { ZumitoFramework } from "../ZumitoFramework";
2
+ import { ZumitoFramework } from "../ZumitoFramework.js";
3
3
  export interface EventParameters {
4
4
  message?: Message;
5
5
  interaction?: Interaction;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,8 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FrameworkEvent = void 0;
4
- class FrameworkEvent {
1
+ export class FrameworkEvent {
5
2
  once = false;
6
3
  disabled = false;
7
4
  }
8
- exports.FrameworkEvent = FrameworkEvent;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,6 +1,6 @@
1
- import { ZumitoFramework } from "../ZumitoFramework";
2
- import { Command } from "./Commands";
3
- import { FrameworkEvent } from "./FrameworkEvent";
1
+ import { ZumitoFramework } from "../ZumitoFramework.js";
2
+ import { Command } from "./Command.js";
3
+ import { FrameworkEvent } from "./FrameworkEvent.js";
4
4
  export declare abstract class Module {
5
5
  protected path: string;
6
6
  protected framework: ZumitoFramework;
@@ -8,14 +8,18 @@ export declare abstract class Module {
8
8
  protected events: Map<string, FrameworkEvent>;
9
9
  protected models: Map<string, any>;
10
10
  constructor(path: any, framework: any);
11
- registerCommands(): void;
11
+ initialize(): Promise<void>;
12
+ registerCommands(): Promise<void>;
13
+ onCommandCreated(filePath: string): Promise<void>;
14
+ onCommandChanged(filePath: string): Promise<void>;
15
+ onErrorLoadingCommand(error: Error): void;
12
16
  getCommands(): Map<string, Command>;
13
- registerEvents(): void;
17
+ registerEvents(): Promise<void>;
14
18
  registerDiscordEvent(frameworkEvent: FrameworkEvent): void;
15
19
  parseEventArgs(args: any[]): any;
16
20
  getEvents(): Map<string, FrameworkEvent>;
17
- registerTranslations(): void;
21
+ registerTranslations(): Promise<void>;
18
22
  parseTranslation(path: string, lang: string, json: any): any;
19
- registerModels(): void;
23
+ registerModels(): Promise<void>;
20
24
  getModels(): Map<string, any>;
21
25
  }
@@ -1,10 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Module = void 0;
4
- const mongoose = require("mongoose");
5
- const fs = require('fs');
6
- const path = require('path');
7
- class Module {
1
+ import * as chokidar from 'chokidar';
2
+ import chalk from 'chalk';
3
+ import boxen from "boxen";
4
+ import * as fs from 'fs';
5
+ import path from 'path';
6
+ import { SelectMenuInteraction } from "discord.js";
7
+ export class Module {
8
8
  path;
9
9
  framework;
10
10
  commands = new Map();
@@ -13,41 +13,96 @@ class Module {
13
13
  constructor(path, framework) {
14
14
  this.path = path;
15
15
  this.framework = framework;
16
- this.registerCommands();
17
- this.registerEvents();
18
- this.registerTranslations();
19
16
  }
20
- registerCommands() {
21
- if (!fs.existsSync(path.join(this.path, 'commands')))
22
- return;
23
- fs.readdirSync(path.join(this.path, 'commands')).forEach(file => {
24
- if (file.endsWith('.js') || file.endsWith('.ts')) {
25
- let command = require(`${this.path}/commands/${file}`);
26
- command = Object.values(command)[0];
27
- command = new command();
28
- this.commands.set(command.constructor.name.toLowerCase(), command);
17
+ async initialize() {
18
+ await this.registerCommands();
19
+ await this.registerEvents();
20
+ await this.registerTranslations();
21
+ // console.error('[🔄🔴 ] Error initializing module ' + this.constructor.name);
22
+ // console.log(boxen(e + '\n' + e.stack, { padding: 1 }));
23
+ }
24
+ async registerCommands() {
25
+ if (fs.existsSync(path.join(this.path, 'commands'))) {
26
+ let files = fs.readdirSync(path.join(this.path, 'commands'));
27
+ for (let file of files) {
28
+ if (file.endsWith('.js') || file.endsWith('.ts')) {
29
+ let command = await import('file://' + path.join(this.path, 'commands', file)).catch(e => {
30
+ console.error(`[🔄🔴 ] Error loading ${file.slice(0, -3)} command on module ${this.constructor.name}`);
31
+ console.error(e + '\n' + e.name + '\n' + e.stack);
32
+ });
33
+ command = Object.values(command)[0];
34
+ command = new command();
35
+ this.commands.set(command.constructor.name.toLowerCase(), command);
36
+ }
29
37
  }
30
- });
38
+ ;
39
+ // register watcher
40
+ if (process.env.DEBUG) {
41
+ /*
42
+ Debug only cause in prod environment commands should't be changed.
43
+ Appart from that, esm module cache invalidation is not working properly
44
+ and can cause memory leaks and crashes.
45
+ */
46
+ chokidar.watch(path.resolve(path.join(this.path, 'commands')), { ignored: /^\./, persistent: true, ignoreInitial: true })
47
+ .on('add', this.onCommandCreated.bind(this))
48
+ .on('change', this.onCommandChanged.bind(this))
49
+ //.on('unlink', function(path) {console.log('File', path, 'has been removed');})
50
+ .on('error', this.onErrorLoadingCommand.bind(this));
51
+ }
52
+ }
53
+ }
54
+ async onCommandCreated(filePath) {
55
+ if (filePath.endsWith('.js') || filePath.endsWith('.ts')) {
56
+ let command = await import('file://' + filePath).catch(e => {
57
+ console.error('[🆕🔴 ] Error loading command ' + chalk.blue(filePath.replace(/^.*[\\\/]/, '').split('.').slice(0, -1).join('.')));
58
+ console.log(e + '\n' + e.name + '\n' + e.stack);
59
+ });
60
+ command = Object.values(command)[0];
61
+ command = new command();
62
+ this.commands.set(command.constructor.name.toLowerCase(), command);
63
+ console.debug('[🆕🟢 ] Command ' + chalk.blue(filePath.replace(/^.*[\\\/]/, '').split('.').slice(0, -1).join('.')) + ' loaded');
64
+ }
65
+ }
66
+ async onCommandChanged(filePath) {
67
+ if (filePath.endsWith('.js') || filePath.endsWith('.ts')) {
68
+ let command = await import('file://' + filePath + '?update=' + Date.now().toString()).catch(e => {
69
+ console.error('[🔄🔴 ] Error reloading command ' + chalk.blue(filePath.replace(/^.*[\\\/]/, '').split('.').slice(0, -1).join('.')));
70
+ console.log(boxen(e + '\n' + e.name + '\n' + e.stack, { padding: 1 }));
71
+ });
72
+ command = Object.values(command)[0];
73
+ command = new command();
74
+ this.commands.set(command.constructor.name.toLowerCase(), command);
75
+ console.debug('[🔄🟢 ] Command ' + chalk.blue(filePath.replace(/^.*[\\\/]/, '').split('.').slice(0, -1).join('.')) + ' reloaded');
76
+ }
77
+ }
78
+ onErrorLoadingCommand(error) {
79
+ console.error('[🔄🔴 ] Error reloading command');
80
+ console.log(boxen(error + '\n' + error.stack, { padding: 1 }));
31
81
  }
32
82
  getCommands() {
33
83
  return this.commands;
34
84
  }
35
- registerEvents() {
85
+ async registerEvents() {
36
86
  if (!fs.existsSync(path.join(this.path, 'events')))
37
87
  return;
38
- fs.readdirSync(path.join(this.path, 'events')).forEach(file => {
88
+ let files = fs.readdirSync(path.join(this.path, 'events'));
89
+ for (let file of files) {
39
90
  if (file == 'discord') {
40
- fs.readdirSync(path.join(this.path, 'events', 'discord')).forEach(moduleFileName => {
91
+ let moduleFileNames = fs.readdirSync(path.join(this.path, 'events', 'discord'));
92
+ for (let moduleFileName of moduleFileNames) {
41
93
  if (moduleFileName.endsWith('.js') || moduleFileName.endsWith('.ts')) {
42
- let event = require(path.join(this.path, 'events', 'discord', moduleFileName));
94
+ let event = await import('file://' + path.join(this.path, 'events', 'discord', moduleFileName)).catch(e => {
95
+ console.error(`[🔄🔴 ] Error loading ${moduleFileName.slice(0, -3)} event on module ${this.constructor.name}`);
96
+ console.log(boxen(e + '\n' + e.name + '\n' + e.stack, { padding: 1 }));
97
+ });
43
98
  event = Object.values(event)[0];
44
99
  event = new event();
45
100
  this.events.set(event.constructor.name.toLowerCase(), event);
46
101
  this.registerDiscordEvent(event);
47
102
  }
48
- });
103
+ }
49
104
  }
50
- });
105
+ }
51
106
  }
52
107
  registerDiscordEvent(frameworkEvent) {
53
108
  if (frameworkEvent.disabled)
@@ -60,6 +115,7 @@ class Module {
60
115
  emitter[once ? 'once' : 'on'](eventName, (...args) => frameworkEvent.execute(this.parseEventArgs(args))); // Run the event using the above defined emitter (client)
61
116
  }
62
117
  catch (error) {
118
+ console.log(error, error.message, error, name);
63
119
  console.error(error.stack); // If there is an error, console log the error stack message
64
120
  }
65
121
  }
@@ -71,21 +127,33 @@ class Module {
71
127
  args.forEach(arg => {
72
128
  finalArgs[arg.constructor.name.toLowerCase()] = arg;
73
129
  });
130
+ let selectMenuInteraction = args.find((arg) => arg instanceof SelectMenuInteraction);
131
+ if (selectMenuInteraction) {
132
+ finalArgs['interaction'] = selectMenuInteraction;
133
+ }
74
134
  return finalArgs;
75
135
  }
76
136
  getEvents() {
77
137
  return this.events;
78
138
  }
79
- registerTranslations() {
139
+ async registerTranslations() {
80
140
  if (!fs.existsSync(path.join(this.path, 'translations')))
81
141
  return;
82
- fs.readdirSync(path.join(this.path, 'translations')).forEach(file => {
142
+ let files = fs.readdirSync(path.join(this.path, 'translations'));
143
+ for (let file of files) {
83
144
  if (file.endsWith('.json')) {
84
- let json = require(`${this.path}/translations/${file}`);
145
+ let json = await import('file://' + `${this.path}/translations/${file}`, {
146
+ assert: {
147
+ type: "json",
148
+ },
149
+ }).catch(e => {
150
+ console.error(`[🔄🔴 ] Error loading ${file.slice(0, -5)} translations on module ${this.constructor.name}`);
151
+ console.log(boxen(e + '\n' + e.name + '\n' + e.stack, { padding: 1 }));
152
+ });
85
153
  let lang = file.slice(0, -5);
86
- this.parseTranslation('', lang, json);
154
+ this.parseTranslation('', lang, json.default);
87
155
  }
88
- });
156
+ }
89
157
  }
90
158
  parseTranslation(path, lang, json) {
91
159
  if (typeof json === 'object') {
@@ -97,19 +165,26 @@ class Module {
97
165
  this.framework.translations.set(path.slice(0, -1), lang, json);
98
166
  }
99
167
  }
100
- registerModels() {
168
+ async registerModels() {
101
169
  if (!fs.existsSync(path.join(this.path, 'models')))
102
170
  return;
103
- fs.readdirSync(path.join(this.path, 'models')).forEach(file => {
171
+ let files = fs.readdirSync(path.join(this.path, 'models'));
172
+ for (let file of files) {
104
173
  if (file.endsWith('.json')) {
105
174
  let modelName = file.slice(0, -5).charAt(0).toUpperCase() + file.slice(0, -5).slice(1);
106
- let modelDefiniton = require(`${this.path}/models/${file}`);
175
+ let modelDefiniton = await import('file://' + `${this.path}/models/${file}`, {
176
+ assert: {
177
+ type: "json",
178
+ },
179
+ }).catch(e => {
180
+ console.error(`[🔄🔴 ] Error loading model ${modelName} on module ${this.constructor.name}`);
181
+ console.log(boxen(e + '\n' + e.name + '\n' + e.stack, { padding: 1 }));
182
+ });
107
183
  this.models.set(modelName, modelDefiniton);
108
184
  }
109
- });
185
+ }
110
186
  }
111
187
  getModels() {
112
188
  return this.models;
113
189
  }
114
190
  }
115
- exports.Module = Module;
@@ -1,8 +1,8 @@
1
- import { Client, Interaction } from "discord.js";
2
- import { ZumitoFramework } from "../ZumitoFramework";
1
+ import { Client, SelectMenuInteraction } from "discord.js";
2
+ import { ZumitoFramework } from "../ZumitoFramework.js";
3
3
  export interface SelectMenuParameters {
4
4
  path: string[];
5
- interaction: Interaction;
5
+ interaction: SelectMenuInteraction;
6
6
  client: Client;
7
7
  framework: ZumitoFramework;
8
8
  }
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Translation = void 0;
4
- class Translation {
1
+ export class Translation {
5
2
  text = new Map();
6
3
  constructor() { }
7
4
  get(language, params) {
@@ -32,4 +29,3 @@ class Translation {
32
29
  this.text = text;
33
30
  }
34
31
  }
35
- exports.Translation = Translation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zumito-framework",
3
- "version": "1.1.32",
3
+ "version": "1.1.34",
4
4
  "description": "Discord.js bot framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "scripts": {
17
17
  "test": "echo \"Error: no test specified\" && exit 1",
18
- "build": "tsc",
18
+ "build": "tsc-esm",
19
19
  "publish": "npm publish",
20
20
  "docs": "typedoc --out docs src"
21
21
  },
@@ -23,15 +23,25 @@
23
23
  "license": "ISC",
24
24
  "dependencies": {
25
25
  "@types/express": "^4.17.13",
26
+ "autocorrect": "^1.2.0",
26
27
  "better-logging": "^5.0.0",
27
- "discord.js": "^14.2.0",
28
+ "boxen": "^7.0.0",
29
+ "chalk": "^4.1.2",
30
+ "chokidar": "^3.5.3",
31
+ "cookie-parser": "^1.4.6",
32
+ "cors": "^2.8.5",
33
+ "discord.js": "^14.3.0",
34
+ "error-stack-parser": "^2.1.4",
28
35
  "express": "^4.18.1",
36
+ "leven": "^4.0.0",
29
37
  "mongoose": "^6.5.2",
30
38
  "plop": "^3.1.1",
31
39
  "zumito-framework": "^1.1.16"
32
40
  },
33
41
  "devDependencies": {
34
- "typedoc": "^0.23.10",
35
- "typescript": "^4.7.4"
36
- }
42
+ "@types/node": "^18.7.16",
43
+ "typedoc": "^0.23.14",
44
+ "typescript": "^4.8.2"
45
+ },
46
+ "type": "module"
37
47
  }
@@ -1,10 +1,17 @@
1
1
  import { Command, CommandParameters } from "zumito-framework";
2
2
 
3
- export class {{command.charAt(0).toUpperCase() + command.slice(1)}} extends Command {
3
+ export class {{capitalize command}} extends Command {
4
4
 
5
5
  execute({ message, interaction, args, client, framework }: CommandParameters): void {
6
- (message || interaction).reply({
6
+ (message || interaction!).reply({
7
7
  content: "Message content",
8
8
  });
9
9
  }
10
+
11
+ async selectMenu({ path, interaction, client, framework }: SelectMenuParameters): Promise<void> {
12
+ await interaction.deferUpdate();
13
+ await interaction.editReply({
14
+ content: "Select menu content",
15
+ });
16
+ }
10
17
  }
package/plopfile.js CHANGED
@@ -1,4 +1,7 @@
1
1
  module.exports = function (plop) {
2
+ plop.setHelper('capitalize', function (text) {
3
+ return text.charAt(0).toUpperCase() + text.slice(1);
4
+ });
2
5
  // create your generators here
3
6
  plop.setGenerator('command', {
4
7
  description: 'this is a skeleton command file',