Skip to content

Commit 08c7e9f

Browse files
committed
add type defs + update built-in validations
1 parent 4b739a3 commit 08c7e9f

File tree

11 files changed

+181
-102
lines changed

11 files changed

+181
-102
lines changed

packages/commandkit/src/CommandKit.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CommandHandler, EventHandler, ValidationHandler } from './handlers';
2-
import { CommandKitData, CommandKitOptions, CommandFileObject } from './typings';
2+
import { CommandKitData, CommandKitOptions } from './typings';
3+
import { CommandFileObject } from './types';
34
import colors from 'colors/safe';
45

56
export class CommandKit {
@@ -25,30 +26,26 @@ export class CommandKit {
2526
}
2627

2728
async #init() {
28-
// Event handler
2929
if (this.#data.eventsPath) {
3030
const eventHandler = new EventHandler({
3131
client: this.#data.client,
3232
eventsPath: this.#data.eventsPath,
33+
commandKitInstance: this,
3334
});
3435

3536
await eventHandler.init();
3637
}
3738

38-
// Validation handler
3939
let validationFunctions: Function[] = [];
40-
4140
if (this.#data.validationsPath) {
4241
const validationHandler = new ValidationHandler({
4342
validationsPath: this.#data.validationsPath,
4443
});
4544

4645
await validationHandler.init();
47-
4846
validationHandler.validations.forEach((v) => validationFunctions.push(v));
4947
}
5048

51-
// Command handler
5249
if (this.#data.commandsPath) {
5350
const commandHandler = new CommandHandler({
5451
client: this.#data.client,
@@ -58,14 +55,19 @@ export class CommandKit {
5855
devRoleIds: this.#data.devRoleIds || [],
5956
customValidations: validationFunctions,
6057
skipBuiltInValidations: this.#data.skipBuiltInValidations || false,
58+
commandKitInstance: this,
6159
});
6260

6361
await commandHandler.init();
64-
6562
this.#data.commands = commandHandler.commands;
6663
}
6764
}
6865

66+
/**
67+
* Returns all the commands that CommandKit is handling.
68+
*
69+
* @returns An array of command objects
70+
*/
6971
get commands(): CommandFileObject[] {
7072
const commands = this.#data.commands.map((cmd) => {
7173
const { run, ...command } = cmd;

packages/commandkit/src/handlers/command-handler/functions/handleCommands.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { CommandHandler } from '../CommandHandler';
22

33
export default function handleCommands(commandHandler: CommandHandler) {
44
const client = commandHandler._data.client;
5+
const handler = commandHandler._data.commandKitInstance;
56

67
client.on('interactionCreate', async (interaction) => {
78
if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand()) return;
@@ -27,6 +28,7 @@ export default function handleCommands(commandHandler: CommandHandler) {
2728
interaction,
2829
client,
2930
commandObj,
31+
handler,
3032
});
3133

3234
if (stopValidationLoop) {
@@ -55,6 +57,6 @@ export default function handleCommands(commandHandler: CommandHandler) {
5557

5658
if (!canRun) return;
5759

58-
targetCommand.run({ interaction, client });
60+
targetCommand.run({ interaction, client, handler });
5961
});
6062
}

packages/commandkit/src/handlers/command-handler/typings.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ChatInputCommandInteraction, Client, ContextMenuCommandInteraction } from 'discord.js';
22
import { ContextCommandObject, SlashCommandObject } from '../../typings';
3+
import { CommandKit } from '../../CommandKit';
34

45
export interface CommandHandlerOptions {
56
client: Client;
@@ -9,6 +10,7 @@ export interface CommandHandlerOptions {
910
devRoleIds: string[];
1011
customValidations: Function[];
1112
skipBuiltInValidations: boolean;
13+
commandKitInstance: CommandKit;
1214
}
1315

1416
export interface CommandHandlerData extends CommandHandlerOptions {

packages/commandkit/src/handlers/command-handler/validations/botPermissions.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,32 @@ import { BuiltInValidationParams } from '../typings';
22

33
export default function ({ interaction, targetCommand }: BuiltInValidationParams) {
44
const botMember = interaction.guild?.members.me;
5+
let commandPermissions = targetCommand.options?.botPermissions;
56

6-
if (targetCommand.options?.botPermissions && botMember) {
7-
const missingPermissions: string[] = [];
7+
if (!botMember || !commandPermissions) return;
88

9-
for (const permission of targetCommand.options.botPermissions) {
10-
const hasPermission = botMember.permissions.has(permission);
9+
if (!Array.isArray(commandPermissions)) {
10+
commandPermissions = [commandPermissions];
11+
}
1112

12-
if (!hasPermission) {
13-
missingPermissions.push(`\`${permission.toString()}\``);
14-
}
15-
}
13+
const missingPermissions: string[] = [];
1614

17-
if (missingPermissions.length) {
18-
interaction.reply({
19-
content: `❌ I do not have enough permission to execute this command. Missing: ${missingPermissions.join(
20-
', ',
21-
)}`,
22-
ephemeral: true,
23-
});
15+
for (const permission of commandPermissions) {
16+
const hasPermission = botMember.permissions.has(permission);
2417

25-
return true;
18+
if (!hasPermission) {
19+
missingPermissions.push(`\`${permission.toString()}\``);
2620
}
2721
}
22+
23+
if (missingPermissions.length) {
24+
interaction.reply({
25+
content: `❌ I do not have enough permissions to execute this command. Missing: ${missingPermissions.join(
26+
', ',
27+
)}`,
28+
ephemeral: true,
29+
});
30+
31+
return true;
32+
}
2833
}

packages/commandkit/src/handlers/command-handler/validations/userPermissions.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,32 @@ import { BuiltInValidationParams } from '../typings';
22

33
export default function ({ interaction, targetCommand }: BuiltInValidationParams) {
44
const memberPermissions = interaction.memberPermissions;
5+
let commandPermissions = targetCommand.options?.userPermissions;
56

6-
if (targetCommand.options?.userPermissions && memberPermissions) {
7-
const missingPermissions: string[] = [];
7+
if (!memberPermissions || !commandPermissions) return;
88

9-
for (const permission of targetCommand.options.userPermissions) {
10-
const hasPermission = memberPermissions.has(permission);
9+
if (!Array.isArray(commandPermissions)) {
10+
commandPermissions = [commandPermissions];
11+
}
1112

12-
if (!hasPermission) {
13-
missingPermissions.push(`\`${permission.toString()}\``);
14-
}
15-
}
13+
const missingPermissions: string[] = [];
1614

17-
if (missingPermissions.length) {
18-
interaction.reply({
19-
content: `❌ You do not have enough permission to run this command. Missing: ${missingPermissions.join(
20-
', ',
21-
)}`,
22-
ephemeral: true,
23-
});
15+
for (const permission of commandPermissions) {
16+
const hasPermission = memberPermissions.has(permission);
2417

25-
return true;
18+
if (!hasPermission) {
19+
missingPermissions.push(`\`${permission.toString()}\``);
2620
}
2721
}
22+
23+
if (missingPermissions.length) {
24+
interaction.reply({
25+
content: `❌ You do not have enough permissions to run this command. Missing: ${missingPermissions.join(
26+
', ',
27+
)}`,
28+
ephemeral: true,
29+
});
30+
31+
return true;
32+
}
2833
}

packages/commandkit/src/handlers/event-handler/EventHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,12 @@ export class EventHandler {
5757

5858
#registerEvents() {
5959
const client = this.#data.client;
60+
const handler = this.#data.commandKitInstance;
6061

6162
for (const eventObj of this.#data.events) {
6263
client.on(eventObj.name, async (...params) => {
6364
for (const eventFunction of eventObj.functions) {
64-
const stopEventLoop = await eventFunction(...params, client);
65+
const stopEventLoop = await eventFunction(...params, client, handler);
6566

6667
if (stopEventLoop) {
6768
break;

packages/commandkit/src/handlers/event-handler/typings.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { Client } from 'discord.js';
2+
import { CommandKit } from '../../CommandKit';
23

34
export interface EventHandlerOptions {
45
client: Client;
56
eventsPath: string;
7+
commandKitInstance: CommandKit;
68
}
79

810
export interface EventHandlerData extends EventHandlerOptions {

packages/commandkit/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './CommandKit';
2+
export * from './types';
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import type {
2+
Client,
3+
CommandInteraction,
4+
PermissionResolvable,
5+
ChatInputCommandInteraction,
6+
ContextMenuCommandInteraction,
7+
APIApplicationCommandSubcommandOption,
8+
APIApplicationCommandSubcommandGroupOption,
9+
} from 'discord.js';
10+
import type { CommandKit } from '../CommandKit';
11+
import type { ContextCommandObject, SlashCommandObject } from '../typings';
12+
13+
export interface CommandProps {
14+
interaction: CommandInteraction;
15+
client: Client<true>;
16+
handler: CommandKit;
17+
}
18+
19+
export interface SlashCommandProps {
20+
interaction: ChatInputCommandInteraction;
21+
client: Client<true>;
22+
handler: CommandKit;
23+
}
24+
25+
export interface ContextMenuCommandProps {
26+
interaction: ContextMenuCommandInteraction;
27+
client: Client<true>;
28+
handler: CommandKit;
29+
}
30+
31+
export interface ValidationFunctionProps {
32+
interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction;
33+
client: Client<true>;
34+
commandObj: SlashCommandObject | ContextCommandObject;
35+
handler: CommandKit;
36+
}
37+
38+
export interface CommandOptions {
39+
guildOnly?: boolean;
40+
devOnly?: boolean;
41+
deleted?: boolean;
42+
userPermissions?: PermissionResolvable;
43+
botPermissions?: PermissionResolvable;
44+
[key: string]: any;
45+
}
46+
47+
export enum CommandType {
48+
'ChatInput' = 1,
49+
'Message' = 3,
50+
'User' = 2,
51+
}
52+
53+
type LocaleString =
54+
| 'id'
55+
| 'en-US'
56+
| 'en-GB'
57+
| 'bg'
58+
| 'zh-CN'
59+
| 'zh-TW'
60+
| 'hr'
61+
| 'cs'
62+
| 'da'
63+
| 'nl'
64+
| 'fi'
65+
| 'fr'
66+
| 'de'
67+
| 'el'
68+
| 'hi'
69+
| 'hu'
70+
| 'it'
71+
| 'ja'
72+
| 'ko'
73+
| 'lt'
74+
| 'no'
75+
| 'pl'
76+
| 'pt-BR'
77+
| 'ro'
78+
| 'ru'
79+
| 'es-ES'
80+
| 'sv-SE'
81+
| 'th'
82+
| 'tr'
83+
| 'uk'
84+
| 'vi';
85+
86+
export type CommandData = {
87+
name: string;
88+
description: string;
89+
type?: CommandType;
90+
name_localizations?: Partial<Record<LocaleString, string | null>>;
91+
description_localizations?: Partial<Record<LocaleString, string | null>>;
92+
dm_permission?: boolean;
93+
default_member_permissions?: string;
94+
nsfw?: boolean;
95+
options?: Array<
96+
APIApplicationCommandSubcommandOption | APIApplicationCommandSubcommandGroupOption
97+
>;
98+
};
99+
100+
export interface CommandFileObject {
101+
data: CommandData;
102+
options?: CommandOptions;
103+
}

0 commit comments

Comments
 (0)