|
1 | 1 | import { CommandPlugin, CommandType, Command } from '@spark.ts/handler'; |
2 | 2 | import { ChatInputCommandInteraction, Message } from 'discord.js'; |
3 | 3 |
|
4 | | -type RemoveMethods<T> = T extends {} ? { |
5 | | - [P in keyof T as T[P] extends (...args: any[]) => unknown ? never : P]: RemoveMethods<T[P]>; |
| 4 | +type Immutable<T> = T extends {} ? { |
| 5 | + readonly [P in keyof T as T[P] extends (...args: any[]) => unknown ? never : P]: Immutable<T[P]>; |
6 | 6 | } : T; |
7 | 7 |
|
8 | | -type ConditionalMethod = (args: { |
| 8 | +export type Helper = (args: { |
9 | 9 | command: Command, |
10 | | - interaction: RemoveMethods<ChatInputCommandInteraction>, |
11 | | - message: RemoveMethods<Message>; |
| 10 | + interaction: Immutable<ChatInputCommandInteraction>, |
| 11 | + message: Immutable<Message>; |
12 | 12 | }) => unknown; |
13 | 13 |
|
14 | 14 | interface Conditional { |
15 | | - condition: ConditionalMethod | unknown; |
| 15 | + /** |
| 16 | + * The condition or helper to check. |
| 17 | + */ |
| 18 | + condition: Helper | unknown; |
| 19 | + |
| 20 | + /** |
| 21 | + * How to reply to the user if the condition fails. |
| 22 | + */ |
16 | 23 | onFalse?: string; |
17 | 24 | } |
18 | 25 |
|
| 26 | +/** |
| 27 | + * Accepts a number of conditions to check before running a command. |
| 28 | + * @param conditionals All of conditions to check |
| 29 | + * @example |
| 30 | + * export default new SparkCommand({ |
| 31 | + * description: "...", |
| 32 | + * plugins: [ |
| 33 | + * Guard( |
| 34 | + * { |
| 35 | + * condition: Helpers.Not(Helpers.IsBot()) |
| 36 | + * } |
| 37 | + * ) |
| 38 | + * ] |
| 39 | + * }); |
| 40 | + */ |
19 | 41 | export function Guard(...conditionals: Conditional[]): CommandPlugin<CommandType.Both> { |
20 | 42 | return { |
21 | 43 | name: 'guard', |
@@ -43,12 +65,81 @@ export function Guard(...conditionals: Conditional[]): CommandPlugin<CommandType |
43 | 65 | }; |
44 | 66 | } |
45 | 67 |
|
46 | | -export abstract class Helpers { |
47 | | - static InGuild(guilds: string[]): ConditionalMethod { |
| 68 | +export const Helpers = { |
| 69 | + /** |
| 70 | + * Checks if the id of the server the command is used in is in a provided list of guild ids. |
| 71 | + * @param guilds Provided list of guild ids. |
| 72 | + */ |
| 73 | + InGuild(guilds: string[]): Helper { |
48 | 74 | return ({ command, message, interaction }) => guilds.includes((command.type === 'slash' ? interaction : message).guildId!); |
49 | | - } |
| 75 | + }, |
50 | 76 |
|
51 | | - static InChannel(channels: string[]): ConditionalMethod { |
| 77 | + /** |
| 78 | + * Checks if the id of the channel the command is used in is in a provided list of channel ids. |
| 79 | + * @param channels Provided list of channel ids. |
| 80 | + */ |
| 81 | + InChannel(channels: string[]): Helper { |
52 | 82 | return ({ command, message, interaction }) => channels.includes((command.type === 'slash' ? interaction : message).channelId!); |
| 83 | + }, |
| 84 | + |
| 85 | + /** |
| 86 | + * Checks if the id of the user who used the command is in a provided list of user ids. |
| 87 | + * @param users Provided list of user ids. |
| 88 | + */ |
| 89 | + ByUser(users: string[]): Helper { |
| 90 | + return ({ command, message, interaction }) => users.includes((command.type === "slash" ? interaction : message).member?.user.id!); |
| 91 | + }, |
| 92 | + |
| 93 | + /** |
| 94 | + * Checks if the user who used the command is a discord bot or not. |
| 95 | + */ |
| 96 | + IsBot(): Helper { |
| 97 | + return ({ command, message, interaction }) => (command.type === "slash" ? interaction : message).member?.user.bot!; |
| 98 | + }, |
| 99 | + |
| 100 | + /** |
| 101 | + * Checks if the command was used in a discord server or not. |
| 102 | + */ |
| 103 | + InServer(): Helper { |
| 104 | + return ({ command, message, interaction }) => (command.type === "slash" ? interaction : message).guild !== null; |
| 105 | + }, |
| 106 | + |
| 107 | + /** |
| 108 | + * Accepts a helper function and returns true if the condition doesn't pass. Mimics `!` operator. |
| 109 | + * @param condition Helper function to test. |
| 110 | + * @example |
| 111 | + * export default new SparkCommand({ |
| 112 | + * description: "...", |
| 113 | + * plugins: [ |
| 114 | + * Guard( |
| 115 | + * { |
| 116 | + * condition: Helpers.Not(Helpers.IsBot()) // don't use `!Helpers.IsBot()` |
| 117 | + * } |
| 118 | + * ) |
| 119 | + * ] |
| 120 | + * }); |
| 121 | + */ |
| 122 | + Not(condition: Helper): Helper { |
| 123 | + return (o) => !condition(o); |
| 124 | + }, |
| 125 | + |
| 126 | + /** |
| 127 | + * Accepts 2 helper functions and if one turns out to be true then the condition passes. Mimics `||` operator. |
| 128 | + * @param x First helper function to test. |
| 129 | + * @param y Second helper function to test. |
| 130 | + * @example |
| 131 | + * export default new SparkCommand({ |
| 132 | + * description: "...", |
| 133 | + * plugins: [ |
| 134 | + * Guard( |
| 135 | + * { |
| 136 | + * condition: Helpers.Or(Helpers.IsBot(),Helpers.InServer()) |
| 137 | + * } |
| 138 | + * ) |
| 139 | + * ] |
| 140 | + * }); |
| 141 | + */ |
| 142 | + Or(x: Helper,y: Helper): Helper { |
| 143 | + return (o) => x(o) || y(o); |
53 | 144 | } |
54 | 145 | } |
0 commit comments