commandkit 0.1.2 → 0.1.3-dev.20231002193305

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