@pikokr/command.ts 3.0.0-dev.a94f324 → 3.0.0-dev.ca01eb5

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 (90) hide show
  1. package/.prettierrc +2 -1
  2. package/README.md +2 -2
  3. package/dist/builtinModules/BuiltinCommandConverters.d.ts +9 -1
  4. package/dist/builtinModules/BuiltinCommandConverters.js +53 -0
  5. package/dist/builtinModules/BuiltinSlashCommandConverters.d.ts +9 -0
  6. package/dist/builtinModules/BuiltinSlashCommandConverters.js +32 -0
  7. package/dist/builtinModules/CommandHandler.d.ts +4 -2
  8. package/dist/builtinModules/CommandHandler.js +152 -53
  9. package/dist/builtinModules/index.d.ts +1 -0
  10. package/dist/builtinModules/index.js +1 -0
  11. package/dist/command/ArgumentConverter.d.ts +7 -1
  12. package/dist/command/ArgumentConverter.js +11 -1
  13. package/dist/command/Command.d.ts +8 -2
  14. package/dist/command/Command.js +7 -1
  15. package/dist/command/cooldown/adapter.d.ts +10 -0
  16. package/dist/command/cooldown/adapter.js +30 -0
  17. package/dist/command/cooldown/decorator.d.ts +2 -0
  18. package/dist/command/cooldown/decorator.js +72 -0
  19. package/dist/command/cooldown/error.d.ts +4 -0
  20. package/dist/command/cooldown/error.js +10 -0
  21. package/dist/command/cooldown/index.d.ts +5 -0
  22. package/dist/command/cooldown/index.js +17 -0
  23. package/dist/command/cooldown/type.d.ts +8 -0
  24. package/dist/command/cooldown/type.js +12 -0
  25. package/dist/command/decorator.d.ts +9 -1
  26. package/dist/command/decorator.js +70 -12
  27. package/dist/command/index.d.ts +2 -0
  28. package/dist/command/index.js +2 -0
  29. package/dist/command/utils.d.ts +2 -0
  30. package/dist/command/utils.js +29 -0
  31. package/dist/constants.d.ts +6 -0
  32. package/dist/constants.js +7 -1
  33. package/dist/error/ArgumentConverterNotFound.d.ts +7 -1
  34. package/dist/error/ArgumentConverterNotFound.js +9 -1
  35. package/dist/error/ArgumentNotProvided.d.ts +3 -1
  36. package/dist/error/ArgumentNotProvided.js +2 -1
  37. package/dist/error/CommandCheckFailed.d.ts +13 -0
  38. package/dist/error/CommandCheckFailed.js +19 -0
  39. package/dist/error/PermissionRequired.d.ts +10 -0
  40. package/dist/error/PermissionRequired.js +18 -0
  41. package/dist/error/index.d.ts +2 -0
  42. package/dist/error/index.js +2 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.js +3 -0
  45. package/dist/slashCommand/SlashCommand.d.ts +19 -0
  46. package/dist/slashCommand/SlashCommand.js +21 -0
  47. package/dist/slashCommand/decorator.d.ts +10 -0
  48. package/dist/slashCommand/decorator.js +37 -0
  49. package/dist/slashCommand/index.d.ts +2 -0
  50. package/dist/slashCommand/index.js +14 -0
  51. package/dist/structures/CommandClient.d.ts +14 -3
  52. package/dist/structures/CommandClient.js +27 -12
  53. package/dist/structures/Module.d.ts +5 -1
  54. package/dist/structures/Module.js +9 -0
  55. package/dist/structures/Registry.d.ts +16 -6
  56. package/dist/structures/Registry.js +130 -40
  57. package/dist/typings.d.ts +18 -0
  58. package/dist/typings.js +2 -0
  59. package/package.json +4 -1
  60. package/src/builtinModules/BuiltinCommandConverters.ts +42 -1
  61. package/src/builtinModules/BuiltinSlashCommandConverters.ts +18 -0
  62. package/src/builtinModules/CommandHandler.ts +155 -63
  63. package/src/builtinModules/index.ts +1 -0
  64. package/src/command/ArgumentConverter.ts +10 -6
  65. package/src/command/Command.ts +12 -1
  66. package/src/command/cooldown/adapter.ts +18 -0
  67. package/src/command/cooldown/decorator.ts +62 -0
  68. package/src/command/cooldown/error.ts +5 -0
  69. package/src/command/cooldown/index.ts +5 -0
  70. package/src/command/cooldown/type.ts +8 -0
  71. package/src/command/decorator.ts +102 -36
  72. package/src/command/index.ts +2 -0
  73. package/src/command/utils.ts +29 -0
  74. package/src/constants.ts +12 -0
  75. package/src/error/ArgumentConverterNotFound.ts +7 -1
  76. package/src/error/ArgumentNotProvided.ts +2 -1
  77. package/src/error/CommandCheckFailed.ts +15 -0
  78. package/src/error/PermissionRequired.ts +13 -0
  79. package/src/error/index.ts +2 -0
  80. package/src/index.ts +3 -0
  81. package/src/slashCommand/SlashCommand.ts +29 -0
  82. package/src/slashCommand/decorator.ts +58 -0
  83. package/src/slashCommand/index.ts +2 -0
  84. package/src/structures/CommandClient.ts +31 -19
  85. package/src/structures/Module.ts +15 -2
  86. package/src/structures/Registry.ts +96 -29
  87. package/src/typings.ts +19 -0
  88. package/test/index.ts +4 -0
  89. package/test/modules/test.ts +32 -5
  90. package/pagesconfig.json +0 -13
@@ -12,6 +12,15 @@ class Module {
12
12
  get argumentConverters() {
13
13
  return Reflect.getMetadata(constants_1.KArgumentConverters, this) || [];
14
14
  }
15
+ get slashArgumentConverters() {
16
+ return Reflect.getMetadata(constants_1.KSlashArgumentConverters, this) || [];
17
+ }
18
+ get slashCommands() {
19
+ return Reflect.getMetadata(constants_1.KSlashCommands, this) || [];
20
+ }
21
+ get path() {
22
+ return Reflect.getMetadata(constants_1.KModulePath, this);
23
+ }
15
24
  load() { }
16
25
  unload() { }
17
26
  beforeReload() { }
@@ -1,17 +1,27 @@
1
1
  import { CommandClient } from './CommandClient';
2
2
  import { Module } from './Module';
3
- import { Command } from '../command';
3
+ import { Command, SlashArgumentConverter } from '../command';
4
4
  import { Collection } from 'discord.js';
5
- import { ArgumentConverter } from '../command/ArgumentConverter';
5
+ import { ArgumentConverter } from '../command';
6
+ import { SlashCommand } from '../slashCommand';
6
7
  export declare class Registry {
7
8
  client: CommandClient;
8
9
  constructor(client: CommandClient);
9
10
  modules: Collection<symbol, Module>;
10
11
  get commands(): Command[];
11
12
  get argumentConverters(): ArgumentConverter[];
13
+ get slashArgumentConverters(): SlashArgumentConverter[];
14
+ get slashCommands(): SlashCommand[];
12
15
  registerModule(module: Module): Module;
13
- loadModulesIn(dir: string, absolute?: boolean): void;
14
- loadModule(file: string, absolute?: boolean): Module;
15
- unregisterModule(module: Module): Module;
16
- unloadModule(module: Module): void;
16
+ loadModulesIn(dir: string, absolute?: boolean): Promise<void>;
17
+ loadModule(file: string, absolute?: boolean): Promise<Module>;
18
+ syncCommands(): Promise<void>;
19
+ unregisterModule(module: Module): Promise<Module>;
20
+ unloadModule(module: Module): Promise<void>;
21
+ reloadModule(module: Module): Promise<boolean>;
22
+ reloadAll(): Promise<{
23
+ path: string;
24
+ success: boolean;
25
+ error?: Error | undefined;
26
+ }[]>;
17
27
  }
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -10,6 +19,7 @@ const path_1 = __importDefault(require("path"));
10
19
  const error_1 = require("../error");
11
20
  const discord_js_1 = require("discord.js");
12
21
  const walk_sync_1 = __importDefault(require("walk-sync"));
22
+ const v9_1 = require("discord-api-types/v9");
13
23
  class Registry {
14
24
  constructor(client) {
15
25
  this.client = client;
@@ -29,6 +39,20 @@ class Registry {
29
39
  }
30
40
  return result;
31
41
  }
42
+ get slashArgumentConverters() {
43
+ const result = [];
44
+ for (const [, module] of this.modules) {
45
+ result.push(...module.slashArgumentConverters);
46
+ }
47
+ return result;
48
+ }
49
+ get slashCommands() {
50
+ const result = [];
51
+ for (const [, module] of this.modules) {
52
+ result.push(...module.slashCommands);
53
+ }
54
+ return result;
55
+ }
32
56
  registerModule(module) {
33
57
  this.modules.set(Symbol(module.constructor.name), module);
34
58
  const list = [];
@@ -41,53 +65,119 @@ class Registry {
41
65
  return module;
42
66
  }
43
67
  loadModulesIn(dir, absolute = false) {
44
- let p = absolute ? dir : path_1.default.join(require.main.path, dir);
45
- for (const i of walk_sync_1.default(p)) {
46
- this.loadModule(path_1.default.join(p, i), true);
47
- }
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ let p = absolute ? dir : path_1.default.join(require.main.path, dir);
70
+ for (const i of walk_sync_1.default(p)) {
71
+ yield this.loadModule(path_1.default.join(p, i), true);
72
+ }
73
+ });
48
74
  }
49
75
  loadModule(file, absolute = false) {
50
- let p = absolute ? file : path_1.default.join(require.main.path, file);
51
- let m;
52
- try {
53
- m = require(p);
54
- }
55
- catch (e) {
56
- throw new error_1.ModuleLoadError(p);
57
- }
58
- if (m.loaded)
59
- throw new Error('MODULE_ALREADY_LOADED');
60
- if (!m.install)
61
- throw new error_1.InvalidModuleError('Install function not found.');
62
- const mod = m.install(this.client);
63
- if (!(mod instanceof Module_1.Module))
64
- throw new error_1.InvalidTargetError();
65
- Reflect.defineMetadata(constants_1.KModulePath, require.resolve(p), mod);
66
- this.registerModule(mod);
67
- mod.load();
68
- m.loaded = true;
69
- return mod;
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ let p = absolute ? file : path_1.default.join(require.main.path, file);
78
+ let m;
79
+ try {
80
+ m = require(p);
81
+ }
82
+ catch (e) {
83
+ throw new error_1.ModuleLoadError(p);
84
+ }
85
+ if (m.loaded)
86
+ throw new Error('MODULE_ALREADY_LOADED');
87
+ if (!m.install)
88
+ throw new error_1.InvalidModuleError('Install function not found.');
89
+ const mod = m.install(this.client);
90
+ if (!(mod instanceof Module_1.Module))
91
+ throw new error_1.InvalidTargetError();
92
+ Reflect.defineMetadata(constants_1.KModulePath, require.resolve(p), mod);
93
+ this.registerModule(mod);
94
+ yield mod.load();
95
+ m.loaded = true;
96
+ return mod;
97
+ });
98
+ }
99
+ syncCommands() {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ const commands = this.slashCommands.filter((x) => !x.guild);
102
+ const guild = this.client.options.slashCommands.guild;
103
+ if (guild) {
104
+ const syncForGuild = (g) => __awaiter(this, void 0, void 0, function* () {
105
+ yield this.client.rest.put(v9_1.Routes.applicationGuildCommands(this.client.client.application.id, g.id), {
106
+ body: commands.map((x) => x.commandBuilder.toJSON()),
107
+ });
108
+ });
109
+ if (typeof guild === 'string') {
110
+ yield syncForGuild(yield this.client.client.guilds.fetch(guild));
111
+ }
112
+ else {
113
+ for (const g of guild) {
114
+ yield syncForGuild(yield this.client.client.guilds.fetch(g));
115
+ }
116
+ }
117
+ }
118
+ else {
119
+ yield this.client.rest.put(v9_1.Routes.applicationCommands(this.client.client.application.id), {
120
+ body: commands.map((x) => x.commandBuilder.toJSON()),
121
+ });
122
+ }
123
+ });
70
124
  }
71
125
  unregisterModule(module) {
72
- if (Reflect.getMetadata(constants_1.KBuiltInModule, module))
73
- throw new Error('Built-in modules cannot be unloaded');
74
- const symbol = this.modules.findKey((x) => x === module);
75
- if (!symbol)
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ if (Reflect.getMetadata(constants_1.KBuiltInModule, module))
128
+ throw new Error('Built-in modules cannot be unloaded');
129
+ const symbol = this.modules.findKey((x) => x === module);
130
+ if (!symbol)
131
+ return module;
132
+ yield module.unload();
133
+ const list = Reflect.getMetadata(constants_1.KListenerExecuteCache, module);
134
+ for (const listener of list) {
135
+ this.client.client.removeListener(listener.event, listener.execute);
136
+ }
137
+ this.modules.delete(symbol);
76
138
  return module;
77
- module.unload();
78
- const list = Reflect.getMetadata(constants_1.KListenerExecuteCache, module);
79
- for (const listener of list) {
80
- this.client.client.removeListener(listener.event, listener.execute);
81
- }
82
- this.modules.delete(symbol);
83
- return module;
139
+ });
84
140
  }
85
141
  unloadModule(module) {
86
- const p = Reflect.getMetadata(constants_1.KModulePath, module);
87
- if (!p)
88
- throw new error_1.InvalidModuleError('This module is not loaded by loadModule.');
89
- this.unregisterModule(module);
90
- delete require.cache[p];
142
+ return __awaiter(this, void 0, void 0, function* () {
143
+ const p = Reflect.getMetadata(constants_1.KModulePath, module);
144
+ if (!p)
145
+ throw new error_1.InvalidModuleError('This module is not loaded by loadModule.');
146
+ yield this.unregisterModule(module);
147
+ delete require.cache[p];
148
+ });
149
+ }
150
+ reloadModule(module) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ yield module.beforeReload();
153
+ const p = Reflect.getMetadata(constants_1.KModulePath, module);
154
+ yield this.unloadModule(module);
155
+ const mod = yield this.loadModule(p, true);
156
+ yield mod.afterReload();
157
+ return true;
158
+ });
159
+ }
160
+ reloadAll() {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ const results = [];
163
+ for (const [, module] of this.modules.filter((x) => !!x.path)) {
164
+ try {
165
+ yield this.reloadModule(module);
166
+ results.push({
167
+ path: module.path,
168
+ success: false,
169
+ });
170
+ }
171
+ catch (e) {
172
+ results.push({
173
+ error: e,
174
+ path: module.path,
175
+ success: false,
176
+ });
177
+ }
178
+ }
179
+ return results;
180
+ });
91
181
  }
92
182
  }
93
183
  exports.Registry = Registry;
@@ -0,0 +1,18 @@
1
+ import type { Command } from './command';
2
+ import { CommandClient } from './structures';
3
+ import { SlashCommand } from './slashCommand';
4
+ declare module 'discord.js' {
5
+ interface Message {
6
+ data: {
7
+ command: Command;
8
+ prefix: string;
9
+ cts: CommandClient;
10
+ };
11
+ }
12
+ interface CommandInteraction {
13
+ data: {
14
+ command: SlashCommand;
15
+ cts: CommandClient;
16
+ };
17
+ }
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@pikokr/command.ts",
3
3
  "description": "Discord.js command framework for typescript.",
4
- "version": "3.0.0-dev.a94f324",
4
+ "version": "3.0.0-dev.ca01eb5",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "MIT",
8
8
  "devDependencies": {
9
+ "@discordjs/builders": "^0.6.0",
10
+ "@discordjs/rest": "^0.1.0-canary.0",
9
11
  "@types/lodash": "^4.14.172",
10
12
  "discord.js": "^13.1.0",
11
13
  "prettier": "^2.2.1",
@@ -14,6 +16,7 @@
14
16
  },
15
17
  "dependencies": {
16
18
  "@types/node": "^14.14.37",
19
+ "discord-api-types": "^0.23.1",
17
20
  "lodash": "^4.17.21",
18
21
  "reflect-metadata": "^0.1.13",
19
22
  "typescript": "^4.2.3",
@@ -1,8 +1,16 @@
1
1
  import { BuiltInModule } from './BuiltInModule'
2
2
  import { argumentConverter } from '../command'
3
- import { Message } from 'discord.js'
3
+ import { Client, GuildMember, Message, User } from 'discord.js'
4
+ import { CommandClient } from '../structures'
4
5
 
5
6
  export class BuiltinCommandConverters extends BuiltInModule {
7
+ client: Client
8
+
9
+ constructor(private cts: CommandClient) {
10
+ super()
11
+ this.client = cts.client
12
+ }
13
+
6
14
  @argumentConverter(Message, false)
7
15
  message(msg: Message) {
8
16
  return msg
@@ -12,4 +20,37 @@ export class BuiltinCommandConverters extends BuiltInModule {
12
20
  string(msg: Message, arg: string) {
13
21
  return arg
14
22
  }
23
+
24
+ getUserIDByMention(mention: string): `${bigint}` | undefined {
25
+ if (!mention) return
26
+ if (mention.startsWith('<@') && mention.endsWith('>')) {
27
+ mention = mention.slice(2, -1)
28
+ if (mention.startsWith('!')) {
29
+ mention = mention.slice(1)
30
+ }
31
+ return mention as `${bigint}`
32
+ }
33
+ }
34
+
35
+ @argumentConverter(User)
36
+ user(value: string): User | null {
37
+ const id = this.getUserIDByMention(value)
38
+ if (!id) return null
39
+ const user = this.client.users.cache.get(id)
40
+ return user || null
41
+ }
42
+
43
+ @argumentConverter(GuildMember)
44
+ member(value: string, msg: Message): GuildMember | undefined {
45
+ const id = this.getUserIDByMention(value)
46
+ if (!id) return
47
+ const user = msg.guild?.members.cache.get(id)
48
+ return user || undefined
49
+ }
50
+
51
+ @argumentConverter(Number)
52
+ number(value: string) {
53
+ const n = Number(value)
54
+ return isNaN(n) ? undefined : n
55
+ }
15
56
  }
@@ -0,0 +1,18 @@
1
+ import { BuiltInModule } from './BuiltInModule'
2
+ import { slashArgumentConverter } from '../command'
3
+ import { Client, CommandInteraction } from 'discord.js'
4
+ import { CommandClient } from '../structures'
5
+
6
+ export class BuiltinSlashCommandConverters extends BuiltInModule {
7
+ client: Client
8
+
9
+ constructor(private cts: CommandClient) {
10
+ super()
11
+ this.client = cts.client
12
+ }
13
+
14
+ @slashArgumentConverter(CommandInteraction)
15
+ message(interaction: CommandInteraction) {
16
+ return interaction
17
+ }
18
+ }
@@ -1,14 +1,14 @@
1
1
  import { BuiltInModule } from './BuiltInModule'
2
2
  import { Registry } from '../structures'
3
3
  import { listener } from '../listener'
4
- import { Message } from 'discord.js'
4
+ import { CommandInteraction, GuildMember, Interaction, Message, Role, User } from 'discord.js'
5
5
  import { CommandClient } from '../structures'
6
6
  import { Command } from '../command'
7
- import { ArgumentConverterNotFound, ArgumentNotProvided } from '../error'
7
+ import { ArgumentConverterNotFound, ArgumentNotProvided, CommandCheckFailed, SlashArgumentConverterNotFound, SlashCommandCheckFailed } from '../error'
8
8
  import { CommandNotFound } from '../error/CommandNotFound'
9
9
 
10
10
  export class CommandHandler extends BuiltInModule {
11
- private client: CommandClient
11
+ private readonly client: CommandClient
12
12
 
13
13
  constructor(private registry: Registry) {
14
14
  super()
@@ -17,87 +17,179 @@ export class CommandHandler extends BuiltInModule {
17
17
 
18
18
  @listener('messageCreate')
19
19
  async message(msg: Message) {
20
- const error = (error: Error) =>
21
- this.client.client.emit('commandError', error, msg)
22
-
23
- const prefixList: string[] | string =
24
- typeof this.client.options.command.prefix === 'string'
25
- ? this.client.options.command.prefix
26
- : typeof this.client.options.command.prefix === 'function'
27
- ? await this.client.options.command.prefix(msg)
28
- : this.client.options.command.prefix
29
- let prefix: string
30
- if (typeof prefixList === 'object') {
31
- const res = prefixList.find((x) => msg.content.includes(x))
32
-
33
- if (!res) return
34
-
35
- prefix = res
36
- } else {
37
- if (!msg.content.includes(prefixList)) return
38
- prefix = prefixList
39
- }
20
+ const error = (error: Error) => this.client.client.emit('commandError', error, msg)
21
+
22
+ try {
23
+ const prefixList: string[] | string =
24
+ typeof this.client.options.command.prefix === 'string'
25
+ ? this.client.options.command.prefix
26
+ : typeof this.client.options.command.prefix === 'function'
27
+ ? await this.client.options.command.prefix(msg)
28
+ : this.client.options.command.prefix
29
+ let prefix: string
30
+ if (typeof prefixList === 'object') {
31
+ const res = prefixList.find((x) => msg.content.includes(x))
32
+
33
+ if (!res) return
34
+
35
+ prefix = res
36
+ } else {
37
+ if (!msg.content.includes(prefixList)) return
38
+ prefix = prefixList
39
+ }
40
40
 
41
- if (!msg.content.startsWith(prefix)) return
41
+ if (!msg.content.startsWith(prefix)) return
42
42
 
43
- const args = msg.content.slice(prefix.length).split(' ')
43
+ const args = msg.content.slice(prefix.length).split(' ')
44
44
 
45
- const command = args.shift()
45
+ const command = args.shift()
46
46
 
47
- if (!command) return
47
+ if (!command) return
48
+
49
+ let cmd: Command | null = null
50
+
51
+ for (const c of this.registry.commands) {
52
+ if (c.name === command) {
53
+ cmd = c
54
+ break
55
+ }
56
+ if ((typeof c.aliases === 'function' ? await c.aliases(msg) : c.aliases).includes(command)) {
57
+ cmd = c
58
+ break
59
+ }
60
+ }
48
61
 
49
- let cmd: Command | null = null
62
+ if (!cmd) return error(new CommandNotFound(command))
50
63
 
51
- for (const c of this.registry.commands) {
52
- if (c.name === command) {
53
- cmd = c
54
- break
64
+ msg.data = {
65
+ cts: this.client,
66
+ command: cmd,
67
+ prefix: prefix,
55
68
  }
56
- if (
57
- (typeof c.aliases === 'function'
58
- ? await c.aliases(msg)
59
- : c.aliases
60
- ).includes(command)
61
- ) {
62
- cmd = c
63
- break
69
+
70
+ const module = this.registry.modules.find((x) => x.commands.includes(cmd!))
71
+
72
+ if (!module) return
73
+
74
+ const argList: any[] = []
75
+
76
+ for (const check of cmd.checks) {
77
+ if (!(await check(msg))) return error(new CommandCheckFailed(msg, cmd))
78
+ }
79
+
80
+ for (let i = 0; i < cmd.argTypes.length; i++) {
81
+ const argType = cmd.argTypes[i]
82
+ const converter = this.registry.argumentConverters.find((x) => x.type === argType.type)
83
+
84
+ if (argType.rest) {
85
+ const i = args.join(' ')
86
+ if (!i) break
87
+ argList.push(i)
88
+ break
89
+ }
90
+
91
+ if (!converter) return error(new ArgumentConverterNotFound(argType, msg))
92
+
93
+ if (converter.withoutParameter) {
94
+ argList.push(await converter.execute(module, msg))
95
+ continue
96
+ }
97
+ const arg = args.shift()
98
+ if (argType.optional && !arg) {
99
+ break
100
+ }
101
+ if (!arg) {
102
+ return error(new ArgumentNotProvided(i, cmd, msg))
103
+ }
104
+ const executed = await converter.execute(module, msg, arg)
105
+ if (!executed === undefined) {
106
+ return error(new ArgumentNotProvided(i, cmd, msg))
107
+ }
108
+ argList.push(executed)
64
109
  }
110
+
111
+ try {
112
+ await cmd.execute(module, argList)
113
+ } catch (e: any) {
114
+ return error(e)
115
+ }
116
+ } catch (e) {
117
+ return error(e)
65
118
  }
119
+ }
66
120
 
67
- if (!cmd) return error(new CommandNotFound(command))
121
+ private async command(i: CommandInteraction) {
122
+ const error = (error: Error) => this.client.client.emit('slashCommandError', error, i)
123
+ try {
124
+ const cmd = this.registry.slashCommands.find((x) => x.commandBuilder.name === i.commandName)
68
125
 
69
- const module = this.registry.modules.find((x) => x.commands.includes(cmd!))
126
+ const module = this.registry.modules.find((x) => x.slashCommands.includes(cmd!))
70
127
 
71
- if (!module) return
128
+ if (!module) return
72
129
 
73
- const argList: any[] = []
130
+ const argList: any[] = []
74
131
 
75
- for (let i = 0; i < cmd.argTypes.length; i++) {
76
- const argType = cmd.argTypes[i]
77
- const converter = this.registry.argumentConverters.find(
78
- (x) => x.type === argType.type,
79
- )
132
+ if (!cmd)
133
+ return i.reply({
134
+ content: 'Unknown command.',
135
+ ephemeral: true,
136
+ })
80
137
 
81
- if (!converter) return error(new ArgumentConverterNotFound(argType, msg))
138
+ i.data = {
139
+ cts: this.client,
140
+ command: cmd,
141
+ }
82
142
 
83
- if (converter.withoutParameter) {
84
- argList.push(await converter.execute(module, msg))
85
- continue
143
+ for (const check of cmd.checks) {
144
+ if (!(await check(i))) return error(new SlashCommandCheckFailed(i, cmd))
86
145
  }
87
- const arg = args.shift()
88
- if (argType.optional && !arg) {
89
- break
146
+
147
+ for (let j = 0; j < cmd.params.length; j++) {
148
+ const argType = cmd.params[j]
149
+ const converter = this.registry.slashArgumentConverters.find((x) => x.type === argType.type)
150
+
151
+ if (argType.name) {
152
+ switch (argType.type) {
153
+ case String:
154
+ argList.push(i.options.getString(argType.name, false) || undefined)
155
+ break
156
+ case Role:
157
+ argList.push(i.options.getRole(argType.name, false) || undefined)
158
+ break
159
+ case User:
160
+ argList.push(i.options.getUser(argType.name, false) || undefined)
161
+ break
162
+ case GuildMember:
163
+ argList.push(i.options.getMember(argType.name, false) || undefined)
164
+ break
165
+ case Boolean:
166
+ argList.push(i.options.getBoolean(argType.name, false) || undefined)
167
+ break
168
+ case Number:
169
+ argList.push(i.options.getNumber(argType.name, false) || i.options.getInteger(argType.name, false) || undefined)
170
+ }
171
+ continue
172
+ }
173
+
174
+ if (!converter) return error(new SlashArgumentConverterNotFound(argType, i))
175
+
176
+ argList.push(await converter.execute(module, i))
90
177
  }
91
- if (!arg) {
92
- return error(new ArgumentNotProvided(i, msg))
178
+
179
+ try {
180
+ await cmd.execute(module, argList)
181
+ } catch (e: any) {
182
+ return error(e)
93
183
  }
94
- argList.push(await converter.execute(module, msg, arg))
184
+ } catch (e) {
185
+ return error(e)
95
186
  }
187
+ }
96
188
 
97
- try {
98
- cmd.execute(module, argList)
99
- } catch (e: any) {
100
- return error(e)
189
+ @listener('interactionCreate')
190
+ async interaction(i: Interaction) {
191
+ if (i.isCommand()) {
192
+ await this.command(i)
101
193
  }
102
194
  }
103
195
  }
@@ -1,2 +1,3 @@
1
1
  export * from './CommandHandler'
2
2
  export * from './BuiltinCommandConverters'
3
+ export * from './BuiltinSlashCommandConverters'
@@ -1,14 +1,18 @@
1
1
  import { Module } from '../structures'
2
- import { Message } from 'discord.js'
2
+ import { CommandInteraction, Message } from 'discord.js'
3
3
 
4
4
  export class ArgumentConverter {
5
5
  execute(module: Module, msg: Message, arg?: string) {
6
6
  return this.run.apply(module, [msg, arg])
7
7
  }
8
8
 
9
- constructor(
10
- public type: object,
11
- private run: Function,
12
- public withoutParameter: boolean,
13
- ) {}
9
+ constructor(public type: object, private run: Function, public withoutParameter: boolean) {}
10
+ }
11
+
12
+ export class SlashArgumentConverter {
13
+ execute(module: Module, interaction: CommandInteraction) {
14
+ return this.run.apply(module, [interaction])
15
+ }
16
+
17
+ constructor(public type: object, private run: Function) {}
14
18
  }