commandkit 0.1.1 → 0.1.3-dev.20231002185336

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/index.mjs CHANGED
@@ -1,3 +1,11 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
1
9
  // src/utils/get-paths.ts
2
10
  import path from "path";
3
11
  import fs from "fs";
@@ -38,7 +46,286 @@ function getFolderPaths(directory, nesting) {
38
46
  import path2 from "path";
39
47
  function toFileURL(filePath) {
40
48
  const resolvedPath = path2.resolve(filePath);
41
- return "file://" + resolvedPath.replace(/\\/g, "/");
49
+ return "file://" + resolvedPath.replace(/\\\\|\\/g, "/");
50
+ }
51
+
52
+ // src/utils/colors.ts
53
+ var resetColor = "\x1B[0m";
54
+ var colors_default = {
55
+ reset: (text) => `${text}${resetColor}`,
56
+ bright: (text) => `\x1B[1m${text}${resetColor}`,
57
+ dim: (text) => `\x1B[2m${text}${resetColor}`,
58
+ underscore: (text) => `\x1B[4m${text}${resetColor}`,
59
+ blink: (text) => `\x1B[5m${text}${resetColor}`,
60
+ reverse: (text) => `\x1B[7m${text}${resetColor}`,
61
+ hidden: (text) => `\x1B[8m${text}${resetColor}`,
62
+ black: (text) => `\x1B[30m${text}${resetColor}`,
63
+ red: (text) => `\x1B[31m${text}${resetColor}`,
64
+ green: (text) => `\x1B[32m${text}${resetColor}`,
65
+ yellow: (text) => `\x1B[33m${text}${resetColor}`,
66
+ blue: (text) => `\x1B[34m${text}${resetColor}`,
67
+ magenta: (text) => `\x1B[35m${text}${resetColor}`,
68
+ cyan: (text) => `\x1B[36m${text}${resetColor}`,
69
+ white: (text) => `\x1B[37m${text}${resetColor}`,
70
+ bgBlack: (text) => `\x1B[40m${text}${resetColor}`,
71
+ bgRed: (text) => `\x1B[41m${text}${resetColor}`,
72
+ bgGreen: (text) => `\x1B[42m${text}${resetColor}`,
73
+ bgYellow: (text) => `\x1B[43m${text}${resetColor}`,
74
+ bgBlue: (text) => `\x1B[44m${text}${resetColor}`,
75
+ bgMagenta: (text) => `\x1B[45m${text}${resetColor}`,
76
+ bgCyan: (text) => `\x1B[46m${text}${resetColor}`,
77
+ bgWhite: (text) => `\x1B[47m${text}${resetColor}`
78
+ };
79
+
80
+ // src/handlers/command-handler/functions/loadCommandsWithRest.ts
81
+ async function loadCommandsWithRest(props) {
82
+ if (props.reloading) {
83
+ if (props.client.isReady()) {
84
+ await handleLoading(
85
+ props.client,
86
+ props.commands,
87
+ props.devGuildIds,
88
+ props.reloading,
89
+ props.type
90
+ );
91
+ } else {
92
+ throw new Error(colors_default.red(`\u274C Cannot reload commands when client is not ready.`));
93
+ }
94
+ } else {
95
+ props.client.once("ready", async (c) => {
96
+ await handleLoading(c, props.commands, props.devGuildIds, props.reloading, props.type);
97
+ });
98
+ }
99
+ }
100
+ async function handleLoading(client, commands, devGuildIds, reloading, type) {
101
+ const devOnlyCommands = commands.filter((cmd) => cmd.options?.devOnly);
102
+ const globalCommands = commands.filter((cmd) => !cmd.options?.devOnly);
103
+ if (type === "dev") {
104
+ await loadDevCommands(client, devOnlyCommands, devGuildIds, reloading);
105
+ } else if (type === "global") {
106
+ await loadGlobalCommands(client, globalCommands, reloading);
107
+ } else {
108
+ await loadDevCommands(client, devOnlyCommands, devGuildIds, reloading);
109
+ await loadGlobalCommands(client, globalCommands, reloading);
110
+ }
111
+ }
112
+ async function loadGlobalCommands(client, commands, reloading) {
113
+ const requestBody = commands.map((cmd) => cmd.data);
114
+ await client.application.commands.set(requestBody).catch((error) => {
115
+ console.log(
116
+ colors_default.red(
117
+ `\u274C Error ${reloading ? "reloading" : "loading"} global application commands.
118
+ `
119
+ )
120
+ );
121
+ throw new Error(error);
122
+ });
123
+ console.log(
124
+ colors_default.green(
125
+ `\u2705 ${reloading ? "Reloaded" : "Loaded"} ${requestBody.length} global commands.`
126
+ )
127
+ );
128
+ }
129
+ async function loadDevCommands(client, commands, guildIds, reloading) {
130
+ const requestBody = commands.map((cmd) => cmd.data);
131
+ for (const guildId of guildIds) {
132
+ const targetGuild = client.guilds.cache.get(guildId) || await client.guilds.fetch(guildId);
133
+ if (!targetGuild) {
134
+ console.log(
135
+ `Couldn't ${reloading ? "reloading" : "loading"} commands in guild "${targetGuild}" - guild doesn't exist or client isn't part of the guild.`
136
+ );
137
+ continue;
138
+ }
139
+ await targetGuild.commands.set(requestBody).catch((error) => {
140
+ console.log(
141
+ colors_default.red(
142
+ `\u274C Error ${reloading ? "reloading" : "loading"} developer application commands in guild "${targetGuild?.name || guildId}".
143
+ `
144
+ )
145
+ );
146
+ throw new Error(error);
147
+ });
148
+ console.log(
149
+ colors_default.green(
150
+ `\u2705 ${reloading ? "Reloaded" : "Loaded"} ${requestBody.length} developer commands in guild "${targetGuild.name}".`
151
+ )
152
+ );
153
+ }
154
+ }
155
+
156
+ // src/handlers/command-handler/utils/areSlashCommandsDifferent.ts
157
+ function areSlashCommandsDifferent(appCommand, localCommand) {
158
+ if (!appCommand.options)
159
+ appCommand.options = [];
160
+ if (!localCommand.options)
161
+ localCommand.options = [];
162
+ if (!appCommand.description)
163
+ appCommand.description = "";
164
+ if (!localCommand.description)
165
+ localCommand.description = "";
166
+ if (localCommand.description !== appCommand.description || localCommand.options.length !== appCommand.options.length) {
167
+ return true;
168
+ }
169
+ }
170
+
171
+ // src/handlers/command-handler/functions/registerCommands.ts
172
+ async function registerCommands(props) {
173
+ if (props.reloading) {
174
+ if (props.client.isReady()) {
175
+ await handleRegistration(props.client, props.commands, props.devGuildIds, props.type);
176
+ } else {
177
+ throw new Error(colors_default.red(`\u274C Cannot reload commands when client is not ready.`));
178
+ }
179
+ } else {
180
+ props.client.once("ready", async (c) => {
181
+ await handleRegistration(c, props.commands, props.devGuildIds, props.type);
182
+ });
183
+ }
184
+ }
185
+ async function handleRegistration(client, commands, devGuildIds, type) {
186
+ const devOnlyCommands = commands.filter((cmd) => cmd.options?.devOnly);
187
+ const globalCommands = commands.filter((cmd) => !cmd.options?.devOnly);
188
+ if (type === "dev") {
189
+ await registerDevCommands(client, devOnlyCommands, devGuildIds);
190
+ } else if (type === "global") {
191
+ await registerGlobalCommands(client, globalCommands);
192
+ } else {
193
+ await registerDevCommands(client, devOnlyCommands, devGuildIds);
194
+ await registerGlobalCommands(client, globalCommands);
195
+ }
196
+ }
197
+ async function registerGlobalCommands(client, commands) {
198
+ const appCommandsManager = client.application.commands;
199
+ await appCommandsManager.fetch();
200
+ for (const command of commands) {
201
+ const targetCommand = appCommandsManager.cache.find(
202
+ (cmd) => cmd.name === command.data.name
203
+ );
204
+ if (command.options?.deleted) {
205
+ if (!targetCommand) {
206
+ console.log(
207
+ colors_default.yellow(
208
+ `\u23E9 Ignoring: Command "${command.data.name}" is globally marked as deleted.`
209
+ )
210
+ );
211
+ } else {
212
+ targetCommand.delete().then(() => {
213
+ console.log(
214
+ colors_default.green(`\u{1F6AE} Deleted command "${command.data.name}" globally.`)
215
+ );
216
+ });
217
+ }
218
+ continue;
219
+ }
220
+ if (targetCommand) {
221
+ const commandsAreDifferent = areSlashCommandsDifferent(targetCommand, command.data);
222
+ if (commandsAreDifferent) {
223
+ targetCommand.edit(command.data).then(() => {
224
+ console.log(
225
+ colors_default.green(`\u2705 Edited command "${command.data.name}" globally.`)
226
+ );
227
+ }).catch((error) => {
228
+ console.log(
229
+ colors_default.red(
230
+ `\u274C Failed to edit command "${command.data.name}" globally.`
231
+ )
232
+ );
233
+ console.error(error);
234
+ });
235
+ continue;
236
+ }
237
+ }
238
+ if (targetCommand)
239
+ continue;
240
+ appCommandsManager.create(command.data).then(() => {
241
+ console.log(colors_default.green(`\u2705 Registered command "${command.data.name}" globally.`));
242
+ }).catch((error) => {
243
+ console.log(
244
+ colors_default.red(`\u274C Failed to register command "${command.data.name}" globally.`)
245
+ );
246
+ console.error(error);
247
+ });
248
+ }
249
+ }
250
+ async function registerDevCommands(client, commands, guildIds) {
251
+ const devGuilds = [];
252
+ for (const guildId of guildIds) {
253
+ const guild = client.guilds.cache.get(guildId) || await client.guilds.fetch(guildId);
254
+ if (!guild) {
255
+ console.log(
256
+ colors_default.yellow(
257
+ `\u23E9 Ignoring: Guild ${guildId} does not exist or client isn't in this guild.`
258
+ )
259
+ );
260
+ continue;
261
+ }
262
+ devGuilds.push(guild);
263
+ }
264
+ const guildCommandsManagers = [];
265
+ for (const guild of devGuilds) {
266
+ const guildCommandsManager = guild.commands;
267
+ await guildCommandsManager.fetch();
268
+ guildCommandsManagers.push(guildCommandsManager);
269
+ }
270
+ for (const command of commands) {
271
+ for (const guildCommands of guildCommandsManagers) {
272
+ const targetCommand = guildCommands.cache.find((cmd) => cmd.name === command.data.name);
273
+ if (command.options?.deleted) {
274
+ if (!targetCommand) {
275
+ console.log(
276
+ colors_default.yellow(
277
+ `\u23E9 Ignoring: Command "${command.data.name}" is marked as deleted for ${guildCommands.guild.name}.`
278
+ )
279
+ );
280
+ } else {
281
+ targetCommand.delete().then(() => {
282
+ console.log(
283
+ colors_default.green(
284
+ `\u{1F6AE} Deleted command "${command.data.name}" in ${guildCommands.guild.name}.`
285
+ )
286
+ );
287
+ });
288
+ }
289
+ continue;
290
+ }
291
+ if (targetCommand) {
292
+ const commandsAreDifferent = areSlashCommandsDifferent(targetCommand, command.data);
293
+ if (commandsAreDifferent) {
294
+ targetCommand.edit(command.data).then(() => {
295
+ console.log(
296
+ colors_default.green(
297
+ `\u2705 Edited command "${command.data.name}" in ${guildCommands.guild.name}.`
298
+ )
299
+ );
300
+ }).catch((error) => {
301
+ console.log(
302
+ colors_default.red(
303
+ `\u274C Failed to edit command "${command.data.name}" in ${guildCommands.guild.name}.`
304
+ )
305
+ );
306
+ console.error(error);
307
+ });
308
+ continue;
309
+ }
310
+ }
311
+ if (targetCommand)
312
+ continue;
313
+ guildCommands.create(command.data).then(() => {
314
+ console.log(
315
+ colors_default.green(
316
+ `\u2705 Registered command "${command.data.name}" in ${guildCommands.guild.name}.`
317
+ )
318
+ );
319
+ }).catch((error) => {
320
+ console.log(
321
+ colors_default.red(
322
+ `\u274C Failed to register command "${command.data.name}" in ${guildCommands.guild.name}.`
323
+ )
324
+ );
325
+ console.error(error);
326
+ });
327
+ }
328
+ }
42
329
  }
43
330
 
44
331
  // src/handlers/command-handler/validations/botPermissions.ts
@@ -82,7 +369,7 @@ function devOnly_default({ interaction, targetCommand, handlerData }) {
82
369
  const memberRoles = guildMember?.roles.cache;
83
370
  let hasDevRole = false;
84
371
  memberRoles?.forEach((role) => {
85
- if (handlerData.devRoleIds?.includes(role.id)) {
372
+ if (handlerData.devRoleIds.includes(role.id)) {
86
373
  hasDevRole = true;
87
374
  }
88
375
  });
@@ -138,254 +425,13 @@ function userPermissions_default({ interaction, targetCommand }) {
138
425
  // src/handlers/command-handler/validations/index.ts
139
426
  var validations_default = [botPermissions_default, devOnly_default, guildOnly_default, userPermissions_default];
140
427
 
141
- // src/handlers/command-handler/utils/areSlashCommandsDifferent.ts
142
- function areSlashCommandsDifferent(appCommand, localCommand) {
143
- if (!appCommand.options)
144
- appCommand.options = [];
145
- if (!localCommand.options)
146
- localCommand.options = [];
147
- if (!appCommand.description)
148
- appCommand.description = "";
149
- if (!localCommand.description)
150
- localCommand.description = "";
151
- if (localCommand.description !== appCommand.description || localCommand.options.length !== appCommand.options.length) {
152
- return true;
153
- }
154
- }
155
-
156
- // src/handlers/command-handler/functions/registerCommands.ts
157
- import colors from "colors/safe";
158
- async function registerCommands(commandHandler) {
159
- const client = commandHandler._data.client;
160
- const devGuildIds = commandHandler._data.devGuildIds;
161
- const commands = commandHandler._data.commands;
162
- client.once("ready", async () => {
163
- const devGuilds = [];
164
- for (const devGuildId of devGuildIds) {
165
- const guild = client.guilds.cache.get(devGuildId);
166
- if (!guild) {
167
- console.log(
168
- colors.yellow(
169
- `\u23E9 Ignoring: Guild ${devGuildId} does not exist or client isn't in this guild.`
170
- )
171
- );
172
- continue;
173
- }
174
- devGuilds.push(guild);
175
- }
176
- const appCommands = client.application?.commands;
177
- await appCommands?.fetch();
178
- const devGuildCommands = [];
179
- for (const guild of devGuilds) {
180
- const guildCommands = guild.commands;
181
- await guildCommands?.fetch();
182
- devGuildCommands.push(guildCommands);
183
- }
184
- for (const command of commands) {
185
- let commandData = command.data;
186
- if (command.options?.deleted) {
187
- const targetCommand = appCommands?.cache.find(
188
- (cmd) => cmd.name === commandData.name
189
- );
190
- if (!targetCommand) {
191
- console.log(
192
- colors.yellow(
193
- `\u23E9 Ignoring: Command "${commandData.name}" is globally marked as deleted.`
194
- )
195
- );
196
- } else {
197
- targetCommand.delete().then(() => {
198
- console.log(
199
- colors.green(`\u{1F6AE} Deleted command "${commandData.name}" globally.`)
200
- );
201
- });
202
- }
203
- for (const guildCommands of devGuildCommands) {
204
- const targetCommand2 = guildCommands.cache.find(
205
- (cmd) => cmd.name === commandData.name
206
- );
207
- if (!targetCommand2) {
208
- console.log(
209
- colors.yellow(
210
- `\u23E9 Ignoring: Command "${commandData.name}" is marked as deleted for ${guildCommands.guild.name}.`
211
- )
212
- );
213
- } else {
214
- targetCommand2.delete().then(() => {
215
- console.log(
216
- colors.green(
217
- `\u{1F6AE} Deleted command "${commandData.name}" in ${guildCommands.guild.name}.`
218
- )
219
- );
220
- });
221
- }
222
- }
223
- continue;
224
- }
225
- let editedCommand = false;
226
- const appGlobalCommand = appCommands?.cache.find(
227
- (cmd) => cmd.name === commandData.name
228
- );
229
- if (appGlobalCommand) {
230
- const commandsAreDifferent = areSlashCommandsDifferent(
231
- appGlobalCommand,
232
- commandData
233
- );
234
- if (commandsAreDifferent) {
235
- appGlobalCommand.edit(commandData).then(() => {
236
- console.log(
237
- colors.green(`\u2705 Edited command "${commandData.name}" globally.`)
238
- );
239
- }).catch((error) => {
240
- console.log(
241
- colors.red(
242
- `\u274C Failed to edit command "${commandData.name}" globally.`
243
- )
244
- );
245
- console.error(error);
246
- });
247
- editedCommand = true;
248
- }
249
- }
250
- for (const guildCommands of devGuildCommands) {
251
- const appGuildCommand = guildCommands.cache.find(
252
- (cmd) => cmd.name === commandData.name
253
- );
254
- if (appGuildCommand) {
255
- const commandsAreDifferent = areSlashCommandsDifferent(
256
- appGuildCommand,
257
- commandData
258
- );
259
- if (commandsAreDifferent) {
260
- appGuildCommand.edit(commandData).then(() => {
261
- console.log(
262
- colors.green(
263
- `\u2705 Edited command "${commandData.name}" in ${guildCommands.guild.name}.`
264
- )
265
- );
266
- }).catch((error) => {
267
- console.log(
268
- colors.red(
269
- `\u274C Failed to edit command "${commandData.name}" in ${guildCommands.guild.name}.`
270
- )
271
- );
272
- console.error(error);
273
- });
274
- editedCommand = true;
275
- }
276
- }
277
- }
278
- if (editedCommand)
279
- continue;
280
- if (command.options?.devOnly) {
281
- if (!devGuilds.length) {
282
- console.log(
283
- colors.yellow(
284
- `\u23E9 Ignoring: Cannot register command "${commandData.name}" as no valid "devGuildIds" were provided.`
285
- )
286
- );
287
- continue;
288
- }
289
- for (const guild of devGuilds) {
290
- const cmdExists = guild.commands.cache.some(
291
- (cmd) => cmd.name === commandData.name
292
- );
293
- if (cmdExists)
294
- continue;
295
- guild?.commands.create(commandData).then(() => {
296
- console.log(
297
- colors.green(
298
- `\u2705 Registered command "${commandData.name}" in ${guild.name}.`
299
- )
300
- );
301
- }).catch((error) => {
302
- console.log(
303
- colors.red(
304
- `\u274C Failed to register command "${commandData.name}" in ${guild.name}.`
305
- )
306
- );
307
- console.error(error);
308
- });
309
- }
310
- } else {
311
- const cmdExists = appCommands?.cache.some((cmd) => cmd.name === commandData.name);
312
- if (cmdExists)
313
- continue;
314
- appCommands?.create(commandData).then(() => {
315
- console.log(
316
- colors.green(`\u2705 Registered command "${commandData.name}" globally.`)
317
- );
318
- }).catch((error) => {
319
- console.log(
320
- colors.red(
321
- `\u274C Failed to register command "${commandData.name}" globally.`
322
- )
323
- );
324
- console.error(error);
325
- });
326
- }
327
- }
328
- });
329
- }
330
-
331
- // src/handlers/command-handler/functions/handleCommands.ts
332
- function handleCommands(commandHandler) {
333
- const client = commandHandler._data.client;
334
- const handler = commandHandler._data.commandKitInstance;
335
- client.on("interactionCreate", async (interaction) => {
336
- if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand())
337
- return;
338
- const targetCommand = commandHandler._data.commands.find(
339
- (cmd) => cmd.data.name === interaction.commandName
340
- );
341
- if (!targetCommand)
342
- return;
343
- const { data, options, run, ...rest } = targetCommand;
344
- const commandObj = {
345
- data: targetCommand.data,
346
- options: targetCommand.options,
347
- ...rest
348
- };
349
- let canRun = true;
350
- for (const validationFunction of commandHandler._data.customValidations) {
351
- const stopValidationLoop = await validationFunction({
352
- interaction,
353
- client,
354
- commandObj,
355
- handler
356
- });
357
- if (stopValidationLoop) {
358
- canRun = false;
359
- break;
360
- }
361
- }
362
- if (!canRun)
363
- return;
364
- if (!commandHandler._data.skipBuiltInValidations) {
365
- for (const validation of commandHandler._data.builtInValidations) {
366
- const stopValidationLoop = validation({
367
- targetCommand,
368
- interaction,
369
- handlerData: commandHandler._data
370
- });
371
- if (stopValidationLoop) {
372
- canRun = false;
373
- break;
374
- }
375
- }
376
- }
377
- if (!canRun)
378
- return;
379
- targetCommand.run({ interaction, client, handler });
380
- });
381
- }
382
-
383
428
  // src/handlers/command-handler/CommandHandler.ts
384
- import colors2 from "colors/safe";
429
+ import rdfc from "rfdc";
430
+ var clone = rdfc();
385
431
  var CommandHandler = class {
386
- _data;
432
+ #data;
387
433
  constructor({ ...options }) {
388
- this._data = {
434
+ this.#data = {
389
435
  ...options,
390
436
  builtInValidations: [],
391
437
  commands: []
@@ -394,54 +440,177 @@ var CommandHandler = class {
394
440
  async init() {
395
441
  await this.#buildCommands();
396
442
  this.#buildValidations();
397
- await this.#registerCommands();
443
+ const devOnlyCommands = this.#data.commands.filter((cmd) => cmd.options?.devOnly);
444
+ if (devOnlyCommands.length && !this.#data.devGuildIds.length) {
445
+ console.log(
446
+ colors_default.yellow(
447
+ '\u2139\uFE0F Warning: You have commands marked as "devOnly" but "devGuildIds" has not been set.'
448
+ )
449
+ );
450
+ }
451
+ if (devOnlyCommands.length && !this.#data.devUserIds.length && !this.#data.devRoleIds.length) {
452
+ console.log(
453
+ colors_default.yellow(
454
+ '\u2139\uFE0F Warning: You have commands marked as "devOnly" but not "devUserIds" or "devRoleIds" were set.'
455
+ )
456
+ );
457
+ }
458
+ if (this.#data.useRest) {
459
+ await loadCommandsWithRest({
460
+ client: this.#data.client,
461
+ devGuildIds: this.#data.devGuildIds,
462
+ commands: this.#data.commands
463
+ });
464
+ } else {
465
+ await registerCommands({
466
+ client: this.#data.client,
467
+ devGuildIds: this.#data.devGuildIds,
468
+ commands: this.#data.commands
469
+ });
470
+ }
398
471
  this.#handleCommands();
399
472
  }
400
473
  async #buildCommands() {
401
- const commandFilePaths = getFilePaths(this._data.commandsPath, true).filter(
402
- (path3) => path3.endsWith(".js") || path3.endsWith(".ts")
474
+ const allowedExtensions = /\.(js|mjs|cjs|ts)$/i;
475
+ const commandFilePaths = getFilePaths(this.#data.commandsPath, true).filter(
476
+ (path3) => allowedExtensions.test(path3)
403
477
  );
404
478
  for (const commandFilePath of commandFilePaths) {
405
479
  const modulePath = toFileURL(commandFilePath);
406
- let commandObj = await import(modulePath);
480
+ let importedObj = await import(`${modulePath}?t=${Date.now()}`);
481
+ let commandObj = clone(importedObj);
482
+ if (typeof module !== "undefined" && typeof __require !== "undefined") {
483
+ delete __require.cache[__require.resolve(commandFilePath)];
484
+ }
407
485
  const compactFilePath = commandFilePath.split(process.cwd())[1] || commandFilePath;
408
486
  if (commandObj.default)
409
487
  commandObj = commandObj.default;
410
488
  if (!commandObj.data) {
411
489
  console.log(
412
- colors2.yellow(
490
+ colors_default.yellow(
413
491
  `\u23E9 Ignoring: Command ${compactFilePath} does not export "data".`
414
492
  )
415
493
  );
416
494
  continue;
417
495
  }
496
+ if (!commandObj.data.name) {
497
+ console.log(
498
+ colors_default.yellow(
499
+ `\u23E9 Ignoring: Command ${compactFilePath} does not export "data.name".`
500
+ )
501
+ );
502
+ continue;
503
+ }
418
504
  if (!commandObj.run) {
419
505
  console.log(
420
- colors2.yellow(`\u23E9 Ignoring: Command ${compactFilePath} does not export "run".`)
506
+ colors_default.yellow(
507
+ `\u23E9 Ignoring: Command ${commandObj.data.name} does not export "run".`
508
+ )
509
+ );
510
+ continue;
511
+ }
512
+ if (typeof commandObj.run !== "function") {
513
+ console.log(
514
+ colors_default.yellow(
515
+ `\u23E9 Ignoring: Command ${commandObj.data.name} does not export "run" as a function.`
516
+ )
421
517
  );
422
518
  continue;
423
519
  }
424
- this._data.commands.push(commandObj);
520
+ commandObj.filePath = commandFilePath;
521
+ let commandCategory = commandFilePath.split(this.#data.commandsPath)[1]?.replace(/\\\\|\\/g, "/").split("/")[1] || null;
522
+ if (commandCategory && allowedExtensions.test(commandCategory)) {
523
+ commandObj.category = null;
524
+ } else {
525
+ commandObj.category = commandCategory;
526
+ }
527
+ this.#data.commands.push(commandObj);
425
528
  }
426
529
  }
427
530
  #buildValidations() {
428
531
  for (const validationFunction of validations_default) {
429
- this._data.builtInValidations.push(validationFunction);
532
+ this.#data.builtInValidations.push(validationFunction);
430
533
  }
431
534
  }
432
- async #registerCommands() {
433
- await registerCommands(this);
434
- }
435
535
  #handleCommands() {
436
- handleCommands(this);
536
+ this.#data.client.on("interactionCreate", async (interaction) => {
537
+ if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand())
538
+ return;
539
+ const targetCommand = this.#data.commands.find(
540
+ (cmd) => cmd.data.name === interaction.commandName
541
+ );
542
+ if (!targetCommand)
543
+ return;
544
+ const { data, options, run, ...rest } = targetCommand;
545
+ const commandObj = {
546
+ data: targetCommand.data,
547
+ options: targetCommand.options,
548
+ ...rest
549
+ };
550
+ let canRun = true;
551
+ for (const validationFunction of this.#data.customValidations) {
552
+ const stopValidationLoop = await validationFunction({
553
+ interaction,
554
+ commandObj,
555
+ client: this.#data.client,
556
+ handler: this.#data.handler
557
+ });
558
+ if (stopValidationLoop) {
559
+ canRun = false;
560
+ break;
561
+ }
562
+ }
563
+ if (!canRun)
564
+ return;
565
+ if (!this.#data.skipBuiltInValidations) {
566
+ for (const validation of this.#data.builtInValidations) {
567
+ const stopValidationLoop = validation({
568
+ targetCommand,
569
+ interaction,
570
+ handlerData: this.#data
571
+ });
572
+ if (stopValidationLoop) {
573
+ canRun = false;
574
+ break;
575
+ }
576
+ }
577
+ }
578
+ if (!canRun)
579
+ return;
580
+ targetCommand.run({
581
+ interaction,
582
+ client: this.#data.client,
583
+ handler: this.#data.handler
584
+ });
585
+ });
437
586
  }
438
587
  get commands() {
439
- return this._data.commands;
588
+ return this.#data.commands;
589
+ }
590
+ async reloadCommands(type) {
591
+ this.#data.commands = [];
592
+ await this.#buildCommands();
593
+ if (this.#data.useRest) {
594
+ await loadCommandsWithRest({
595
+ client: this.#data.client,
596
+ devGuildIds: this.#data.devGuildIds,
597
+ commands: this.#data.commands,
598
+ reloading: true,
599
+ type
600
+ });
601
+ } else {
602
+ await registerCommands({
603
+ client: this.#data.client,
604
+ devGuildIds: this.#data.devGuildIds,
605
+ commands: this.#data.commands,
606
+ reloading: true,
607
+ type
608
+ });
609
+ }
440
610
  }
441
611
  };
442
612
 
443
613
  // src/handlers/event-handler/EventHandler.ts
444
- import colors3 from "colors/safe";
445
614
  var EventHandler = class {
446
615
  #data;
447
616
  constructor({ ...options }) {
@@ -457,7 +626,7 @@ var EventHandler = class {
457
626
  async #buildEvents() {
458
627
  const eventFolderPaths = getFolderPaths(this.#data.eventsPath);
459
628
  for (const eventFolderPath of eventFolderPaths) {
460
- const eventName = eventFolderPath.replace(/\\/g, "/").split("/").pop();
629
+ const eventName = eventFolderPath.replace(/\\\\|\\/g, "/").split("/").pop();
461
630
  const eventFilePaths = getFilePaths(eventFolderPath, true).filter(
462
631
  (path3) => path3.endsWith(".js") || path3.endsWith(".ts")
463
632
  );
@@ -475,7 +644,7 @@ var EventHandler = class {
475
644
  const compactFilePath = eventFilePath.split(process.cwd())[1] || eventFilePath;
476
645
  if (typeof eventFunction !== "function") {
477
646
  console.log(
478
- colors3.yellow(
647
+ colors_default.yellow(
479
648
  `\u23E9 Ignoring: Event ${compactFilePath} does not export a function.`
480
649
  )
481
650
  );
@@ -505,7 +674,6 @@ var EventHandler = class {
505
674
  };
506
675
 
507
676
  // src/handlers/validation-handler/ValidationHandler.ts
508
- import colors4 from "colors/safe";
509
677
  var ValidationHandler = class {
510
678
  #data;
511
679
  constructor({ ...options }) {
@@ -530,7 +698,7 @@ var ValidationHandler = class {
530
698
  const compactFilePath = validationFilePath.split(process.cwd())[1] || validationFilePath;
531
699
  if (typeof validationFunction !== "function") {
532
700
  console.log(
533
- colors4.yellow(
701
+ colors_default.yellow(
534
702
  `\u23E9 Ignoring: Validation ${compactFilePath} does not export a function.`
535
703
  )
536
704
  );
@@ -545,22 +713,18 @@ var ValidationHandler = class {
545
713
  };
546
714
 
547
715
  // src/CommandKit.ts
548
- import colors5 from "colors/safe";
549
716
  var CommandKit = class {
550
717
  #data;
551
- constructor({ ...options }) {
718
+ constructor(options) {
552
719
  if (!options.client) {
553
- throw new Error(colors5.red('"client" is required when instantiating CommandKit.'));
720
+ throw new Error(colors_default.red('"client" is required when instantiating CommandKit.'));
554
721
  }
555
722
  if (options.validationsPath && !options.commandsPath) {
556
723
  throw new Error(
557
- colors5.red('"commandsPath" is required when "validationsPath" is set.')
724
+ colors_default.red('"commandsPath" is required when "validationsPath" is set.')
558
725
  );
559
726
  }
560
- this.#data = {
561
- ...options,
562
- commands: []
563
- };
727
+ this.#data = options;
564
728
  this.#init();
565
729
  }
566
730
  async #init() {
@@ -571,6 +735,7 @@ var CommandKit = class {
571
735
  commandKitInstance: this
572
736
  });
573
737
  await eventHandler.init();
738
+ this.#data.eventHandler = eventHandler;
574
739
  }
575
740
  let validationFunctions = [];
576
741
  if (this.#data.validationsPath) {
@@ -579,6 +744,7 @@ var CommandKit = class {
579
744
  });
580
745
  await validationHandler.init();
581
746
  validationHandler.validations.forEach((v) => validationFunctions.push(v));
747
+ this.#data.validationHandler = validationHandler;
582
748
  }
583
749
  if (this.#data.commandsPath) {
584
750
  const commandHandler = new CommandHandler({
@@ -589,24 +755,71 @@ var CommandKit = class {
589
755
  devRoleIds: this.#data.devRoleIds || [],
590
756
  customValidations: validationFunctions,
591
757
  skipBuiltInValidations: this.#data.skipBuiltInValidations || false,
592
- commandKitInstance: this
758
+ handler: this,
759
+ useRest: this.#data.useRest || false
593
760
  });
594
761
  await commandHandler.init();
595
- this.#data.commands = commandHandler.commands;
762
+ this.#data.commandHandler = commandHandler;
596
763
  }
597
764
  }
598
765
  /**
599
- * Returns all the commands that CommandKit is handling.
600
- *
601
- * @returns An array of command objects
766
+ * Updates application commands with the latest from "commandsPath".
767
+ * @experimental
768
+ */
769
+ async reloadCommands(type) {
770
+ if (!this.#data.commandHandler)
771
+ return;
772
+ await this.#data.commandHandler.reloadCommands(type);
773
+ }
774
+ /**
775
+ * @returns An array of objects of all the commands that CommandKit is handling.
602
776
  */
603
777
  get commands() {
604
- const commands = this.#data.commands.map((cmd) => {
778
+ if (!this.#data.commandHandler) {
779
+ return [];
780
+ }
781
+ const commands = this.#data.commandHandler.commands.map((cmd) => {
605
782
  const { run, ...command } = cmd;
606
783
  return command;
607
784
  });
608
785
  return commands;
609
786
  }
787
+ /**
788
+ * @returns The path to the commands folder which was set when instantiating CommandKit.
789
+ */
790
+ get commandsPath() {
791
+ return this.#data.commandsPath;
792
+ }
793
+ /**
794
+ * @returns The path to the events folder which was set when instantiating CommandKit.
795
+ */
796
+ get eventsPath() {
797
+ return this.#data.eventsPath;
798
+ }
799
+ /**
800
+ * @returns The path to the validations folder which was set when instantiating CommandKit.
801
+ */
802
+ get validationsPath() {
803
+ return this.#data.validationsPath;
804
+ }
805
+ /**
806
+ * @returns An array of all the developer user IDs which was set when instantiating CommandKit.
807
+ */
808
+ get devUserIds() {
809
+ return this.#data.devUserIds || [];
810
+ }
811
+ /**
812
+ * @returns An array of all the developer guild IDs which was set when instantiating CommandKit.
813
+ */
814
+ get devGuildIds() {
815
+ return this.#data.devGuildIds || [];
816
+ }
817
+ /**
818
+ * @returns An array of all the developer role IDs which was set when instantiating CommandKit.
819
+ */
820
+ get devRoleIds() {
821
+ return this.#data.devRoleIds || [];
822
+ }
610
823
  };
611
824
 
612
825
  // src/types/index.ts
@@ -616,7 +829,13 @@ var CommandType = /* @__PURE__ */ ((CommandType2) => {
616
829
  CommandType2[CommandType2["User"] = 2] = "User";
617
830
  return CommandType2;
618
831
  })(CommandType || {});
832
+ var ReloadType = /* @__PURE__ */ ((ReloadType2) => {
833
+ ReloadType2["Developer"] = "dev";
834
+ ReloadType2["Global"] = "global";
835
+ return ReloadType2;
836
+ })(ReloadType || {});
619
837
  export {
620
838
  CommandKit,
621
- CommandType
839
+ CommandType,
840
+ ReloadType
622
841
  };