@pikokr/command.ts 4.0.7 → 5.0.0-dev.645f87d

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 (83) hide show
  1. package/.github/workflows/codeql-analysis.yml +70 -0
  2. package/.github/workflows/docs.yml +1 -1
  3. package/.github/workflows/publish.stable.yml +1 -1
  4. package/.github/workflows/publish.yml +1 -1
  5. package/.vscode/settings.json +10 -0
  6. package/.vscode/templates/ts.lict +5 -0
  7. package/README.md +2 -0
  8. package/dist/index.d.ts +63 -310
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/docs/index.yml +1 -1
  12. package/package.json +14 -11
  13. package/publish-version.js +10 -0
  14. package/scripts/docs.ts +5 -1
  15. package/src/applicationCommand/ApplicationCommand.ts +17 -0
  16. package/src/applicationCommand/ApplicationCommandOption.ts +9 -0
  17. package/src/applicationCommand/index.ts +2 -6
  18. package/src/core/components/BaseComponent.ts +34 -0
  19. package/src/core/components/ComponentArgument.ts +7 -0
  20. package/src/core/components/ComponentArgumentDecorator.ts +17 -0
  21. package/src/core/components/decoratorCreator.ts +67 -0
  22. package/src/core/components/index.ts +3 -0
  23. package/src/core/hooks/index.ts +1 -0
  24. package/src/core/hooks/moduleHook.ts +31 -0
  25. package/src/core/index.ts +3 -0
  26. package/src/core/listener/index.ts +9 -0
  27. package/src/core/structures/CommandClient.ts +14 -0
  28. package/src/core/structures/Registry.ts +86 -0
  29. package/src/core/structures/index.ts +2 -0
  30. package/src/core/symbols.ts +4 -0
  31. package/src/index.ts +6 -12
  32. package/test/index.ts +69 -28
  33. package/tsconfig.json +3 -2
  34. package/tsconfig.prod.json +4 -0
  35. package/tsup.config.ts +6 -1
  36. package/src/applicationCommand/AppCommand.ts +0 -32
  37. package/src/applicationCommand/decorator.ts +0 -62
  38. package/src/builtinModules/BuiltInModule.ts +0 -13
  39. package/src/builtinModules/BuiltinApplicationCommandConverters.ts +0 -16
  40. package/src/builtinModules/BuiltinCommandConverters.ts +0 -87
  41. package/src/builtinModules/CommandHandler.ts +0 -363
  42. package/src/builtinModules/index.ts +0 -7
  43. package/src/command/ArgumentConverter.ts +0 -22
  44. package/src/command/Command.ts +0 -35
  45. package/src/command/cooldown/adapter.ts +0 -22
  46. package/src/command/cooldown/decorator.ts +0 -67
  47. package/src/command/cooldown/error.ts +0 -9
  48. package/src/command/cooldown/index.ts +0 -9
  49. package/src/command/cooldown/type.ts +0 -12
  50. package/src/command/decorator.ts +0 -185
  51. package/src/command/index.ts +0 -9
  52. package/src/command/utils.ts +0 -33
  53. package/src/constants.ts +0 -31
  54. package/src/error/ArgumentConverterNotFound.ts +0 -18
  55. package/src/error/ArgumentNotProvided.ts +0 -12
  56. package/src/error/CommandCheckFailed.ts +0 -19
  57. package/src/error/CommandNotFound.ts +0 -11
  58. package/src/error/InvalidTargetError.ts +0 -9
  59. package/src/error/ModuleError.ts +0 -11
  60. package/src/error/PermissionRequired.ts +0 -17
  61. package/src/error/checks/DMOnlyCommand.ts +0 -9
  62. package/src/error/checks/GuildOnlyCommand.ts +0 -9
  63. package/src/error/checks/OwnerOnlyCommand.ts +0 -9
  64. package/src/error/checks/SlashCommandGlobalCheckError.ts +0 -11
  65. package/src/error/checks/index.ts +0 -8
  66. package/src/error/index.ts +0 -12
  67. package/src/interface/index.ts +0 -7
  68. package/src/listener/Listener.ts +0 -7
  69. package/src/listener/decorator.ts +0 -29
  70. package/src/listener/index.ts +0 -6
  71. package/src/messageComponents/base.ts +0 -16
  72. package/src/messageComponents/button.ts +0 -30
  73. package/src/messageComponents/index.ts +0 -6
  74. package/src/messageComponents/selectMenu.ts +0 -30
  75. package/src/structures/CommandClient.ts +0 -103
  76. package/src/structures/Module.ts +0 -54
  77. package/src/structures/Registry.ts +0 -253
  78. package/src/structures/index.ts +0 -7
  79. package/src/typings.ts +0 -35
  80. package/src/utils.ts +0 -10
  81. package/test/config.example.json +0 -3
  82. package/test/modules/dev.ts +0 -44
  83. package/test/modules/test.ts +0 -148
@@ -1,103 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import _ from 'lodash'
6
- import { Registry } from './Registry'
7
- import { Client, CommandInteraction, Interaction, Message, Snowflake, User } from 'discord.js'
8
- import { BuiltinCommandConverters, BuiltinApplicationCommandConverters, CommandHandler } from '../builtinModules'
9
- import { CoolDownAdapter, DefaultCoolDownAdapter } from '../command'
10
- import { Logger } from 'tslog'
11
-
12
- export interface CommandOptions {
13
- prefix: string | ((msg: any) => string | Promise<string | string[]> | string[]) | string[]
14
- check: (msg: Message) => boolean | Promise<boolean>
15
- }
16
-
17
- export interface SlashCommandOptions {
18
- check: (i: CommandInteraction) => boolean | Promise<boolean>
19
- }
20
-
21
- export interface ApplicationCommandOptions {
22
- guild?: Snowflake | Snowflake[]
23
- autoSync: boolean
24
- beforeRunCheck: (i: Interaction) => void | Promise<void>
25
- }
26
-
27
- export interface CommandClientOptions {
28
- command: CommandOptions
29
- owners: 'auto' | Snowflake[]
30
- slashCommands: SlashCommandOptions
31
- applicationCommands: ApplicationCommandOptions
32
- }
33
-
34
- export interface CommandClientOptionsParam {
35
- command: Partial<CommandOptions>
36
- owners: 'auto' | string[]
37
- slashCommands: Partial<SlashCommandOptions>
38
- applicationCommands: Partial<ApplicationCommandOptions>
39
- }
40
-
41
- export class CommandClient {
42
- options: CommandClientOptions
43
- owners: string[] = []
44
- registry = new Registry(this)
45
- client: Client
46
- coolDownAdapter: CoolDownAdapter
47
- logger: Logger
48
-
49
- private _isReady = false
50
-
51
- private async fetchOwners(): Promise<string[]> {
52
- await this.client.application?.fetch()
53
- const o = this.client.application?.owner
54
- if (!o) return []
55
- if (o instanceof User) return [o.id]
56
- else return o.members.map((x) => x.id)
57
- }
58
-
59
- async ready() {
60
- if (this._isReady) return
61
- this._isReady = true
62
- if (this.options.owners === 'auto') {
63
- const owners = await this.fetchOwners()
64
- this.owners.push(...owners)
65
- }
66
- if (this.options.applicationCommands.autoSync) {
67
- await this.registry.syncCommands()
68
- }
69
- }
70
-
71
- constructor({ client, coolDownAdapter, logger, ...options }: Partial<CommandClientOptionsParam> & { client: Client; coolDownAdapter?: CoolDownAdapter; logger?: Logger }) {
72
- this.client = client
73
- this.coolDownAdapter = coolDownAdapter || new DefaultCoolDownAdapter()
74
- this.options = _.merge<CommandClientOptions, Partial<CommandClientOptionsParam>>(
75
- {
76
- command: {
77
- prefix: '!',
78
- check: () => true,
79
- },
80
- owners: 'auto',
81
- slashCommands: {
82
- check: () => true,
83
- },
84
- applicationCommands: {
85
- autoSync: false,
86
- beforeRunCheck: () => {},
87
- },
88
- },
89
- options,
90
- )
91
-
92
- this.logger = logger ?? new Logger({ name: 'Command.TS' })
93
-
94
- if (this.options.owners !== 'auto') {
95
- this.owners = this.options.owners
96
- }
97
-
98
- this.client.once('ready', () => this.ready())
99
- this.registry.registerModule(new CommandHandler(this.registry))
100
- this.registry.registerModule(new BuiltinCommandConverters(this))
101
- this.registry.registerModule(new BuiltinApplicationCommandConverters(this))
102
- }
103
- }
@@ -1,54 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import { KArgumentConverters, KCommands, KListeners, KMessageComponentHandlers, KModulePath, KSlashArgumentConverters, KApplicationCommands } from '../constants'
6
- import type { Command } from '../command'
7
- import { Listener } from '../listener'
8
- import { ArgumentConverter, ApplicationCommandArgumentConverter } from '../command'
9
- import { AppCommand } from '../applicationCommand'
10
- import { CommandClient } from './CommandClient'
11
- import { MessageComponentHandler } from '../messageComponents/base'
12
-
13
- export abstract class Module {
14
- commandClient!: CommandClient
15
-
16
- get logger() {
17
- return this.commandClient.logger.getChildLogger({
18
- name: this.constructor.name,
19
- })
20
- }
21
-
22
- get commands(): Command[] {
23
- return Reflect.getMetadata(KCommands, this) || []
24
- }
25
-
26
- get listeners(): Listener[] {
27
- return Reflect.getMetadata(KListeners, this) || []
28
- }
29
-
30
- get argumentConverters(): ArgumentConverter[] {
31
- return Reflect.getMetadata(KArgumentConverters, this) || []
32
- }
33
-
34
- get applicationCommandArgumentConverters(): ApplicationCommandArgumentConverter[] {
35
- return Reflect.getMetadata(KSlashArgumentConverters, this) || []
36
- }
37
-
38
- get applicationCommands(): AppCommand[] {
39
- return Reflect.getMetadata(KApplicationCommands, this) || []
40
- }
41
-
42
- get messageComponentHandlers(): MessageComponentHandler[] {
43
- return Reflect.getMetadata(KMessageComponentHandlers, this) || []
44
- }
45
-
46
- get path(): string | undefined {
47
- return Reflect.getMetadata(KModulePath, this)
48
- }
49
-
50
- load() {}
51
- unload() {}
52
- beforeReload() {}
53
- afterReload() {}
54
- }
@@ -1,253 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import { CommandClient } from './CommandClient'
6
- import { Module } from './Module'
7
- import { Command, ApplicationCommandArgumentConverter } from '../command'
8
- import { KBuiltInModule, KListenerExecuteCache, KModulePath } from '../constants'
9
- import path from 'path'
10
- import { InvalidModuleError, InvalidTargetError, ModuleLoadError } from '../error'
11
- import { Collection, Guild } from 'discord.js'
12
- import walkSync from 'walk-sync'
13
- import { ArgumentConverter } from '../command'
14
- import { AppCommand } from '../applicationCommand'
15
- import * as fs from 'fs'
16
- import { MessageComponentHandler } from '../messageComponents/base'
17
-
18
- type ListenerExecutor = {
19
- event: string
20
- execute: any
21
- }
22
-
23
- export class Registry {
24
- constructor(public client: CommandClient) {}
25
-
26
- modules: Collection<symbol, Module> = new Collection()
27
-
28
- private get logger() {
29
- return this.client.logger.getChildLogger({
30
- name: 'Registry',
31
- })
32
- }
33
-
34
- get commands(): Command[] {
35
- const result: Command[] = []
36
-
37
- for (const [, module] of this.modules) {
38
- result.push(...module.commands)
39
- }
40
-
41
- return result
42
- }
43
-
44
- get argumentConverters(): ArgumentConverter[] {
45
- const result: ArgumentConverter[] = []
46
-
47
- for (const [, module] of this.modules) {
48
- result.push(...module.argumentConverters)
49
- }
50
-
51
- return result
52
- }
53
-
54
- get applicationCommandArgumentConverters(): ApplicationCommandArgumentConverter[] {
55
- const result: ApplicationCommandArgumentConverter[] = []
56
-
57
- for (const [, module] of this.modules) {
58
- result.push(...module.applicationCommandArgumentConverters)
59
- }
60
-
61
- return result
62
- }
63
-
64
- get applicationCommands(): AppCommand[] {
65
- const result: AppCommand[] = []
66
-
67
- for (const [, module] of this.modules) {
68
- result.push(...module.applicationCommands)
69
- }
70
-
71
- return result
72
- }
73
-
74
- get messageComponentHandlers(): MessageComponentHandler[] {
75
- const result: MessageComponentHandler[] = []
76
-
77
- for (const [, module] of this.modules) {
78
- result.push(...module.messageComponentHandlers)
79
- }
80
-
81
- return result
82
- }
83
-
84
- registerModule(module: Module) {
85
- module.commandClient = this.client
86
-
87
- this.modules.set(Symbol(module.constructor.name), module)
88
-
89
- const list: ListenerExecutor[] = []
90
-
91
- for (const listener of module.listeners) {
92
- const bound = listener.execute.bind(module)
93
- list.push({ event: listener.name, execute: bound })
94
- this.client.client.on(listener.name, bound)
95
- }
96
-
97
- Reflect.defineMetadata(KListenerExecuteCache, list, module)
98
-
99
- return module
100
- }
101
-
102
- async loadModulesIn(dir: string, absolute = false) {
103
- let p = absolute ? dir : path.join(require.main!.path, dir)
104
-
105
- for (const i of walkSync(p)) {
106
- if (fs.lstatSync(path.join(p, i)).isFile()) {
107
- if (i.endsWith('.map')) continue
108
- await this.loadModule(path.join(p, i), true)
109
- }
110
- }
111
- }
112
-
113
- async loadModule(file: string, absolute: boolean = false) {
114
- let p = absolute ? file : path.join(require.main!.path, file)
115
-
116
- let m
117
-
118
- try {
119
- m = require(p)
120
- } catch (e: any) {
121
- throw new ModuleLoadError(p, e)
122
- }
123
-
124
- if (m.loaded) throw new Error('MODULE_ALREADY_LOADED')
125
-
126
- if (!m.install) throw new InvalidModuleError('Install function not found.')
127
-
128
- const mod = m.install(this.client)
129
-
130
- if (!(mod instanceof Module)) throw new InvalidTargetError()
131
-
132
- Reflect.defineMetadata(KModulePath, require.resolve(p), mod)
133
-
134
- this.registerModule(mod)
135
-
136
- await mod.load()
137
-
138
- m.loaded = true
139
-
140
- return mod
141
- }
142
-
143
- async syncCommands() {
144
- this.logger.debug(`Syncing commands...`)
145
- const commands = this.applicationCommands.filter((x) => !x.guild)
146
- const guild = this.client.options.applicationCommands.guild
147
- const syncForGuild = async (g: Guild, commands: AppCommand[]) => {
148
- this.logger.debug(`Syncing for guild ${g.name}(${g.id})`)
149
- const commandsToRegister = commands.map((x) => x.command)
150
- this.logger.debug(`Command List: ${commandsToRegister.map((x) => x.name).join(', ')}`)
151
- await g.commands.set(commandsToRegister)
152
- }
153
- const commandsWithGuild = this.applicationCommands.filter((x) => !!x.guild)
154
-
155
- if (guild) {
156
- if (typeof guild === 'string') {
157
- await syncForGuild(await this.client.client.guilds.fetch(guild), [
158
- ...commands,
159
- ...commandsWithGuild.filter((x) => x.guild && (typeof x.guild === 'string' ? guild === x.guild : x.guild.includes(guild))),
160
- ])
161
- } else {
162
- for (const g of guild) {
163
- await syncForGuild(await this.client.client.guilds.fetch(g), [
164
- ...commands,
165
- ...commandsWithGuild.filter((x) => x.guild && (typeof x.guild === 'string' ? g === x.guild : x.guild.includes(g))),
166
- ])
167
- }
168
- }
169
- } else {
170
- this.logger.debug('Syncing global...')
171
- await this.client.client.application?.commands.set(commands.map((x) => x.command))
172
- }
173
-
174
- const guilds = new Set<string>()
175
-
176
- for (const command of commandsWithGuild) {
177
- if (!command.guild) continue
178
- if (typeof command.guild === 'string') {
179
- guilds.add(command.guild)
180
- } else {
181
- for (const guild of command.guild) {
182
- guilds.add(guild)
183
- }
184
- }
185
- }
186
-
187
- for (const guild of guilds) {
188
- if (this.client.options.applicationCommands.guild?.includes(guild)) continue
189
- await syncForGuild(
190
- await this.client.client.guilds.fetch(guild),
191
- commandsWithGuild.filter((x) => x.guild && (typeof x.guild === 'string' ? guild === x.guild : x.guild.includes(guild))),
192
- )
193
- }
194
-
195
- this.logger.debug('Syncing ended.')
196
- }
197
-
198
- async unregisterModule(module: Module) {
199
- if (Reflect.getMetadata(KBuiltInModule, module)) throw new Error('Built-in modules cannot be unloaded')
200
- const symbol = this.modules.findKey((x) => x === module)
201
- if (!symbol) return module
202
- await module.unload()
203
- const list: ListenerExecutor[] = Reflect.getMetadata(KListenerExecuteCache, module)
204
- for (const listener of list) {
205
- this.client.client.removeListener(listener.event, listener.execute)
206
- }
207
- this.modules.delete(symbol)
208
- return module
209
- }
210
-
211
- async unloadModule(module: Module) {
212
- const p = Reflect.getMetadata(KModulePath, module)
213
-
214
- if (!p) throw new InvalidModuleError('This module is not loaded by loadModule.')
215
-
216
- await this.unregisterModule(module)
217
- delete require.cache[p]
218
- }
219
-
220
- async reloadModule(module: Module) {
221
- await module.beforeReload()
222
- const p = Reflect.getMetadata(KModulePath, module)
223
- await this.unloadModule(module)
224
- const mod = await this.loadModule(p, true)
225
- await mod.afterReload()
226
- return true
227
- }
228
-
229
- async reloadAll() {
230
- const results: {
231
- path: string
232
- success: boolean
233
- error?: Error
234
- }[] = []
235
-
236
- for (const [, module] of this.modules.filter((x) => !!x.path && !Reflect.getMetadata(KBuiltInModule, x))) {
237
- try {
238
- await this.reloadModule(module)
239
- results.push({
240
- path: module.path!,
241
- success: true,
242
- })
243
- } catch (e: any) {
244
- results.push({
245
- error: e,
246
- path: module.path!,
247
- success: false,
248
- })
249
- }
250
- }
251
- return results
252
- }
253
- }
@@ -1,7 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- export * from './Module'
6
- export * from './CommandClient'
7
- export * from './Registry'
package/src/typings.ts DELETED
@@ -1,35 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import type { Command } from './command'
6
- import { CommandClient } from './structures'
7
- import { AppCommand } from './applicationCommand'
8
-
9
- declare module 'discord.js' {
10
- interface Message {
11
- data: {
12
- command: Command | null
13
- prefix: string
14
- cts: CommandClient
15
- }
16
- }
17
- interface CommandInteraction {
18
- data: {
19
- command: AppCommand
20
- cts: CommandClient
21
- }
22
- }
23
- interface MessageComponentInteraction {
24
- data: {
25
- command: AppCommand
26
- cts: CommandClient
27
- }
28
- }
29
- interface ContextMenuInteraction {
30
- data: {
31
- command: AppCommand
32
- cts: CommandClient
33
- }
34
- }
35
- }
package/src/utils.ts DELETED
@@ -1,10 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import { Module } from './structures'
6
- import { InvalidTargetError } from './error'
7
-
8
- export const checkTarget = (target: Object) => {
9
- if (!(target instanceof Module)) throw new InvalidTargetError()
10
- }
@@ -1,3 +0,0 @@
1
- {
2
- "token": ""
3
- }
@@ -1,44 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import { BuiltInModule, CommandClient, ownerOnly, applicationCommand, listener, ApplicationCommandCheckFailed } from '../../dist'
6
- import { CommandInteraction } from 'discord.js'
7
-
8
- export class Dev extends BuiltInModule {
9
- constructor(private cts: CommandClient) {
10
- super()
11
- }
12
-
13
- @listener('slashCommandError')
14
- slashError(e: Error, i: CommandInteraction) {
15
- if (e instanceof ApplicationCommandCheckFailed) {
16
- return i.reply({
17
- content: 'Command before-run check failed',
18
- ephemeral: true,
19
- })
20
- }
21
- console.error(e.message)
22
- }
23
-
24
- // new SlashCommandBuilder().setName('reload').setDescription('리로드 커맨드')
25
- @applicationCommand({
26
- command: {
27
- name: 'reload',
28
- type: 'CHAT_INPUT',
29
- description: '리로드 커맨드',
30
- },
31
- })
32
- @ownerOnly
33
- async reload(i: CommandInteraction) {
34
- const data = await this.cts.registry.reloadAll()
35
- await i.reply({
36
- ephemeral: true,
37
- content: '```\n' + data.map((x) => (x.success ? `✅ ${x.path}` : `❌ ${x.path}\n${x.error}`)).join('\n') + '```',
38
- })
39
- }
40
- }
41
-
42
- export function install(cts: CommandClient) {
43
- return new Dev(cts)
44
- }
@@ -1,148 +0,0 @@
1
- /*
2
- * Copyright (c) 2022 pikokr. Licensed under the MIT license
3
- */
4
-
5
- import { CommandClient, coolDown, CoolDownError, CoolDownType, listener, messageButton, messageSelectMenu, Module, option, applicationCommand } from '../../dist'
6
- import {
7
- ButtonInteraction,
8
- CommandInteraction,
9
- ContextMenuInteraction,
10
- Message,
11
- MessageActionRow,
12
- MessageButton,
13
- MessageContextMenuInteraction,
14
- MessageSelectMenu,
15
- SelectMenuInteraction,
16
- UserContextMenuInteraction,
17
- } from 'discord.js'
18
-
19
- class Test extends Module {
20
- constructor(private client: CommandClient) {
21
- super()
22
- }
23
-
24
- // region lifetime method
25
- load() {
26
- console.log('load')
27
- }
28
-
29
- unload() {
30
- console.log('unload')
31
- }
32
-
33
- beforeReload() {
34
- console.log('before reload')
35
- }
36
-
37
- afterReload() {
38
- console.log('after reload')
39
- }
40
- // endregion
41
-
42
- @listener('ready')
43
- ready() {
44
- console.log(`Logged in as ${this.client.client.user!.tag}`)
45
- }
46
-
47
- @listener('commandError')
48
- error(err: Error, msg: Message) {
49
- if (err instanceof CoolDownError) {
50
- return msg.reply(`쿨다운: <t:${(err.endsAt.getTime() / 1000).toFixed(0)}:R>`)
51
- }
52
- console.error(err)
53
- }
54
- @listener('applicationCommandError')
55
- slashCommandError(err: Error, msg: CommandInteraction | ContextMenuInteraction) {
56
- if (err instanceof CoolDownError) {
57
- return msg.reply({
58
- content: `쿨다운: <t:${(err.endsAt.getTime() / 1000).toFixed(0)}:R>`,
59
- ephemeral: true,
60
- })
61
- }
62
- console.error(err)
63
- }
64
-
65
- @applicationCommand({
66
- command: {
67
- type: 'CHAT_INPUT',
68
- name: 'test',
69
- description: 'test',
70
- options: [
71
- {
72
- type: 'STRING',
73
- name: 'asdf',
74
- description: 'test',
75
- },
76
- ],
77
- },
78
- })
79
- @coolDown(CoolDownType.USER, 10)
80
- coolDownSlash(i: CommandInteraction, @option('asdf') asdf: string = 'wa sans') {
81
- i.reply({
82
- content: asdf,
83
- components: [
84
- new MessageActionRow().addComponents(new MessageButton().setLabel('test').setCustomId('testButton').setStyle('PRIMARY')),
85
- new MessageActionRow().addComponents(
86
- new MessageSelectMenu()
87
- .setCustomId('testSelectMenu')
88
- .setPlaceholder('test')
89
- .setMinValues(1)
90
- .setOptions(
91
- new Array(10).fill(1).map((_, i) => ({
92
- label: `${i}`,
93
- value: `${i}`,
94
- })),
95
- ),
96
- ),
97
- ],
98
- })
99
- }
100
-
101
- @applicationCommand({
102
- command: {
103
- type: 'MESSAGE',
104
- name: 'contextMenuTest',
105
- defaultPermission: true,
106
- },
107
- })
108
- @coolDown(CoolDownType.USER, 10)
109
- async contextMenuMessage(i: MessageContextMenuInteraction) {
110
- return i.reply({
111
- content: `message id: ${i.targetMessage.id}`,
112
- })
113
- }
114
-
115
- @applicationCommand({
116
- command: {
117
- type: 'USER',
118
- name: 'contextMenuTest',
119
- defaultPermission: true,
120
- },
121
- })
122
- @coolDown(CoolDownType.USER, 10)
123
- async contextMenuUser(i: UserContextMenuInteraction) {
124
- return i.reply({
125
- content: `user id: ${i.targetUser.id}`,
126
- })
127
- }
128
-
129
- @messageButton('testButton')
130
- async testButton(i: ButtonInteraction) {
131
- await i.update({
132
- content: 'test',
133
- components: [],
134
- })
135
- }
136
-
137
- @messageSelectMenu('testSelectMenu')
138
- async testSelectMenu(i: SelectMenuInteraction) {
139
- await i.update({
140
- content: i.values.join(', '),
141
- components: [],
142
- })
143
- }
144
- }
145
-
146
- export function install(client: CommandClient) {
147
- return new Test(client)
148
- }