@pikokr/command.ts 3.2.4 → 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 (183) 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.d.ts +1 -1
  16. package/dist/builtinModules/BuiltinCommandConverters.js +3 -0
  17. package/dist/builtinModules/BuiltinCommandConverters.js.map +1 -1
  18. package/dist/builtinModules/CommandHandler.d.ts +4 -1
  19. package/dist/builtinModules/CommandHandler.js +149 -19
  20. package/dist/builtinModules/CommandHandler.js.map +1 -1
  21. package/dist/builtinModules/index.d.ts +1 -1
  22. package/dist/builtinModules/index.js +4 -1
  23. package/dist/builtinModules/index.js.map +1 -1
  24. package/dist/command/ArgumentConverter.d.ts +3 -3
  25. package/dist/command/ArgumentConverter.js +6 -3
  26. package/dist/command/ArgumentConverter.js.map +1 -1
  27. package/dist/command/Command.d.ts +2 -2
  28. package/dist/command/Command.js +3 -0
  29. package/dist/command/Command.js.map +1 -1
  30. package/dist/command/cooldown/adapter.js +3 -0
  31. package/dist/command/cooldown/adapter.js.map +1 -1
  32. package/dist/command/cooldown/decorator.js +3 -0
  33. package/dist/command/cooldown/decorator.js.map +1 -1
  34. package/dist/command/cooldown/error.js +3 -0
  35. package/dist/command/cooldown/error.js.map +1 -1
  36. package/dist/command/cooldown/index.js +3 -0
  37. package/dist/command/cooldown/index.js.map +1 -1
  38. package/dist/command/cooldown/type.js +3 -0
  39. package/dist/command/cooldown/type.js.map +1 -1
  40. package/dist/command/decorator.d.ts +2 -1
  41. package/dist/command/decorator.js +9 -5
  42. package/dist/command/decorator.js.map +1 -1
  43. package/dist/command/index.js +3 -0
  44. package/dist/command/index.js.map +1 -1
  45. package/dist/command/utils.d.ts +2 -2
  46. package/dist/command/utils.js +9 -6
  47. package/dist/command/utils.js.map +1 -1
  48. package/dist/constants.d.ts +3 -2
  49. package/dist/constants.js +7 -3
  50. package/dist/constants.js.map +1 -1
  51. package/dist/error/ArgumentConverterNotFound.d.ts +6 -6
  52. package/dist/error/ArgumentConverterNotFound.js +6 -3
  53. package/dist/error/ArgumentConverterNotFound.js.map +1 -1
  54. package/dist/error/ArgumentNotProvided.js +3 -0
  55. package/dist/error/ArgumentNotProvided.js.map +1 -1
  56. package/dist/error/CommandCheckFailed.d.ts +6 -6
  57. package/dist/error/CommandCheckFailed.js +6 -3
  58. package/dist/error/CommandCheckFailed.js.map +1 -1
  59. package/dist/error/CommandNotFound.js +3 -0
  60. package/dist/error/CommandNotFound.js.map +1 -1
  61. package/dist/error/InvalidTargetError.js +3 -0
  62. package/dist/error/InvalidTargetError.js.map +1 -1
  63. package/dist/error/ModuleError.js +3 -0
  64. package/dist/error/ModuleError.js.map +1 -1
  65. package/dist/error/PermissionRequired.js +3 -0
  66. package/dist/error/PermissionRequired.js.map +1 -1
  67. package/dist/error/checks/DMOnlyCommand.js +3 -0
  68. package/dist/error/checks/DMOnlyCommand.js.map +1 -1
  69. package/dist/error/checks/GuildOnlyCommand.js +3 -0
  70. package/dist/error/checks/GuildOnlyCommand.js.map +1 -1
  71. package/dist/error/checks/OwnerOnlyCommand.js +3 -0
  72. package/dist/error/checks/OwnerOnlyCommand.js.map +1 -1
  73. package/dist/error/checks/SlashCommandGlobalCheckError.d.ts +5 -0
  74. package/dist/error/checks/SlashCommandGlobalCheckError.js +14 -0
  75. package/dist/error/checks/SlashCommandGlobalCheckError.js.map +1 -0
  76. package/dist/error/checks/index.js +3 -0
  77. package/dist/error/checks/index.js.map +1 -1
  78. package/dist/error/index.js +3 -0
  79. package/dist/error/index.js.map +1 -1
  80. package/dist/index.d.ts +2 -1
  81. package/dist/index.js +5 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/interface/index.js +3 -1
  84. package/dist/interface/index.js.map +1 -1
  85. package/dist/listener/Listener.js +3 -0
  86. package/dist/listener/Listener.js.map +1 -1
  87. package/dist/listener/decorator.js +3 -0
  88. package/dist/listener/decorator.js.map +1 -1
  89. package/dist/listener/index.js +3 -0
  90. package/dist/listener/index.js.map +1 -1
  91. package/dist/messageComponents/base.d.ts +10 -0
  92. package/dist/messageComponents/base.js +18 -0
  93. package/dist/messageComponents/base.js.map +1 -0
  94. package/dist/messageComponents/button.d.ts +5 -0
  95. package/dist/messageComponents/button.js +31 -0
  96. package/dist/messageComponents/button.js.map +1 -0
  97. package/dist/messageComponents/index.d.ts +2 -0
  98. package/dist/messageComponents/index.js +18 -0
  99. package/dist/messageComponents/index.js.map +1 -0
  100. package/dist/messageComponents/selectMenu.d.ts +5 -0
  101. package/dist/messageComponents/selectMenu.js +31 -0
  102. package/dist/messageComponents/selectMenu.js.map +1 -0
  103. package/dist/structures/CommandClient.d.ts +8 -3
  104. package/dist/structures/CommandClient.js +11 -8
  105. package/dist/structures/CommandClient.js.map +1 -1
  106. package/dist/structures/Module.d.ts +6 -4
  107. package/dist/structures/Module.js +9 -3
  108. package/dist/structures/Module.js.map +1 -1
  109. package/dist/structures/Registry.d.ts +6 -4
  110. package/dist/structures/Registry.js +21 -15
  111. package/dist/structures/Registry.js.map +1 -1
  112. package/dist/structures/index.js +3 -0
  113. package/dist/structures/index.js.map +1 -1
  114. package/dist/typings.d.ts +14 -2
  115. package/dist/typings.js +3 -0
  116. package/dist/typings.js.map +1 -1
  117. package/dist/utils.js +3 -0
  118. package/dist/utils.js.map +1 -1
  119. package/package.json +3 -5
  120. package/publish-version.js +7 -3
  121. package/src/applicationCommand/AppCommand.ts +32 -0
  122. package/src/{slashCommand → applicationCommand}/decorator.ts +14 -10
  123. package/src/applicationCommand/index.ts +6 -0
  124. package/src/builtinModules/BuiltInModule.ts +4 -0
  125. package/src/builtinModules/BuiltinApplicationCommandConverters.ts +16 -0
  126. package/src/builtinModules/BuiltinCommandConverters.ts +4 -0
  127. package/src/builtinModules/CommandHandler.ts +178 -22
  128. package/src/builtinModules/index.ts +5 -1
  129. package/src/command/ArgumentConverter.ts +7 -3
  130. package/src/command/Command.ts +6 -2
  131. package/src/command/cooldown/adapter.ts +4 -0
  132. package/src/command/cooldown/decorator.ts +4 -0
  133. package/src/command/cooldown/error.ts +4 -0
  134. package/src/command/cooldown/index.ts +4 -0
  135. package/src/command/cooldown/type.ts +4 -0
  136. package/src/command/decorator.ts +10 -5
  137. package/src/command/index.ts +4 -0
  138. package/src/command/utils.ts +13 -9
  139. package/src/constants.ts +8 -2
  140. package/src/error/ArgumentConverterNotFound.ts +8 -4
  141. package/src/error/ArgumentNotProvided.ts +4 -0
  142. package/src/error/CommandCheckFailed.ts +8 -4
  143. package/src/error/CommandNotFound.ts +4 -0
  144. package/src/error/InvalidTargetError.ts +4 -0
  145. package/src/error/ModuleError.ts +4 -0
  146. package/src/error/PermissionRequired.ts +4 -0
  147. package/src/error/checks/DMOnlyCommand.ts +4 -0
  148. package/src/error/checks/GuildOnlyCommand.ts +4 -0
  149. package/src/error/checks/OwnerOnlyCommand.ts +4 -0
  150. package/src/error/checks/SlashCommandGlobalCheckError.ts +11 -0
  151. package/src/error/checks/index.ts +4 -0
  152. package/src/error/index.ts +4 -0
  153. package/src/index.ts +6 -1
  154. package/src/interface/index.ts +4 -0
  155. package/src/listener/Listener.ts +4 -0
  156. package/src/listener/decorator.ts +4 -0
  157. package/src/listener/index.ts +4 -0
  158. package/src/messageComponents/base.ts +16 -0
  159. package/src/messageComponents/button.ts +30 -0
  160. package/src/messageComponents/index.ts +6 -0
  161. package/src/messageComponents/selectMenu.ts +30 -0
  162. package/src/structures/CommandClient.ts +22 -10
  163. package/src/structures/Module.ts +15 -6
  164. package/src/structures/Registry.ts +29 -19
  165. package/src/structures/index.ts +4 -0
  166. package/src/typings.ts +18 -2
  167. package/src/utils.ts +4 -0
  168. package/test/index.ts +6 -2
  169. package/test/modules/dev.ts +13 -5
  170. package/test/modules/test.ts +92 -15
  171. package/dist/builtinModules/BuiltinSlashCommandConverters.d.ts +0 -10
  172. package/dist/builtinModules/BuiltinSlashCommandConverters.js +0 -42
  173. package/dist/builtinModules/BuiltinSlashCommandConverters.js.map +0 -1
  174. package/dist/slashCommand/SlashCommand.d.ts +0 -19
  175. package/dist/slashCommand/SlashCommand.js +0 -22
  176. package/dist/slashCommand/SlashCommand.js.map +0 -1
  177. package/dist/slashCommand/decorator.d.ts +0 -10
  178. package/dist/slashCommand/decorator.js.map +0 -1
  179. package/dist/slashCommand/index.d.ts +0 -2
  180. package/dist/slashCommand/index.js.map +0 -1
  181. package/src/builtinModules/BuiltinSlashCommandConverters.ts +0 -23
  182. package/src/slashCommand/SlashCommand.ts +0 -29
  183. package/src/slashCommand/index.ts +0 -2
@@ -1,9 +1,13 @@
1
+ /*
2
+ * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
+ */
4
+
1
5
  // DO NOT RUN THIS ON DEV ENVIRONMENT
2
6
  // **CI ONLY**
3
7
 
4
- const package = require('./package.json')
8
+ const pkg = require('./package.json')
5
9
  const fs = require('fs')
6
10
 
7
- package.version = package.version + '-dev.' + process.env.COMMIT_ID
11
+ pkg.version = pkg.version + '-dev.' + process.env.COMMIT_ID
8
12
 
9
- fs.writeFileSync('package.json', JSON.stringify(package, null, 2))
13
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 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)
@@ -48,12 +66,16 @@ export class CommandHandler extends BuiltInModule {
48
66
 
49
67
  let cmd: Command | null = null
50
68
 
69
+ const globalAliases = await this.client.options.command.globalAliases(command, msg)
70
+
51
71
  for (const c of this.registry.commands) {
52
- if (c.name === command) {
72
+ const globalAliases2 = await this.client.options.command.globalAliases(c.name, msg)
73
+ const aliases = typeof c.aliases === 'function' ? await c.aliases(msg) : c.aliases
74
+ if ([...aliases, c.name].some((x) => x === command)) {
53
75
  cmd = c
54
76
  break
55
77
  }
56
- if ((typeof c.aliases === 'function' ? await c.aliases(msg) : c.aliases).includes(command)) {
78
+ if (globalAliases.every((x, i) => globalAliases2[i] === x)) {
57
79
  cmd = c
58
80
  break
59
81
  }
@@ -125,36 +147,47 @@ export class CommandHandler extends BuiltInModule {
125
147
  return error(e)
126
148
  }
127
149
  }
150
+ // endregion
128
151
 
152
+ // region slash command handler
129
153
  private async command(i: CommandInteraction) {
130
- const error = (error: Error) => this.client.client.emit('slashCommandError', error, i)
154
+ const error = (error: Error) => this.client.client.emit('applicationCommandError', error, i)
131
155
  try {
132
- 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)
133
157
 
134
- const module = this.registry.modules.find((x) => x.slashCommands.includes(cmd!))
158
+ if (!cmd) return
159
+
160
+ const module = this.registry.modules.find((x) => x.applicationCommands.includes(cmd))
135
161
 
136
162
  if (!module) return
137
163
 
138
164
  const argList: any[] = []
139
165
 
140
- if (!cmd)
141
- return i.reply({
142
- content: 'Unknown command.',
143
- ephemeral: true,
144
- })
145
-
146
166
  i.data = {
147
167
  cts: this.client,
148
168
  command: cmd,
149
169
  }
150
170
 
171
+ if (!(await this.client.options.slashCommands.check(i))) {
172
+ return error(new SlashCommandGlobalCheckError(i))
173
+ }
151
174
  for (const check of cmd.checks) {
152
- if (!(await check(i))) return error(new SlashCommandCheckFailed(i, cmd))
175
+ if (!(await check(i))) return error(new ApplicationCommandCheckFailed(i, cmd))
153
176
  }
154
177
 
155
178
  for (let j = 0; j < cmd.params.length; j++) {
156
179
  const argType = cmd.params[j]
157
- 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
+ }
158
191
 
159
192
  if (argType.name) {
160
193
  switch (argType.type) {
@@ -191,16 +224,119 @@ export class CommandHandler extends BuiltInModule {
191
224
  continue
192
225
  }
193
226
 
194
- if (!converter) return error(new SlashArgumentConverterNotFound(argType, i))
227
+ if (!converter) return error(new ApplicationCommandArgumentConverterNotFound(argType, i))
195
228
 
196
229
  argList.push(await converter.execute(module, i))
197
230
  }
198
231
 
199
- try {
200
- await cmd.execute(module, argList)
201
- } catch (e: any) {
202
- 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)
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))
203
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)
204
340
  } catch (e) {
205
341
  return error(e)
206
342
  }
@@ -208,8 +344,28 @@ export class CommandHandler extends BuiltInModule {
208
344
 
209
345
  @listener('interactionCreate')
210
346
  async interaction(i: Interaction) {
211
- if (i.isCommand()) {
212
- 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)
213
369
  }
214
370
  }
215
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