zumito-framework 1.1.35 → 1.1.37

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.
@@ -47,4 +47,5 @@ export declare class ZumitoFramework {
47
47
  static splitCommandLine(commandLine: any): any;
48
48
  memberHasPermission(member: GuildMember, channel: TextChannel, permission: bigint): Promise<boolean>;
49
49
  getGuildSettings(guildId: string): Promise<any>;
50
+ refreshSlashCommands(): Promise<void>;
50
51
  }
@@ -1,3 +1,4 @@
1
+ import { SlashCommandBuilder } from "discord.js";
1
2
  import { Module } from "./types/Module.js";
2
3
  import { ApiResponse } from './definitions/ApiResponse.js';
3
4
  import { baseModule } from "./baseModule/index.js";
@@ -9,11 +10,14 @@ import { Client } from "discord.js";
9
10
  // import better-logging
10
11
  import { betterLogging } from "better-logging";
11
12
  betterLogging(console);
13
+ import { REST } from '@discordjs/rest';
14
+ import { Routes } from 'discord-api-types/v9';
12
15
  import mongoose from "mongoose";
13
16
  import cookieParser from 'cookie-parser';
14
17
  import cors from 'cors';
15
18
  import http from 'http';
16
19
  import * as url from 'url';
20
+ import { CommandType } from "./types/CommandType.js";
17
21
  /**
18
22
  * @class ZumitoFramework
19
23
  * @classdesc The main class of the framework.
@@ -80,6 +84,7 @@ export class ZumitoFramework {
80
84
  this.initializeDiscordClient();
81
85
  this.startApiServer();
82
86
  await this.registerModules();
87
+ await this.refreshSlashCommands();
83
88
  }
84
89
  startApiServer() {
85
90
  this.app = express();
@@ -229,6 +234,45 @@ export class ZumitoFramework {
229
234
  }
230
235
  return guild;
231
236
  }
237
+ async refreshSlashCommands() {
238
+ const rest = new REST({ version: '10' }).setToken(this.settings.discordClientOptions.token);
239
+ let commands = Array.from(this.commands.values())
240
+ .filter((command) => command.type == CommandType.slash || command.type == CommandType.separated || command.type == CommandType.any)
241
+ .map((command) => {
242
+ let slashCommand = new SlashCommandBuilder()
243
+ .setName(command.name)
244
+ .setDescription(this.translations.get('commands.' + command.name + '.description', 'en'));
245
+ if (command.args) {
246
+ command.args.forEach((arg) => {
247
+ let method;
248
+ switch (arg.type) {
249
+ case 'string':
250
+ method = 'addStringOption';
251
+ break;
252
+ case 'user':
253
+ case 'member':
254
+ method = 'addUserOption';
255
+ break;
256
+ case 'channel':
257
+ method = 'addChannelOption';
258
+ break;
259
+ case 'role':
260
+ method = 'addRoleOption';
261
+ break;
262
+ }
263
+ slashCommand[method]((option) => {
264
+ option.setName(arg.name);
265
+ option.setDescription(this.translations.get('commands.' + command.name + '.args.' + arg.name + '.description', 'en'));
266
+ option.setRequired(!arg.optional);
267
+ return option;
268
+ });
269
+ });
270
+ }
271
+ return slashCommand.toJSON();
272
+ });
273
+ const data = await rest.put(Routes.applicationCommands(this.settings.discordClientOptions.clientId), { body: commands });
274
+ console.debug(`Successfully reloaded ${data.length} of ${commands.length} application (/) commands.`);
275
+ }
232
276
  }
233
277
  function MergeRecursive(obj1, obj2) {
234
278
  for (var p in obj2) {
@@ -15,7 +15,17 @@ export class InteractionCreate extends FrameworkEvent {
15
15
  commandInstance.args.forEach(arg => {
16
16
  let option = interaction.options.get(arg.name);
17
17
  if (option) {
18
- 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
+ switch (arg.type) {
19
+ case "user":
20
+ args.set(arg.name, option.user);
21
+ break;
22
+ case "member":
23
+ args.set(arg.name, option.member);
24
+ break;
25
+ default:
26
+ args.set(arg.name, option.value || option.user || option.role || option.channel || option.options || option.message || option.member || option.focused || option.autocomplete || option.attachment);
27
+ break;
28
+ }
19
29
  }
20
30
  });
21
31
  if (![CommandType.any, CommandType.separated, CommandType.slash].includes(commandInstance.type))
@@ -64,9 +64,35 @@ export class MessageCreate extends FrameworkEvent {
64
64
  try {
65
65
  let guildSettings = await framework.getGuildSettings(message.guildId);
66
66
  let parsedArgs = new Map();
67
- args.forEach(function (arg, index) {
68
- parsedArgs.set(commandInstance.args?.[index]?.name || index, arg);
69
- });
67
+ let userMentionCount = 0;
68
+ for (let i = 0; i < args.length; i++) {
69
+ let arg = args[i];
70
+ let type = commandInstance.args[i]?.type;
71
+ if (type) {
72
+ if (type == 'member' || type == 'user') {
73
+ const member = await message.guild.members.cache.get(arg.replace(/[<@!>]/g, ''));
74
+ if (member) {
75
+ if (type == 'user') {
76
+ parsedArgs.set(commandInstance.args[i].name, member.user);
77
+ }
78
+ else {
79
+ parsedArgs.set(commandInstance.args[i].name, member);
80
+ }
81
+ }
82
+ else {
83
+ return message.reply({
84
+ content: 'Invalid user.',
85
+ allowedMentions: {
86
+ repliedUser: false,
87
+ }
88
+ });
89
+ }
90
+ }
91
+ else if (type == 'string') {
92
+ parsedArgs.set(commandInstance.args?.[i]?.name || i.toString(), arg);
93
+ }
94
+ }
95
+ }
70
96
  await commandInstance.execute({
71
97
  message,
72
98
  args: parsedArgs,
package/dist/index.d.ts CHANGED
@@ -8,4 +8,7 @@ import { FrameworkEvent } from './types/FrameworkEvent.js';
8
8
  import { Translation } from './types/Translation.js';
9
9
  import { TranslationManager } from './TranslationManager.js';
10
10
  import { ApiResponse } from './definitions/ApiResponse.js';
11
- export { ZumitoFramework, FrameworkSettings, Command, Module, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse };
11
+ import { SelectMenuParameters } from './types/SelectMenuParameters.js';
12
+ import { CommandType } from './types/CommandType.js';
13
+ import { CommandArgDefinition } from './types/CommandArgDefinition.js';
14
+ export { ZumitoFramework, FrameworkSettings, Command, Module, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, SelectMenuParameters, CommandType, CommandArgDefinition };
package/dist/index.js CHANGED
@@ -6,4 +6,5 @@ import { FrameworkEvent } from './types/FrameworkEvent.js';
6
6
  import { Translation } from './types/Translation.js';
7
7
  import { TranslationManager } from './TranslationManager.js';
8
8
  import { ApiResponse } from './definitions/ApiResponse.js';
9
- export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse };
9
+ import { CommandType } from './types/CommandType.js';
10
+ export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, CommandType };
@@ -0,0 +1,11 @@
1
+ import { Client } from "discord.js";
2
+ export declare class EmojiManager {
3
+ /**
4
+ * @param {Client} client - The client client instance.
5
+ */
6
+ client: Client;
7
+ emojiFallbacks: Map<string, string>;
8
+ constructor(client: Client);
9
+ getEmojiByName(name: string): string;
10
+ registerEmojiFallback(id: string, fallback: string): void;
11
+ }
@@ -0,0 +1,32 @@
1
+ export class EmojiManager {
2
+ /**
3
+ * @param {Client} client - The client client instance.
4
+ */
5
+ client;
6
+ emojiFallbacks = new Map();
7
+ constructor(client) {
8
+ this.client = client;
9
+ }
10
+ getEmojiByName(name) {
11
+ let emoji = this.client.emojis.cache.find((e) => e.name === name);
12
+ if (emoji) {
13
+ return emoji.toString();
14
+ }
15
+ else if (this.emojiFallbacks.has(name)) {
16
+ const fallback = this.emojiFallbacks.get(name);
17
+ emoji = this.client.emojis.cache.find((e) => e.name === fallback);
18
+ if (emoji) {
19
+ return emoji.toString();
20
+ }
21
+ else {
22
+ return fallback;
23
+ }
24
+ }
25
+ else {
26
+ throw new Error(`Emoji ${name} not found.`);
27
+ }
28
+ }
29
+ registerEmojiFallback(id, fallback) {
30
+ this.emojiFallbacks.set(id, fallback);
31
+ }
32
+ }
@@ -1,3 +1,4 @@
1
+ import { CommandArgDefinition } from "./CommandArgDefinition.js";
1
2
  import { CommandParameters } from "./CommandParameters.js";
2
3
  import { SelectMenuParameters } from "./SelectMenuParameters.js";
3
4
  export declare abstract class Command {
@@ -1,4 +1,5 @@
1
- interface CommandArgDefinition {
1
+ export interface CommandArgDefinition {
2
2
  name: string;
3
3
  optional: boolean;
4
+ type: string;
4
5
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { Client, Interaction, Message } from "discord.js";
1
+ import { Client, CommandInteraction, Message } from "discord.js";
2
2
  import { ZumitoFramework } from "../ZumitoFramework.js";
3
3
  /**
4
4
  * @class CommandParameters
@@ -10,7 +10,7 @@ import { ZumitoFramework } from "../ZumitoFramework.js";
10
10
  */
11
11
  export interface CommandParameters {
12
12
  message?: Message;
13
- interaction?: Interaction;
13
+ interaction?: CommandInteraction;
14
14
  args: Map<String, any>;
15
15
  client: Client;
16
16
  framework: ZumitoFramework;
@@ -3,7 +3,7 @@ import chalk from 'chalk';
3
3
  import boxen from "boxen";
4
4
  import * as fs from 'fs';
5
5
  import path from 'path';
6
- import { SelectMenuInteraction } from "discord.js";
6
+ import { CommandInteraction, SelectMenuInteraction } from "discord.js";
7
7
  export class Module {
8
8
  path;
9
9
  framework;
@@ -128,9 +128,9 @@ export class Module {
128
128
  args.forEach(arg => {
129
129
  finalArgs[arg.constructor.name.toLowerCase()] = arg;
130
130
  });
131
- let selectMenuInteraction = args.find((arg) => arg instanceof SelectMenuInteraction);
132
- if (selectMenuInteraction) {
133
- finalArgs['interaction'] = selectMenuInteraction;
131
+ let interaction = args.find((arg) => arg instanceof SelectMenuInteraction || arg instanceof CommandInteraction);
132
+ if (interaction) {
133
+ finalArgs['interaction'] = interaction;
134
134
  }
135
135
  return finalArgs;
136
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zumito-framework",
3
- "version": "1.1.35",
3
+ "version": "1.1.37",
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-esm",
18
+ "build": "tsc",
19
19
  "publish": "npm publish",
20
20
  "docs": "typedoc --out docs src"
21
21
  },
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@types/node": "^18.7.16",
42
42
  "typedoc": "^0.23.14",
43
- "typescript": "^4.8.2"
43
+ "typescript": "^4.8.3"
44
44
  },
45
45
  "type": "module"
46
46
  }