chrxmaticc-framework 1.2.0 → 1.2.1

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,13 +1,10 @@
1
1
  /**
2
2
  * core/ChrxCommandBuilder.js
3
3
  * Simple command builder — write a command in 10 lines.
4
- * Handles SlashCommandBuilder, option types, and plugin injection automatically.
5
4
  */
6
5
 
7
6
  const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js");
8
7
 
9
- // ── Option type map ───────────────────────────────────────────────────────
10
- // Write "user" instead of ApplicationCommandOptionType.User etc.
11
8
  const TYPE_MAP = {
12
9
  string: "addStringOption",
13
10
  number: "addNumberOption",
@@ -21,23 +18,6 @@ const TYPE_MAP = {
21
18
  };
22
19
 
23
20
  class ChrxCommandBuilder {
24
- /**
25
- * @param {object} options
26
- * @param {string} options.name Command name (lowercase, no spaces)
27
- * @param {string} options.description Command description
28
- * @param {object[]} [options.options] Command options/arguments
29
- * @param {string} options.options[].name Option name
30
- * @param {string} options.options[].description Option description
31
- * @param {string} options.options[].type Option type — "string" | "number" | "integer" | "boolean" | "user" | "channel" | "role" | "mentionable" | "attachment"
32
- * @param {boolean} [options.options[].required] Whether option is required (default: false)
33
- * @param {Array} [options.options[].choices] Choices array [{ name, value }]
34
- * @param {string} [options.category] Category label for help menus
35
- * @param {string} [options.permission] Required permission e.g. "BanMembers"
36
- * @param {boolean} [options.ownerOnly] Restrict to bot owner
37
- * @param {boolean} [options.guildOnly] Restrict to guilds only (default: true)
38
- * @param {number} [options.cooldown] Cooldown in seconds
39
- * @param {Function} options.run Command function (interaction, plugins) => void
40
- */
41
21
  constructor(options = {}) {
42
22
  if (!options.name) throw new Error("[ChrxCommand] name is required.");
43
23
  if (!options.description) throw new Error("[ChrxCommand] description is required.");
@@ -46,7 +26,6 @@ class ChrxCommandBuilder {
46
26
  this._options = options;
47
27
  this._cooldowns = new Map();
48
28
 
49
- // ── Build SlashCommandBuilder ─────────────────────────────────────────
50
29
  const builder = new SlashCommandBuilder()
51
30
  .setName(options.name)
52
31
  .setDescription(options.description);
@@ -59,7 +38,6 @@ class ChrxCommandBuilder {
59
38
  builder.setDMPermission(false);
60
39
  }
61
40
 
62
- // ── Add options ───────────────────────────────────────────────────────
63
41
  for (const opt of options.options ?? []) {
64
42
  const method = TYPE_MAP[opt.type ?? "string"];
65
43
  if (!method) throw new Error(`[ChrxCommand] Unknown option type: "${opt.type}"`);
@@ -67,43 +45,36 @@ class ChrxCommandBuilder {
67
45
  builder[method]((o) => {
68
46
  o.setName(opt.name).setDescription(opt.description);
69
47
  if (opt.required) o.setRequired(true);
70
- if (opt.choices && (opt.type === "string" || opt.type === "integer" || opt.type === "number")) {
48
+ if (opt.choices && ["string", "integer", "number"].includes(opt.type)) {
71
49
  o.addChoices(...opt.choices);
72
50
  }
73
51
  return o;
74
52
  });
75
53
  }
76
54
 
77
- this.data = builder;
55
+ // ── Critical: expose data and execute so CommandLoader + deploy-commands picks it up ──
56
+ this.data = builder;
57
+ this.execute = this._execute.bind(this);
78
58
  }
79
59
 
80
- /**
81
- * Called by CommandLoader automatically.
82
- * Handles cooldowns, permissions, ownerOnly, then calls run().
83
- */
84
- async execute(interaction) {
60
+ async _execute(interaction) {
85
61
  const client = interaction.client;
86
62
  const opts = this._options;
87
63
 
88
- // ── Guild only ────────────────────────────────────────────────────────
89
64
  if (opts.guildOnly !== false && !interaction.guild) {
90
65
  return interaction.reply({ content: "❌ This command can only be used in a server.", ephemeral: true });
91
66
  }
92
67
 
93
- // ── Owner only ────────────────────────────────────────────────────────
94
68
  if (opts.ownerOnly && interaction.user.id !== process.env.OWNER_ID) {
95
69
  return interaction.reply({ content: "❌ This command is restricted to the bot owner.", ephemeral: true });
96
70
  }
97
71
 
98
- // ── Permission check ──────────────────────────────────────────────────
99
72
  if (opts.permission) {
100
- const member = interaction.member;
101
- if (!member?.permissions.has(PermissionFlagsBits[opts.permission])) {
73
+ if (!interaction.member?.permissions.has(PermissionFlagsBits[opts.permission])) {
102
74
  return interaction.reply({ content: `❌ You need the **${opts.permission}** permission to use this.`, ephemeral: true });
103
75
  }
104
76
  }
105
77
 
106
- // ── Cooldown ──────────────────────────────────────────────────────────
107
78
  if (opts.cooldown) {
108
79
  const key = `${interaction.user.id}-${opts.name}`;
109
80
  const now = Date.now();
@@ -120,8 +91,6 @@ class ChrxCommandBuilder {
120
91
  setTimeout(() => this._cooldowns.delete(key), opts.cooldown * 1000);
121
92
  }
122
93
 
123
- // ── Inject plugins from client ────────────────────────────────────────
124
- // Plugins are attached to client.chrx.* if using ChrxClient
125
94
  const plugins = {
126
95
  economy: client.chrx?.economy,
127
96
  moderation: client.chrx?.moderation,
@@ -137,12 +106,11 @@ class ChrxCommandBuilder {
137
106
  db: client.db,
138
107
  };
139
108
 
140
- // ── Run ───────────────────────────────────────────────────────────────
141
109
  try {
142
110
  await opts.run(interaction, plugins);
143
111
  } catch (err) {
144
112
  console.error(`[ChrxCommand] Error in /${opts.name}:`, err);
145
- const msg = { content: "❌ Something went wrong running this command.", ephemeral: true };
113
+ const msg = { content: err.message || "❌ Something went wrong running this command.", ephemeral: true };
146
114
  if (interaction.replied || interaction.deferred) {
147
115
  interaction.followUp(msg).catch(() => {});
148
116
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrxmaticc-framework",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "A batteries-included Discord bot framework with music, AI, XP and database support.",
5
5
  "main": "index.js",
6
6
  "files": [