@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.
- package/.prettierrc +2 -1
- package/README.md +2 -2
- package/dist/builtinModules/BuiltinCommandConverters.d.ts +9 -1
- package/dist/builtinModules/BuiltinCommandConverters.js +53 -0
- package/dist/builtinModules/BuiltinSlashCommandConverters.d.ts +9 -0
- package/dist/builtinModules/BuiltinSlashCommandConverters.js +32 -0
- package/dist/builtinModules/CommandHandler.d.ts +4 -2
- package/dist/builtinModules/CommandHandler.js +152 -53
- package/dist/builtinModules/index.d.ts +1 -0
- package/dist/builtinModules/index.js +1 -0
- package/dist/command/ArgumentConverter.d.ts +7 -1
- package/dist/command/ArgumentConverter.js +11 -1
- package/dist/command/Command.d.ts +8 -2
- package/dist/command/Command.js +7 -1
- package/dist/command/cooldown/adapter.d.ts +10 -0
- package/dist/command/cooldown/adapter.js +30 -0
- package/dist/command/cooldown/decorator.d.ts +2 -0
- package/dist/command/cooldown/decorator.js +72 -0
- package/dist/command/cooldown/error.d.ts +4 -0
- package/dist/command/cooldown/error.js +10 -0
- package/dist/command/cooldown/index.d.ts +5 -0
- package/dist/command/cooldown/index.js +17 -0
- package/dist/command/cooldown/type.d.ts +8 -0
- package/dist/command/cooldown/type.js +12 -0
- package/dist/command/decorator.d.ts +9 -1
- package/dist/command/decorator.js +70 -12
- package/dist/command/index.d.ts +2 -0
- package/dist/command/index.js +2 -0
- package/dist/command/utils.d.ts +2 -0
- package/dist/command/utils.js +29 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +7 -1
- package/dist/error/ArgumentConverterNotFound.d.ts +7 -1
- package/dist/error/ArgumentConverterNotFound.js +9 -1
- package/dist/error/ArgumentNotProvided.d.ts +3 -1
- package/dist/error/ArgumentNotProvided.js +2 -1
- package/dist/error/CommandCheckFailed.d.ts +13 -0
- package/dist/error/CommandCheckFailed.js +19 -0
- package/dist/error/PermissionRequired.d.ts +10 -0
- package/dist/error/PermissionRequired.js +18 -0
- package/dist/error/index.d.ts +2 -0
- package/dist/error/index.js +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/slashCommand/SlashCommand.d.ts +19 -0
- package/dist/slashCommand/SlashCommand.js +21 -0
- package/dist/slashCommand/decorator.d.ts +10 -0
- package/dist/slashCommand/decorator.js +37 -0
- package/dist/slashCommand/index.d.ts +2 -0
- package/dist/slashCommand/index.js +14 -0
- package/dist/structures/CommandClient.d.ts +14 -3
- package/dist/structures/CommandClient.js +27 -12
- package/dist/structures/Module.d.ts +5 -1
- package/dist/structures/Module.js +9 -0
- package/dist/structures/Registry.d.ts +16 -6
- package/dist/structures/Registry.js +130 -40
- package/dist/typings.d.ts +18 -0
- package/dist/typings.js +2 -0
- package/package.json +4 -1
- package/src/builtinModules/BuiltinCommandConverters.ts +42 -1
- package/src/builtinModules/BuiltinSlashCommandConverters.ts +18 -0
- package/src/builtinModules/CommandHandler.ts +155 -63
- package/src/builtinModules/index.ts +1 -0
- package/src/command/ArgumentConverter.ts +10 -6
- package/src/command/Command.ts +12 -1
- package/src/command/cooldown/adapter.ts +18 -0
- package/src/command/cooldown/decorator.ts +62 -0
- package/src/command/cooldown/error.ts +5 -0
- package/src/command/cooldown/index.ts +5 -0
- package/src/command/cooldown/type.ts +8 -0
- package/src/command/decorator.ts +102 -36
- package/src/command/index.ts +2 -0
- package/src/command/utils.ts +29 -0
- package/src/constants.ts +12 -0
- package/src/error/ArgumentConverterNotFound.ts +7 -1
- package/src/error/ArgumentNotProvided.ts +2 -1
- package/src/error/CommandCheckFailed.ts +15 -0
- package/src/error/PermissionRequired.ts +13 -0
- package/src/error/index.ts +2 -0
- package/src/index.ts +3 -0
- package/src/slashCommand/SlashCommand.ts +29 -0
- package/src/slashCommand/decorator.ts +58 -0
- package/src/slashCommand/index.ts +2 -0
- package/src/structures/CommandClient.ts +31 -19
- package/src/structures/Module.ts +15 -2
- package/src/structures/Registry.ts +96 -29
- package/src/typings.ts +19 -0
- package/test/index.ts +4 -0
- package/test/modules/test.ts +32 -5
- 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
|
|
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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
+
}
|
package/dist/typings.js
ADDED
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.
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
41
|
+
if (!msg.content.startsWith(prefix)) return
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
const args = msg.content.slice(prefix.length).split(' ')
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
const command = args.shift()
|
|
46
46
|
|
|
47
|
-
|
|
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
|
-
|
|
62
|
+
if (!cmd) return error(new CommandNotFound(command))
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
cmd
|
|
54
|
-
|
|
64
|
+
msg.data = {
|
|
65
|
+
cts: this.client,
|
|
66
|
+
command: cmd,
|
|
67
|
+
prefix: prefix,
|
|
55
68
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
+
const module = this.registry.modules.find((x) => x.slashCommands.includes(cmd!))
|
|
70
127
|
|
|
71
|
-
|
|
128
|
+
if (!module) return
|
|
72
129
|
|
|
73
|
-
|
|
130
|
+
const argList: any[] = []
|
|
74
131
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
132
|
+
if (!cmd)
|
|
133
|
+
return i.reply({
|
|
134
|
+
content: 'Unknown command.',
|
|
135
|
+
ephemeral: true,
|
|
136
|
+
})
|
|
80
137
|
|
|
81
|
-
|
|
138
|
+
i.data = {
|
|
139
|
+
cts: this.client,
|
|
140
|
+
command: cmd,
|
|
141
|
+
}
|
|
82
142
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
continue
|
|
143
|
+
for (const check of cmd.checks) {
|
|
144
|
+
if (!(await check(i))) return error(new SlashCommandCheckFailed(i, cmd))
|
|
86
145
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
92
|
-
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
await cmd.execute(module, argList)
|
|
181
|
+
} catch (e: any) {
|
|
182
|
+
return error(e)
|
|
93
183
|
}
|
|
94
|
-
|
|
184
|
+
} catch (e) {
|
|
185
|
+
return error(e)
|
|
95
186
|
}
|
|
187
|
+
}
|
|
96
188
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
189
|
+
@listener('interactionCreate')
|
|
190
|
+
async interaction(i: Interaction) {
|
|
191
|
+
if (i.isCommand()) {
|
|
192
|
+
await this.command(i)
|
|
101
193
|
}
|
|
102
194
|
}
|
|
103
195
|
}
|
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
}
|