@pikokr/command.ts 3.2.4-dev.434c22e → 4.0.0-dev.fddc66b

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.
Files changed (182) hide show
  1. package/dist/applicationCommand/AppCommand.d.ts +18 -0
  2. package/dist/applicationCommand/AppCommand.js +25 -0
  3. package/dist/applicationCommand/AppCommand.js.map +1 -0
  4. package/dist/applicationCommand/decorator.d.ts +10 -0
  5. package/dist/{slashCommand → applicationCommand}/decorator.js +12 -8
  6. package/dist/applicationCommand/decorator.js.map +1 -0
  7. package/dist/applicationCommand/index.d.ts +2 -0
  8. package/dist/{slashCommand → applicationCommand}/index.js +4 -1
  9. package/dist/applicationCommand/index.js.map +1 -0
  10. package/dist/builtinModules/BuiltInModule.js +3 -0
  11. package/dist/builtinModules/BuiltInModule.js.map +1 -1
  12. package/dist/builtinModules/BuiltinApplicationCommandConverters.d.ts +8 -0
  13. package/dist/builtinModules/BuiltinApplicationCommandConverters.js +16 -0
  14. package/dist/builtinModules/BuiltinApplicationCommandConverters.js.map +1 -0
  15. package/dist/builtinModules/BuiltinCommandConverters.js +3 -0
  16. package/dist/builtinModules/BuiltinCommandConverters.js.map +1 -1
  17. package/dist/builtinModules/CommandHandler.d.ts +4 -1
  18. package/dist/builtinModules/CommandHandler.js +144 -17
  19. package/dist/builtinModules/CommandHandler.js.map +1 -1
  20. package/dist/builtinModules/index.d.ts +1 -1
  21. package/dist/builtinModules/index.js +4 -1
  22. package/dist/builtinModules/index.js.map +1 -1
  23. package/dist/command/ArgumentConverter.d.ts +3 -3
  24. package/dist/command/ArgumentConverter.js +6 -3
  25. package/dist/command/ArgumentConverter.js.map +1 -1
  26. package/dist/command/Command.d.ts +2 -2
  27. package/dist/command/Command.js +3 -0
  28. package/dist/command/Command.js.map +1 -1
  29. package/dist/command/cooldown/adapter.js +3 -0
  30. package/dist/command/cooldown/adapter.js.map +1 -1
  31. package/dist/command/cooldown/decorator.js +3 -0
  32. package/dist/command/cooldown/decorator.js.map +1 -1
  33. package/dist/command/cooldown/error.js +3 -0
  34. package/dist/command/cooldown/error.js.map +1 -1
  35. package/dist/command/cooldown/index.js +3 -0
  36. package/dist/command/cooldown/index.js.map +1 -1
  37. package/dist/command/cooldown/type.js +3 -0
  38. package/dist/command/cooldown/type.js.map +1 -1
  39. package/dist/command/decorator.d.ts +2 -1
  40. package/dist/command/decorator.js +9 -5
  41. package/dist/command/decorator.js.map +1 -1
  42. package/dist/command/index.js +3 -0
  43. package/dist/command/index.js.map +1 -1
  44. package/dist/command/utils.d.ts +2 -2
  45. package/dist/command/utils.js +9 -6
  46. package/dist/command/utils.js.map +1 -1
  47. package/dist/constants.d.ts +3 -2
  48. package/dist/constants.js +7 -3
  49. package/dist/constants.js.map +1 -1
  50. package/dist/error/ArgumentConverterNotFound.d.ts +6 -6
  51. package/dist/error/ArgumentConverterNotFound.js +6 -3
  52. package/dist/error/ArgumentConverterNotFound.js.map +1 -1
  53. package/dist/error/ArgumentNotProvided.js +3 -0
  54. package/dist/error/ArgumentNotProvided.js.map +1 -1
  55. package/dist/error/CommandCheckFailed.d.ts +6 -6
  56. package/dist/error/CommandCheckFailed.js +6 -3
  57. package/dist/error/CommandCheckFailed.js.map +1 -1
  58. package/dist/error/CommandNotFound.js +3 -0
  59. package/dist/error/CommandNotFound.js.map +1 -1
  60. package/dist/error/InvalidTargetError.js +3 -0
  61. package/dist/error/InvalidTargetError.js.map +1 -1
  62. package/dist/error/ModuleError.js +3 -0
  63. package/dist/error/ModuleError.js.map +1 -1
  64. package/dist/error/PermissionRequired.js +3 -0
  65. package/dist/error/PermissionRequired.js.map +1 -1
  66. package/dist/error/checks/DMOnlyCommand.js +3 -0
  67. package/dist/error/checks/DMOnlyCommand.js.map +1 -1
  68. package/dist/error/checks/GuildOnlyCommand.js +3 -0
  69. package/dist/error/checks/GuildOnlyCommand.js.map +1 -1
  70. package/dist/error/checks/OwnerOnlyCommand.js +3 -0
  71. package/dist/error/checks/OwnerOnlyCommand.js.map +1 -1
  72. package/dist/error/checks/SlashCommandGlobalCheckError.d.ts +5 -0
  73. package/dist/error/checks/SlashCommandGlobalCheckError.js +14 -0
  74. package/dist/error/checks/SlashCommandGlobalCheckError.js.map +1 -0
  75. package/dist/error/checks/index.js +3 -0
  76. package/dist/error/checks/index.js.map +1 -1
  77. package/dist/error/index.js +3 -0
  78. package/dist/error/index.js.map +1 -1
  79. package/dist/index.d.ts +2 -1
  80. package/dist/index.js +5 -1
  81. package/dist/index.js.map +1 -1
  82. package/dist/interface/index.js +3 -1
  83. package/dist/interface/index.js.map +1 -1
  84. package/dist/listener/Listener.js +3 -0
  85. package/dist/listener/Listener.js.map +1 -1
  86. package/dist/listener/decorator.js +3 -0
  87. package/dist/listener/decorator.js.map +1 -1
  88. package/dist/listener/index.js +3 -0
  89. package/dist/listener/index.js.map +1 -1
  90. package/dist/messageComponents/base.d.ts +10 -0
  91. package/dist/messageComponents/base.js +18 -0
  92. package/dist/messageComponents/base.js.map +1 -0
  93. package/dist/messageComponents/button.d.ts +5 -0
  94. package/dist/messageComponents/button.js +31 -0
  95. package/dist/messageComponents/button.js.map +1 -0
  96. package/dist/messageComponents/index.d.ts +2 -0
  97. package/dist/messageComponents/index.js +18 -0
  98. package/dist/messageComponents/index.js.map +1 -0
  99. package/dist/messageComponents/selectMenu.d.ts +5 -0
  100. package/dist/messageComponents/selectMenu.js +31 -0
  101. package/dist/messageComponents/selectMenu.js.map +1 -0
  102. package/dist/structures/CommandClient.d.ts +7 -3
  103. package/dist/structures/CommandClient.js +10 -8
  104. package/dist/structures/CommandClient.js.map +1 -1
  105. package/dist/structures/Module.d.ts +6 -4
  106. package/dist/structures/Module.js +9 -3
  107. package/dist/structures/Module.js.map +1 -1
  108. package/dist/structures/Registry.d.ts +6 -4
  109. package/dist/structures/Registry.js +21 -15
  110. package/dist/structures/Registry.js.map +1 -1
  111. package/dist/structures/index.js +3 -0
  112. package/dist/structures/index.js.map +1 -1
  113. package/dist/typings.d.ts +14 -2
  114. package/dist/typings.js +3 -0
  115. package/dist/typings.js.map +1 -1
  116. package/dist/utils.js +3 -0
  117. package/dist/utils.js.map +1 -1
  118. package/package.json +1 -3
  119. package/publish-version.js +7 -3
  120. package/src/applicationCommand/AppCommand.ts +32 -0
  121. package/src/{slashCommand → applicationCommand}/decorator.ts +14 -10
  122. package/src/applicationCommand/index.ts +6 -0
  123. package/src/builtinModules/BuiltInModule.ts +4 -0
  124. package/src/builtinModules/BuiltinApplicationCommandConverters.ts +16 -0
  125. package/src/builtinModules/BuiltinCommandConverters.ts +4 -0
  126. package/src/builtinModules/CommandHandler.ts +172 -20
  127. package/src/builtinModules/index.ts +5 -1
  128. package/src/command/ArgumentConverter.ts +7 -3
  129. package/src/command/Command.ts +6 -2
  130. package/src/command/cooldown/adapter.ts +4 -0
  131. package/src/command/cooldown/decorator.ts +4 -0
  132. package/src/command/cooldown/error.ts +4 -0
  133. package/src/command/cooldown/index.ts +4 -0
  134. package/src/command/cooldown/type.ts +4 -0
  135. package/src/command/decorator.ts +10 -5
  136. package/src/command/index.ts +4 -0
  137. package/src/command/utils.ts +13 -9
  138. package/src/constants.ts +8 -2
  139. package/src/error/ArgumentConverterNotFound.ts +8 -4
  140. package/src/error/ArgumentNotProvided.ts +4 -0
  141. package/src/error/CommandCheckFailed.ts +8 -4
  142. package/src/error/CommandNotFound.ts +4 -0
  143. package/src/error/InvalidTargetError.ts +4 -0
  144. package/src/error/ModuleError.ts +4 -0
  145. package/src/error/PermissionRequired.ts +4 -0
  146. package/src/error/checks/DMOnlyCommand.ts +4 -0
  147. package/src/error/checks/GuildOnlyCommand.ts +4 -0
  148. package/src/error/checks/OwnerOnlyCommand.ts +4 -0
  149. package/src/error/checks/SlashCommandGlobalCheckError.ts +11 -0
  150. package/src/error/checks/index.ts +4 -0
  151. package/src/error/index.ts +4 -0
  152. package/src/index.ts +6 -1
  153. package/src/interface/index.ts +4 -0
  154. package/src/listener/Listener.ts +4 -0
  155. package/src/listener/decorator.ts +4 -0
  156. package/src/listener/index.ts +4 -0
  157. package/src/messageComponents/base.ts +16 -0
  158. package/src/messageComponents/button.ts +30 -0
  159. package/src/messageComponents/index.ts +6 -0
  160. package/src/messageComponents/selectMenu.ts +30 -0
  161. package/src/structures/CommandClient.ts +20 -10
  162. package/src/structures/Module.ts +15 -6
  163. package/src/structures/Registry.ts +29 -19
  164. package/src/structures/index.ts +4 -0
  165. package/src/typings.ts +18 -2
  166. package/src/utils.ts +4 -0
  167. package/test/index.ts +6 -2
  168. package/test/modules/dev.ts +13 -5
  169. package/test/modules/test.ts +92 -15
  170. package/dist/builtinModules/BuiltinSlashCommandConverters.d.ts +0 -10
  171. package/dist/builtinModules/BuiltinSlashCommandConverters.js +0 -42
  172. package/dist/builtinModules/BuiltinSlashCommandConverters.js.map +0 -1
  173. package/dist/slashCommand/SlashCommand.d.ts +0 -19
  174. package/dist/slashCommand/SlashCommand.js +0 -22
  175. package/dist/slashCommand/SlashCommand.js.map +0 -1
  176. package/dist/slashCommand/decorator.d.ts +0 -10
  177. package/dist/slashCommand/decorator.js.map +0 -1
  178. package/dist/slashCommand/index.d.ts +0 -2
  179. package/dist/slashCommand/index.js.map +0 -1
  180. package/src/builtinModules/BuiltinSlashCommandConverters.ts +0 -23
  181. package/src/slashCommand/SlashCommand.ts +0 -29
  182. package/src/slashCommand/index.ts +0 -2
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { Module } from '../structures'
6
+ import { ApplicationCommandDataResolvable, Snowflake } from 'discord.js'
7
+ import { KApplicationCommandChecks } from '../constants'
8
+ import { ApplicationCommandCheckFunction } from '../command'
9
+
10
+ export type AppCommandArgument = {
11
+ type: any
12
+ name?: string
13
+ }
14
+
15
+ export class AppCommand {
16
+ get checks(): ApplicationCommandCheckFunction[] {
17
+ return Reflect.getMetadata(KApplicationCommandChecks, this.module, this.key) || []
18
+ }
19
+
20
+ execute(module: Module, args: any[]) {
21
+ return this.run.apply(module, args)
22
+ }
23
+
24
+ constructor(
25
+ public command: ApplicationCommandDataResolvable,
26
+ private run: Function,
27
+ public module: Module,
28
+ public params: AppCommandArgument[],
29
+ public guild: Snowflake | Snowflake[] | undefined,
30
+ private key: string | symbol,
31
+ ) {}
32
+ }
@@ -1,15 +1,19 @@
1
- import { Collection, Snowflake } from 'discord.js'
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { ApplicationCommandDataResolvable, Collection, Snowflake } from 'discord.js'
2
6
  import { checkTarget } from '../utils'
3
- import { KSlashCommandOptions, KSlashCommands } from '../constants'
7
+ import { KSlashCommandOptions, KApplicationCommands } from '../constants'
4
8
  import { Module } from '../structures'
5
- import { SlashCommand } from './SlashCommand'
6
- import { SlashCommandBuilder } from '@discordjs/builders'
9
+ import { AppCommand } from './AppCommand'
7
10
 
8
- type SlashOptions = {
11
+ type ApplicationCommandOptions = {
9
12
  guild: Snowflake | Snowflake[]
13
+ optionTypes?: any[]
10
14
  }
11
15
 
12
- export const slashCommand = (opt: Partial<SlashOptions> & { command: SlashCommandBuilder | Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'> }) => {
16
+ export const applicationCommand = (opt: Partial<ApplicationCommandOptions> & { command: ApplicationCommandDataResolvable }) => {
13
17
  return (
14
18
  target: Object,
15
19
  propertyKey: string,
@@ -17,13 +21,13 @@ export const slashCommand = (opt: Partial<SlashOptions> & { command: SlashComman
17
21
  ) => {
18
22
  checkTarget(target)
19
23
 
20
- let properties: SlashCommand[] = Reflect.getMetadata(KSlashCommands, target)
24
+ let properties: AppCommand[] = Reflect.getMetadata(KApplicationCommands, target)
21
25
 
22
- const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
26
+ const params: any[] = opt.optionTypes ?? Reflect.getMetadata('design:paramtypes', target, propertyKey)
23
27
 
24
28
  const options: Collection<number, string> = Reflect.getMetadata(KSlashCommandOptions, target, propertyKey) || new Collection<number, string>()
25
29
 
26
- const command = new SlashCommand(
30
+ const command = new AppCommand(
27
31
  opt.command,
28
32
  Reflect.get(target, propertyKey),
29
33
  target as Module,
@@ -39,7 +43,7 @@ export const slashCommand = (opt: Partial<SlashOptions> & { command: SlashComman
39
43
  properties.push(command)
40
44
  } else {
41
45
  properties = [command]
42
- Reflect.defineMetadata(KSlashCommands, properties, target)
46
+ Reflect.defineMetadata(KApplicationCommands, properties, target)
43
47
  }
44
48
  }
45
49
  }
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ export * from './decorator'
6
+ export * from './AppCommand'
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Module } from '../structures'
2
6
  import { KBuiltInModule } from '../constants'
3
7
 
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { BuiltInModule } from './BuiltInModule'
6
+ import { Client } from 'discord.js'
7
+ import { CommandClient } from '../structures'
8
+
9
+ export class BuiltinApplicationCommandConverters extends BuiltInModule {
10
+ client: Client
11
+
12
+ constructor(private cts: CommandClient) {
13
+ super()
14
+ this.client = cts.client
15
+ }
16
+ }
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { BuiltInModule } from './BuiltInModule'
2
6
  import { argumentConverter } from '../command'
3
7
  import { Client, GuildMember, Message, User, Role } from 'discord.js'
@@ -1,11 +1,28 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { BuiltInModule } from './BuiltInModule'
2
6
  import { Registry } from '../structures'
3
7
  import { listener } from '../listener'
4
- import { CommandInteraction, GuildMember, Interaction, Message, Role, User } from 'discord.js'
8
+ import {
9
+ CommandInteraction,
10
+ CommandInteractionOptionResolver,
11
+ GuildMember,
12
+ Interaction,
13
+ Message,
14
+ MessageComponentInteraction,
15
+ MessageContextMenuInteraction,
16
+ Role,
17
+ User,
18
+ UserContextMenuInteraction,
19
+ } from 'discord.js'
5
20
  import { CommandClient } from '../structures'
6
21
  import { Command } from '../command'
7
- import { ArgumentConverterNotFound, ArgumentNotProvided, CommandCheckFailed, SlashArgumentConverterNotFound, SlashCommandCheckFailed } from '../error'
22
+ import { ArgumentConverterNotFound, ArgumentNotProvided, CommandCheckFailed, ApplicationCommandArgumentConverterNotFound, ApplicationCommandCheckFailed } from '../error'
8
23
  import { CommandNotFound } from '../error/CommandNotFound'
24
+ import { SlashCommandGlobalCheckError } from '../error/checks/SlashCommandGlobalCheckError'
25
+ import { MessageComponentHandler } from '../messageComponents/base'
9
26
 
10
27
  export class CommandHandler extends BuiltInModule {
11
28
  private readonly client: CommandClient
@@ -15,6 +32,7 @@ export class CommandHandler extends BuiltInModule {
15
32
  this.client = registry.client
16
33
  }
17
34
 
35
+ // region message command handler
18
36
  @listener('messageCreate')
19
37
  async message(msg: Message) {
20
38
  const error = (error: Error) => this.client.client.emit('commandError', error, msg)
@@ -129,36 +147,47 @@ export class CommandHandler extends BuiltInModule {
129
147
  return error(e)
130
148
  }
131
149
  }
150
+ // endregion
132
151
 
152
+ // region slash command handler
133
153
  private async command(i: CommandInteraction) {
134
- const error = (error: Error) => this.client.client.emit('slashCommandError', error, i)
154
+ const error = (error: Error) => this.client.client.emit('applicationCommandError', error, i)
135
155
  try {
136
- const cmd = this.registry.slashCommands.find((x) => x.commandBuilder.name === i.commandName)
156
+ const cmd = this.registry.applicationCommands.find((x) => x.command.type === 'CHAT_INPUT' && x.command.name === i.commandName)
157
+
158
+ if (!cmd) return
137
159
 
138
- const module = this.registry.modules.find((x) => x.slashCommands.includes(cmd!))
160
+ const module = this.registry.modules.find((x) => x.applicationCommands.includes(cmd))
139
161
 
140
162
  if (!module) return
141
163
 
142
164
  const argList: any[] = []
143
165
 
144
- if (!cmd)
145
- return i.reply({
146
- content: 'Unknown command.',
147
- ephemeral: true,
148
- })
149
-
150
166
  i.data = {
151
167
  cts: this.client,
152
168
  command: cmd,
153
169
  }
154
170
 
171
+ if (!(await this.client.options.slashCommands.check(i))) {
172
+ return error(new SlashCommandGlobalCheckError(i))
173
+ }
155
174
  for (const check of cmd.checks) {
156
- if (!(await check(i))) return error(new SlashCommandCheckFailed(i, cmd))
175
+ if (!(await check(i))) return error(new ApplicationCommandCheckFailed(i, cmd))
157
176
  }
158
177
 
159
178
  for (let j = 0; j < cmd.params.length; j++) {
160
179
  const argType = cmd.params[j]
161
- const converter = this.registry.slashArgumentConverters.find((x) => x.type === argType.type)
180
+ const converter = this.registry.applicationCommandArgumentConverters.find((x) => x.type === argType.type)
181
+
182
+ if (argType.type === CommandInteraction) {
183
+ argList.push(i)
184
+ continue
185
+ }
186
+
187
+ if (argType.type === CommandInteractionOptionResolver) {
188
+ argList.push(i.options)
189
+ continue
190
+ }
162
191
 
163
192
  if (argType.name) {
164
193
  switch (argType.type) {
@@ -195,16 +224,119 @@ export class CommandHandler extends BuiltInModule {
195
224
  continue
196
225
  }
197
226
 
198
- if (!converter) return error(new SlashArgumentConverterNotFound(argType, i))
227
+ if (!converter) return error(new ApplicationCommandArgumentConverterNotFound(argType, i))
199
228
 
200
229
  argList.push(await converter.execute(module, i))
201
230
  }
202
231
 
203
- try {
204
- await cmd.execute(module, argList)
205
- } catch (e: any) {
206
- return error(e)
232
+ await cmd.execute(module, argList)
233
+ } catch (e) {
234
+ return error(e)
235
+ }
236
+ }
237
+ // endregion
238
+
239
+ private async messageComponent(i: MessageComponentInteraction) {
240
+ const error = (e: any) => this.client.client.emit('messageComponentError', e)
241
+
242
+ try {
243
+ const handlers: MessageComponentHandler[] = []
244
+
245
+ for (const handler of this.registry.messageComponentHandlers) {
246
+ if (handler.componentId === handler.componentId && handler.componentType === i.componentType) {
247
+ handlers.push(handler)
248
+ }
249
+ }
250
+
251
+ for (const handler of handlers) {
252
+ const module = this.registry.modules.find((x) => x.messageComponentHandlers.includes(handler))
253
+ if (!module) continue
254
+ await handler.run(module, i)
207
255
  }
256
+ } catch (e) {
257
+ error(e)
258
+ }
259
+ }
260
+
261
+ private async userContextMenu(i: UserContextMenuInteraction) {
262
+ const error = (error: Error) => this.client.client.emit('applicationCommandError', error, i)
263
+ try {
264
+ const cmd = this.registry.applicationCommands.find((x) => x.command.type === 'USER' && x.command.name === i.commandName)
265
+
266
+ if (!cmd) return
267
+
268
+ const module = this.registry.modules.find((x) => x.applicationCommands.includes(cmd))
269
+
270
+ if (!module) return
271
+
272
+ i.data = {
273
+ cts: this.client,
274
+ command: cmd,
275
+ }
276
+
277
+ for (const check of cmd.checks) {
278
+ if (!(await check(i))) return error(new ApplicationCommandCheckFailed(i, cmd))
279
+ }
280
+
281
+ let argList: any[] = []
282
+
283
+ for (let j = 0; j < cmd.params.length; j++) {
284
+ const argType = cmd.params[j]
285
+ const converter = this.registry.applicationCommandArgumentConverters.find((x) => x.type === argType.type)
286
+
287
+ if (argType.type === UserContextMenuInteraction) {
288
+ argList.push(i)
289
+ continue
290
+ }
291
+
292
+ if (!converter) return error(new ApplicationCommandArgumentConverterNotFound(argType, i))
293
+
294
+ argList.push(await converter.execute(module, i))
295
+ }
296
+
297
+ await cmd.execute(module, argList)
298
+ } catch (e) {
299
+ return error(e)
300
+ }
301
+ }
302
+
303
+ private async messageContextMenu(i: MessageContextMenuInteraction) {
304
+ const error = (error: Error) => this.client.client.emit('applicationCommandError', error, i)
305
+ try {
306
+ const cmd = this.registry.applicationCommands.find((x) => x.command.type === 'MESSAGE' && x.command.name === i.commandName)
307
+
308
+ if (!cmd) return
309
+
310
+ const module = this.registry.modules.find((x) => x.applicationCommands.includes(cmd))
311
+
312
+ if (!module) return
313
+
314
+ i.data = {
315
+ cts: this.client,
316
+ command: cmd,
317
+ }
318
+
319
+ for (const check of cmd.checks) {
320
+ if (!(await check(i))) return error(new ApplicationCommandCheckFailed(i, cmd))
321
+ }
322
+
323
+ let argList: any[] = []
324
+
325
+ for (let j = 0; j < cmd.params.length; j++) {
326
+ const argType = cmd.params[j]
327
+ const converter = this.registry.applicationCommandArgumentConverters.find((x) => x.type === argType.type)
328
+
329
+ if (argType.type === MessageContextMenuInteraction) {
330
+ argList.push(i)
331
+ continue
332
+ }
333
+
334
+ if (!converter) return error(new ApplicationCommandArgumentConverterNotFound(argType, i))
335
+
336
+ argList.push(await converter.execute(module, i))
337
+ }
338
+
339
+ await cmd.execute(module, argList)
208
340
  } catch (e) {
209
341
  return error(e)
210
342
  }
@@ -212,8 +344,28 @@ export class CommandHandler extends BuiltInModule {
212
344
 
213
345
  @listener('interactionCreate')
214
346
  async interaction(i: Interaction) {
215
- if (i.isCommand()) {
216
- await this.command(i)
347
+ const error = (e: any) => this.client.client.emit('interactionError', e, i)
348
+
349
+ try {
350
+ await this.client.options.applicationCommands.beforeRunCheck(i)
351
+ if (i.isCommand()) {
352
+ await this.command(i)
353
+ return
354
+ }
355
+ if (i.isMessageComponent()) {
356
+ await this.messageComponent(i)
357
+ return
358
+ }
359
+ if (i.isMessageContextMenu()) {
360
+ await this.messageContextMenu(i)
361
+ return
362
+ }
363
+ if (i.isUserContextMenu()) {
364
+ await this.userContextMenu(i)
365
+ return
366
+ }
367
+ } catch (e) {
368
+ return error(e)
217
369
  }
218
370
  }
219
371
  }
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export * from './CommandHandler'
2
6
  export * from './BuiltinCommandConverters'
3
- export * from './BuiltinSlashCommandConverters'
7
+ export * from './BuiltinApplicationCommandConverters'
@@ -1,5 +1,9 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Module } from '../structures'
2
- import { CommandInteraction, Message } from 'discord.js'
6
+ import { CommandInteraction, ContextMenuInteraction, Message } from 'discord.js'
3
7
 
4
8
  export class ArgumentConverter {
5
9
  execute(module: Module, msg: Message, arg?: string) {
@@ -9,8 +13,8 @@ export class ArgumentConverter {
9
13
  constructor(public type: object, private run: Function, public withoutParameter: boolean) {}
10
14
  }
11
15
 
12
- export class SlashArgumentConverter {
13
- execute(module: Module, interaction: CommandInteraction) {
16
+ export class ApplicationCommandArgumentConverter {
17
+ execute(module: Module, interaction: CommandInteraction | ContextMenuInteraction) {
14
18
  return this.run.apply(module, [interaction])
15
19
  }
16
20
 
@@ -1,5 +1,9 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Module } from '../structures'
2
- import { CommandInteraction, Message } from 'discord.js'
6
+ import { CommandInteraction, ContextMenuInteraction, Message, MessageComponentInteraction } from 'discord.js'
3
7
  import { KCommandChecks } from '../constants'
4
8
 
5
9
  export type Argument = {
@@ -9,7 +13,7 @@ export type Argument = {
9
13
  }
10
14
 
11
15
  export type CheckFunction = (msg: Message) => boolean | Promise<boolean>
12
- export type SlashCheckFunction = (i: CommandInteraction) => boolean | Promise<boolean>
16
+ export type ApplicationCommandCheckFunction = (i: CommandInteraction | MessageComponentInteraction | ContextMenuInteraction) => boolean | Promise<boolean>
13
17
 
14
18
  export class Command {
15
19
  execute(module: Module, args: any[]) {
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Collection } from 'discord.js'
2
6
 
3
7
  export interface CoolDownAdapter {
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { createCheckDecorator } from '../utils'
2
6
  import { CoolDownType } from './type'
3
7
  import { DMChannel, GuildMember, TextChannel } from 'discord.js'
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export class CoolDownError extends Error {
2
6
  constructor(public endsAt: Date) {
3
7
  super()
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export * from './decorator'
2
6
  export * from './adapter'
3
7
  export * from './decorator'
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export enum CoolDownType {
2
6
  USER,
3
7
  CHANNEL,
@@ -1,7 +1,11 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { KArgumentConverters, KCommands, KOptionals, KRest, KSlashArgumentConverters } from '../constants'
2
6
  import { Command } from './Command'
3
7
  import { checkTarget } from '../utils'
4
- import { ArgumentConverter, SlashArgumentConverter } from './ArgumentConverter'
8
+ import { ArgumentConverter, ApplicationCommandArgumentConverter } from './ArgumentConverter'
5
9
  import { Module } from '../structures'
6
10
  import { createCheckDecorator } from './utils'
7
11
  import { GuildMember, Message, PermissionResolvable, Permissions, TextChannel } from 'discord.js'
@@ -10,6 +14,7 @@ import { ClientPermissionRequired, DMOnlyCommandError, GuildOnlyCommandError, Ow
10
14
  type CommandOptions = {
11
15
  name: string
12
16
  aliases: string[] | ((msg: Message) => string[])
17
+ optionTypes?: any[]
13
18
  }
14
19
 
15
20
  export const command = (options: Partial<CommandOptions> = {}) => {
@@ -22,7 +27,7 @@ export const command = (options: Partial<CommandOptions> = {}) => {
22
27
 
23
28
  let properties: Command[] = Reflect.getMetadata(KCommands, target)
24
29
 
25
- const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
30
+ const params: any[] = options.optionTypes ?? Reflect.getMetadata('design:paramtypes', target, propertyKey)
26
31
 
27
32
  const optionals: number = Reflect.getMetadata(KOptionals, target, propertyKey) || -1
28
33
 
@@ -71,7 +76,7 @@ export const argumentConverter = (type: object, requireParameter = true) => {
71
76
  }
72
77
  }
73
78
 
74
- export const slashArgumentConverter = (type: object) => {
79
+ export const applicationCommandArgumentConverter = (type: object) => {
75
80
  return (
76
81
  target: Object,
77
82
  propertyKey: string,
@@ -79,9 +84,9 @@ export const slashArgumentConverter = (type: object) => {
79
84
  ) => {
80
85
  checkTarget(target)
81
86
 
82
- let properties: SlashArgumentConverter[] = Reflect.getMetadata(KSlashArgumentConverters, target)
87
+ let properties: ApplicationCommandArgumentConverter[] = Reflect.getMetadata(KSlashArgumentConverters, target)
83
88
 
84
- const converter = new SlashArgumentConverter(type, Reflect.get(target, propertyKey))
89
+ const converter = new ApplicationCommandArgumentConverter(type, Reflect.get(target, propertyKey))
85
90
 
86
91
  if (properties) {
87
92
  properties.push(converter)
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export * from './Command'
2
6
  export * from './decorator'
3
7
  export * from './ArgumentConverter'
@@ -1,10 +1,14 @@
1
- import { CommandInteraction, Message } from 'discord.js'
2
- import type { CheckFunction, SlashCheckFunction } from './Command'
3
- import { KCommandChecks, KSlashCommandChecks } from '../constants'
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { CommandInteraction, ContextMenuInteraction, Message, MessageComponentInteraction } from 'discord.js'
6
+ import type { CheckFunction, ApplicationCommandCheckFunction } from './Command'
7
+ import { KCommandChecks, KApplicationCommandChecks } from '../constants'
4
8
 
5
9
  export const createCheckDecorator = (
6
10
  execute: ((msg: Message) => boolean | Promise<boolean>) | null,
7
- slashExecute?: (i: CommandInteraction) => boolean | Promise<boolean>,
11
+ executeApplicationCommand?: (i: CommandInteraction | MessageComponentInteraction | ContextMenuInteraction) => boolean | Promise<boolean>,
8
12
  ): MethodDecorator => {
9
13
  return (target, propertyKey) => {
10
14
  if (execute) {
@@ -16,13 +20,13 @@ export const createCheckDecorator = (
16
20
  Reflect.defineMetadata(KCommandChecks, properties, target, propertyKey)
17
21
  }
18
22
  }
19
- if (slashExecute) {
20
- let properties: SlashCheckFunction[] = Reflect.getMetadata(KSlashCommandChecks, target, propertyKey)
23
+ if (executeApplicationCommand) {
24
+ let properties: ApplicationCommandCheckFunction[] = Reflect.getMetadata(KApplicationCommandChecks, target, propertyKey)
21
25
  if (properties) {
22
- properties.push(slashExecute)
26
+ properties.push(executeApplicationCommand)
23
27
  } else {
24
- properties = [slashExecute]
25
- Reflect.defineMetadata(KSlashCommandChecks, properties, target, propertyKey)
28
+ properties = [executeApplicationCommand]
29
+ Reflect.defineMetadata(KApplicationCommandChecks, properties, target, propertyKey)
26
30
  }
27
31
  }
28
32
  }
package/src/constants.ts CHANGED
@@ -1,6 +1,10 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export const KCommands = Symbol('Command.TS Commands')
2
6
 
3
- export const KSlashCommands = Symbol('Command.TS Slash Commands')
7
+ export const KApplicationCommands = Symbol('Command.TS Slash Commands')
4
8
 
5
9
  export const KSlashCommandOptions = Symbol('Command.TS Slash Command Options')
6
10
 
@@ -22,4 +26,6 @@ export const KSlashArgumentConverters = Symbol('Command.TS Slash Argument Conver
22
26
 
23
27
  export const KCommandChecks = Symbol('Command.TS Command Checks')
24
28
 
25
- export const KSlashCommandChecks = Symbol('Command.TS Slash Command Checks')
29
+ export const KApplicationCommandChecks = Symbol('Command.TS Slash Command Checks')
30
+
31
+ export const KMessageComponentHandlers = Symbol('Command.TS Message Component Handlers')
@@ -1,14 +1,18 @@
1
- import { CommandInteraction, Message } from 'discord.js'
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { CommandInteraction, ContextMenuInteraction, Message } from 'discord.js'
2
6
  import type { Argument } from '../command'
3
- import type { SlashArgument } from '../slashCommand'
7
+ import type { AppCommandArgument } from '../applicationCommand'
4
8
 
5
9
  export class ArgumentConverterNotFound extends Error {
6
10
  constructor(public type: Argument, public msg: Message) {
7
11
  super(`Argument converter ${type.type.name} not found.`)
8
12
  }
9
13
  }
10
- export class SlashArgumentConverterNotFound extends Error {
11
- constructor(public type: SlashArgument, public interaction: CommandInteraction) {
14
+ export class ApplicationCommandArgumentConverterNotFound extends Error {
15
+ constructor(public type: AppCommandArgument, public interaction: CommandInteraction | ContextMenuInteraction) {
12
16
  super(`Argument converter ${type.type.name} not found.`)
13
17
  }
14
18
  }
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Message } from 'discord.js'
2
6
  import { Command } from '../command'
3
7
 
@@ -1,6 +1,10 @@
1
- import { CommandInteraction, Message } from 'discord.js'
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
5
+ import { CommandInteraction, ContextMenuInteraction, Message, MessageComponentInteraction } from 'discord.js'
2
6
  import { Command } from '../command'
3
- import { SlashCommand } from '../slashCommand'
7
+ import { AppCommand } from '../applicationCommand'
4
8
 
5
9
  export class CommandCheckFailed extends Error {
6
10
  constructor(public msg: Message, public command: Command) {
@@ -8,8 +12,8 @@ export class CommandCheckFailed extends Error {
8
12
  }
9
13
  }
10
14
 
11
- export class SlashCommandCheckFailed extends Error {
12
- constructor(public interaction: CommandInteraction, public command: SlashCommand) {
15
+ export class ApplicationCommandCheckFailed extends Error {
16
+ constructor(public interaction: CommandInteraction | MessageComponentInteraction | ContextMenuInteraction, public command: AppCommand) {
13
17
  super()
14
18
  }
15
19
  }
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  import { Message } from 'discord.js'
2
6
 
3
7
  export class CommandNotFound extends Error {
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  export class InvalidTargetError extends Error {
2
6
  constructor() {
3
7
  super('Class does not extend "Module" class.')