bakit 1.0.0-beta.13 → 1.0.0-beta.15
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/dist/index.d.ts +69 -32
- package/dist/index.js +595 -976
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,41 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Events
|
|
6
|
-
} from "discord.js";
|
|
7
|
-
|
|
8
|
-
// src/command/CommandRegistry.ts
|
|
9
|
-
import {
|
|
10
|
-
Collection as Collection2,
|
|
11
|
-
SlashCommandBuilder,
|
|
12
|
-
SlashCommandSubcommandBuilder,
|
|
13
|
-
SlashCommandSubcommandGroupBuilder
|
|
14
|
-
} from "discord.js";
|
|
15
|
-
import glob from "tiny-glob";
|
|
16
|
-
import { pathToFileURL } from "url";
|
|
1
|
+
import { Collection, SlashCommandBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandBuilder, ChatInputCommandInteraction, Message, codeBlock, Client, Events } from 'discord.js';
|
|
2
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
|
+
import glob from 'tiny-glob';
|
|
4
|
+
import { pathToFileURL } from 'url';
|
|
17
5
|
|
|
18
|
-
// src/
|
|
19
|
-
import { Collection } from "discord.js";
|
|
6
|
+
// src/BakitClient.ts
|
|
20
7
|
|
|
21
8
|
// src/base/BaseEntry.ts
|
|
22
9
|
var BaseEntry = class {
|
|
23
10
|
target;
|
|
24
11
|
hooks = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
12
|
+
MAIN: void 0,
|
|
13
|
+
ERROR: void 0,
|
|
14
|
+
POST: void 0,
|
|
15
|
+
PRE: void 0
|
|
29
16
|
};
|
|
30
17
|
main;
|
|
31
18
|
pre;
|
|
32
19
|
post;
|
|
33
20
|
error;
|
|
34
21
|
constructor() {
|
|
35
|
-
this.main = this.createMainHookDecorator("MAIN" /* Main */);
|
|
36
|
-
this.pre = this.createMainHookDecorator("PRE" /* Pre */);
|
|
37
|
-
this.post = this.createMainHookDecorator("POST" /* Post */);
|
|
38
|
-
this.error = this.createMainHookDecorator("ERROR" /* Error */);
|
|
22
|
+
this.main = this.createMainHookDecorator("MAIN" /* Main */), this.pre = this.createMainHookDecorator("PRE" /* Pre */), this.post = this.createMainHookDecorator("POST" /* Post */), this.error = this.createMainHookDecorator("ERROR" /* Error */);
|
|
39
23
|
}
|
|
40
24
|
setTarget(target) {
|
|
41
25
|
this.target = target;
|
|
@@ -51,14 +35,12 @@ var BaseEntry = class {
|
|
|
51
35
|
};
|
|
52
36
|
}
|
|
53
37
|
addHook(state, target, descriptor) {
|
|
54
|
-
if (this.target && this.target !== target.constructor)
|
|
38
|
+
if (this.target && this.target !== target.constructor)
|
|
55
39
|
throw new Error("Hook is used at wrong constructor.");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (typeof method !== "function") {
|
|
40
|
+
let { value: method } = descriptor;
|
|
41
|
+
if (typeof method != "function")
|
|
59
42
|
throw new Error("Invalid target method for hook.");
|
|
60
|
-
|
|
61
|
-
const hook = {
|
|
43
|
+
let hook = {
|
|
62
44
|
state,
|
|
63
45
|
method,
|
|
64
46
|
entry: this
|
|
@@ -67,160 +49,216 @@ var BaseEntry = class {
|
|
|
67
49
|
}
|
|
68
50
|
};
|
|
69
51
|
|
|
70
|
-
// src/
|
|
71
|
-
var
|
|
52
|
+
// src/listener/ListenerEntry.ts
|
|
53
|
+
var ListenerEntry = class extends BaseEntry {
|
|
72
54
|
constructor(options) {
|
|
73
55
|
super();
|
|
74
56
|
this.options = options;
|
|
75
57
|
}
|
|
76
58
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return subcommand;
|
|
59
|
+
|
|
60
|
+
// src/listener/Listener.ts
|
|
61
|
+
var ListenerAPI;
|
|
62
|
+
((ListenerAPI2) => {
|
|
63
|
+
let entries = /* @__PURE__ */ new WeakMap();
|
|
64
|
+
function use(entry) {
|
|
65
|
+
return (target) => {
|
|
66
|
+
entries.set(target, entry);
|
|
67
|
+
};
|
|
87
68
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const fullOptions = typeof options === "string" ? { name: options, description: `${options} command` } : { description: `${options.name} command`, ...options };
|
|
92
|
-
if (this.children.has(fullOptions.name)) {
|
|
93
|
-
throw new Error(`Entry "${fullOptions.name}" is already existed.`);
|
|
94
|
-
}
|
|
95
|
-
const group = new CommandGroupEntry(fullOptions, this);
|
|
96
|
-
this.children.set(fullOptions.name, group);
|
|
97
|
-
return group;
|
|
69
|
+
ListenerAPI2.use = use;
|
|
70
|
+
function getEntry(target) {
|
|
71
|
+
return entries.get(target);
|
|
98
72
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
73
|
+
ListenerAPI2.getEntry = getEntry;
|
|
74
|
+
})(ListenerAPI ||= {});
|
|
75
|
+
function ListenerFactory(options) {
|
|
76
|
+
let fullOptions = typeof options != "object" ? { name: options, once: false } : { once: false, ...options };
|
|
77
|
+
return new ListenerEntry(fullOptions);
|
|
78
|
+
}
|
|
79
|
+
var Listener = Object.assign(ListenerFactory, ListenerAPI);
|
|
80
|
+
var StateBox = class _StateBox {
|
|
81
|
+
static storage = new AsyncLocalStorage();
|
|
82
|
+
static getState() {
|
|
83
|
+
let state = this.storage.getStore();
|
|
84
|
+
if (!state)
|
|
85
|
+
throw new Error("No active context, did you forget to wrap it with StateBox.wrap()?");
|
|
86
|
+
return state;
|
|
104
87
|
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
constructor(options, parent) {
|
|
108
|
-
super(options);
|
|
109
|
-
this.parent = parent;
|
|
88
|
+
static run(fn, store2 = {}) {
|
|
89
|
+
return this.storage.run(store2, fn);
|
|
110
90
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return (target) => {
|
|
119
|
-
|
|
120
|
-
|
|
91
|
+
static wrap(fn) {
|
|
92
|
+
let currentStore = this.storage.getStore();
|
|
93
|
+
if (!currentStore)
|
|
94
|
+
throw new Error("No active context, cannot wrap function outside a StateBox.run()");
|
|
95
|
+
return () => this.run(fn, currentStore);
|
|
96
|
+
}
|
|
97
|
+
static use(defaultValue) {
|
|
98
|
+
return (target, key) => {
|
|
99
|
+
let generalKey = key;
|
|
100
|
+
Object.defineProperty(target, key, {
|
|
101
|
+
get() {
|
|
102
|
+
let states = _StateBox.getState();
|
|
103
|
+
return key in states || (states[generalKey] = defaultValue), states[generalKey];
|
|
104
|
+
},
|
|
105
|
+
set(value) {
|
|
106
|
+
let states = _StateBox.getState();
|
|
107
|
+
states[generalKey] = value;
|
|
108
|
+
},
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true
|
|
111
|
+
});
|
|
121
112
|
};
|
|
122
113
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
114
|
+
};
|
|
115
|
+
var ListenerRegistry = class {
|
|
116
|
+
static client;
|
|
117
|
+
static constructors = /* @__PURE__ */ new Set();
|
|
118
|
+
static instances = /* @__PURE__ */ new WeakMap();
|
|
119
|
+
static executors = /* @__PURE__ */ new WeakMap();
|
|
120
|
+
/**
|
|
121
|
+
* Add and register a listener to the registry.
|
|
122
|
+
* If `options.emitter` is not provided, the registry will use the base `client` by default.
|
|
123
|
+
* @param constructor The listener class you want to add.
|
|
124
|
+
*/
|
|
125
|
+
static add(constructor) {
|
|
126
|
+
let entry = Listener.getEntry(constructor);
|
|
127
|
+
if (!entry)
|
|
128
|
+
throw new Error(`No entry found for "${constructor.name}"`);
|
|
129
|
+
let { options } = entry;
|
|
130
|
+
if (!options.emitter) {
|
|
131
|
+
if (!this.client)
|
|
132
|
+
throw new Error("Client is not ready.");
|
|
133
|
+
options.emitter = this.client;
|
|
134
|
+
}
|
|
135
|
+
let instance = new constructor(), executor = this.createExecutor(constructor, instance);
|
|
136
|
+
this.constructors.add(constructor), this.instances.set(constructor, instance), this.executors.set(instance, executor), options.emitter[options.once ? "once" : "on"](options.name, (...args) => {
|
|
137
|
+
executor(...args);
|
|
138
|
+
});
|
|
126
139
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Remove and unregister a listener from the registry.
|
|
142
|
+
* @param constructor The listener class you want to remove.
|
|
143
|
+
* @returns `boolean`, returns `true` if the listener is removed successfully.
|
|
144
|
+
*/
|
|
145
|
+
static remove(constructor) {
|
|
146
|
+
let entry = Listener.getEntry(constructor);
|
|
147
|
+
if (!entry)
|
|
148
|
+
return false;
|
|
149
|
+
this.constructors.delete(constructor);
|
|
150
|
+
let instance = this.instances.get(constructor);
|
|
151
|
+
if (!instance)
|
|
152
|
+
return false;
|
|
153
|
+
this.instances.delete(constructor);
|
|
154
|
+
let executor = this.executors.get(instance);
|
|
155
|
+
if (!executor)
|
|
156
|
+
return false;
|
|
157
|
+
let { name, emitter } = entry.options;
|
|
158
|
+
return emitter?.removeListener(name, executor), this.executors.delete(instance), true;
|
|
132
159
|
}
|
|
133
|
-
|
|
134
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Remove and unregister all listeners from the registry.
|
|
162
|
+
* @returns Amount of removed listeners.
|
|
163
|
+
*/
|
|
164
|
+
static removeAll() {
|
|
165
|
+
let removedAmount = 0;
|
|
166
|
+
for (let constructor of this.constructors)
|
|
167
|
+
this.remove(constructor) && removedAmount++;
|
|
168
|
+
return removedAmount;
|
|
135
169
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Set base client for the registry to fallback as default emitter. This should be used only by BakitClient and stay untouched.
|
|
172
|
+
* @param newClient base client to set for the registry.
|
|
173
|
+
*/
|
|
174
|
+
static setClient(newClient) {
|
|
175
|
+
this.client = newClient;
|
|
176
|
+
}
|
|
177
|
+
static createExecutor(constructor, instance) {
|
|
178
|
+
let entry = Listener.getEntry(constructor);
|
|
179
|
+
if (!entry)
|
|
180
|
+
throw new Error("Missing listener entry");
|
|
181
|
+
let { hooks } = entry, execute = async (...args) => {
|
|
182
|
+
let mainHook = hooks.MAIN, preHook = hooks.PRE, postHook = hooks.POST, errorHook = hooks.ERROR;
|
|
183
|
+
if (mainHook)
|
|
184
|
+
try {
|
|
185
|
+
preHook && await preHook.method.call(instance, ...args), await mainHook.method.call(instance, ...args), postHook && await postHook.method.call(instance, ...args);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
if (errorHook)
|
|
188
|
+
await errorHook.method.call(
|
|
189
|
+
instance,
|
|
190
|
+
error,
|
|
191
|
+
...args
|
|
192
|
+
);
|
|
193
|
+
else
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
return async (...args) => {
|
|
198
|
+
await StateBox.run(() => execute(...args));
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Load and add all listeners which matched provided glob pattern to the registry.
|
|
203
|
+
* @param pattern glob pattern to load.
|
|
204
|
+
* @param parallel load all matched results in parallel, enabled by default.
|
|
205
|
+
* @returns All loaded listener constructors.
|
|
206
|
+
*/
|
|
207
|
+
static async load(pattern, parallel = true) {
|
|
208
|
+
let loaders = (await glob(pattern)).map(async (file) => {
|
|
209
|
+
let fileURL = pathToFileURL(file).toString(), { default: constructor } = await import(fileURL);
|
|
210
|
+
return this.add(constructor), constructor;
|
|
211
|
+
});
|
|
212
|
+
if (parallel)
|
|
213
|
+
return Promise.all(loaders);
|
|
214
|
+
let result = [];
|
|
215
|
+
for (let loader of loaders)
|
|
216
|
+
result.push(await loader);
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
139
220
|
|
|
140
221
|
// src/command/argument/Argument.ts
|
|
141
|
-
var ArgumentType = /* @__PURE__ */ ((ArgumentType2) => {
|
|
142
|
-
ArgumentType2["String"] = "string";
|
|
143
|
-
ArgumentType2["Integer"] = "integer";
|
|
144
|
-
ArgumentType2["Number"] = "number";
|
|
145
|
-
ArgumentType2["User"] = "user";
|
|
146
|
-
ArgumentType2["Member"] = "member";
|
|
147
|
-
return ArgumentType2;
|
|
148
|
-
})(ArgumentType || {});
|
|
222
|
+
var ArgumentType = /* @__PURE__ */ ((ArgumentType2) => (ArgumentType2.String = "string", ArgumentType2.Integer = "integer", ArgumentType2.Number = "number", ArgumentType2.User = "user", ArgumentType2.Member = "member", ArgumentType2.Literal = "literal", ArgumentType2))(ArgumentType || {});
|
|
149
223
|
|
|
150
224
|
// src/command/argument/Arg.ts
|
|
151
225
|
var store = /* @__PURE__ */ new WeakMap();
|
|
152
226
|
function getMethodArguments(method, init = false) {
|
|
153
227
|
let args = store.get(method);
|
|
154
|
-
|
|
155
|
-
args = [];
|
|
156
|
-
if (init) {
|
|
157
|
-
store.set(method, args);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return init ? args : Object.freeze([...args]);
|
|
228
|
+
return args || (args = [], init && store.set(method, args)), init ? args : Object.freeze([...args]);
|
|
161
229
|
}
|
|
162
230
|
function createArgument(type) {
|
|
163
231
|
return function(options) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
if (!("required" in fullOptions)) {
|
|
170
|
-
fullOptions.required = true;
|
|
171
|
-
}
|
|
172
|
-
return function(target, key, _index) {
|
|
173
|
-
const method = Object.getOwnPropertyDescriptor(target, key)?.value;
|
|
174
|
-
if (!method) {
|
|
232
|
+
let fullOptions = { ...typeof options == "string" ? { name: options } : options, type };
|
|
233
|
+
return fullOptions.description || (fullOptions.description = fullOptions.name), "required" in fullOptions || (fullOptions.required = true), function(target, key, _index) {
|
|
234
|
+
let method = Object.getOwnPropertyDescriptor(target, key)?.value;
|
|
235
|
+
if (!method)
|
|
175
236
|
throw new Error("No method found");
|
|
176
|
-
|
|
177
|
-
const args = getMethodArguments(method, true);
|
|
178
|
-
args.unshift(fullOptions);
|
|
237
|
+
getMethodArguments(method, true).unshift(fullOptions);
|
|
179
238
|
};
|
|
180
239
|
};
|
|
181
240
|
}
|
|
182
|
-
var string = createArgument("string" /* String */);
|
|
183
|
-
var integer = createArgument("integer" /* Integer */);
|
|
184
|
-
var number = createArgument("number" /* Number */);
|
|
185
|
-
var user = createArgument("user" /* User */);
|
|
186
|
-
var member = createArgument("member" /* Member */);
|
|
241
|
+
var string = createArgument("string" /* String */), integer = createArgument("integer" /* Integer */), number = createArgument("number" /* Number */), user = createArgument("user" /* User */), member = createArgument("member" /* Member */);
|
|
187
242
|
function describeArgumentExpectation(arg) {
|
|
188
|
-
|
|
243
|
+
let parts = [arg.type];
|
|
189
244
|
switch (arg.type) {
|
|
190
245
|
case "string" /* String */: {
|
|
191
|
-
|
|
192
|
-
parts.push(`\u2265 ${String(arg.minLength)}`);
|
|
193
|
-
}
|
|
194
|
-
if (!arg.minLength && arg.maxLength) {
|
|
195
|
-
parts.push(`\u2264 ${String(arg.maxLength)}`);
|
|
196
|
-
}
|
|
197
|
-
if (arg.minLength && arg.maxLength) {
|
|
198
|
-
parts.push(`${String(arg.minLength)} - ${String(arg.maxLength)}`);
|
|
199
|
-
}
|
|
246
|
+
arg.minLength && !arg.maxLength && parts.push(`\u2265 ${String(arg.minLength)}`), !arg.minLength && arg.maxLength && parts.push(`\u2264 ${String(arg.maxLength)}`), arg.minLength && arg.maxLength && parts.push(`${String(arg.minLength)} - ${String(arg.maxLength)}`);
|
|
200
247
|
break;
|
|
201
248
|
}
|
|
202
249
|
case "number" /* Number */:
|
|
203
250
|
case "integer" /* Integer */: {
|
|
204
|
-
|
|
205
|
-
parts.push(`\u2265 ${String(arg.minValue)}`);
|
|
206
|
-
}
|
|
207
|
-
if (arg.minValue === void 0 && arg.maxValue !== void 0) {
|
|
208
|
-
parts.push(`\u2264 ${String(arg.maxValue)}`);
|
|
209
|
-
}
|
|
210
|
-
if (arg.minValue !== void 0 && arg.maxValue !== void 0) {
|
|
211
|
-
parts.push(`${String(arg.minValue)} - ${String(arg.maxValue)}`);
|
|
212
|
-
}
|
|
251
|
+
arg.minValue !== void 0 && arg.maxValue === void 0 && parts.push(`\u2265 ${String(arg.minValue)}`), arg.minValue === void 0 && arg.maxValue !== void 0 && parts.push(`\u2264 ${String(arg.maxValue)}`), arg.minValue !== void 0 && arg.maxValue !== void 0 && parts.push(`${String(arg.minValue)} - ${String(arg.maxValue)}`);
|
|
213
252
|
break;
|
|
214
253
|
}
|
|
215
254
|
}
|
|
216
255
|
return parts.join(", ");
|
|
217
256
|
}
|
|
218
257
|
function format(arg) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return `${opening}${prefix}${name}: ${describeArgumentExpectation(arg)}${closing}`;
|
|
258
|
+
if (arg.type === "literal" /* Literal */)
|
|
259
|
+
return arg.value;
|
|
260
|
+
let { required, tuple, name } = arg, opening = required ? "<" : "[", closing = required ? ">" : "]";
|
|
261
|
+
return `${opening}${tuple ? "..." : ""}${name}: ${describeArgumentExpectation(arg)}${closing}`;
|
|
224
262
|
}
|
|
225
263
|
var Arg = {
|
|
226
264
|
getMethodArguments,
|
|
@@ -234,457 +272,141 @@ var Arg = {
|
|
|
234
272
|
member
|
|
235
273
|
};
|
|
236
274
|
|
|
237
|
-
// src/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
* @returns All loaded command constructors.
|
|
259
|
-
*/
|
|
260
|
-
static async load(pattern, parallel = true) {
|
|
261
|
-
const files = await glob(pattern);
|
|
262
|
-
const loaders = files.map(async (file) => {
|
|
263
|
-
const fileURL = pathToFileURL(file).toString();
|
|
264
|
-
const { default: constructor } = await import(fileURL);
|
|
265
|
-
_CommandRegistry.add(constructor);
|
|
266
|
-
return constructor;
|
|
267
|
-
});
|
|
268
|
-
if (parallel) {
|
|
269
|
-
return await Promise.all(loaders);
|
|
270
|
-
}
|
|
271
|
-
const result = [];
|
|
272
|
-
for (const loader of loaders) {
|
|
273
|
-
result.push(await loader);
|
|
274
|
-
}
|
|
275
|
-
return result;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Build a command into application command data.
|
|
279
|
-
* @param constructor The command class you want to build.
|
|
280
|
-
* @returns a REST JSON version of the application command data.
|
|
281
|
-
*/
|
|
282
|
-
static buildSlashCommand(constructor) {
|
|
283
|
-
const root = Command.getRoot(constructor);
|
|
284
|
-
if (!root) {
|
|
285
|
-
throw new Error(`No root found for "${constructor.name}"`);
|
|
286
|
-
}
|
|
287
|
-
const { options } = root;
|
|
288
|
-
const builder = new SlashCommandBuilder().setName(options.name).setDescription(options.description).setNSFW(Boolean(options.nsfw));
|
|
289
|
-
const args = this.getMainHookArguments(root);
|
|
290
|
-
if (root.children.size) {
|
|
291
|
-
this.buildSlashCommandSubcommands(builder, root, args);
|
|
292
|
-
} else {
|
|
293
|
-
this.buildSlashCommandOptions(builder, args);
|
|
294
|
-
}
|
|
295
|
-
return builder.toJSON();
|
|
296
|
-
}
|
|
297
|
-
static getMainHookArguments(entry) {
|
|
298
|
-
const { hooks } = entry;
|
|
299
|
-
const mainHook = hooks["MAIN" /* Main */];
|
|
300
|
-
return mainHook ? Arg.getMethodArguments(mainHook.method) : [];
|
|
301
|
-
}
|
|
302
|
-
static buildSlashCommandSubcommands(parent, entry, inheritedArgs) {
|
|
303
|
-
const { children } = entry;
|
|
304
|
-
for (const child of children.values()) {
|
|
305
|
-
if (child instanceof CommandGroupEntry && parent instanceof SlashCommandBuilder) {
|
|
306
|
-
const { options } = child;
|
|
307
|
-
const group = new SlashCommandSubcommandGroupBuilder().setName(options.name).setDescription(options.description);
|
|
308
|
-
this.buildSlashCommandSubcommands(group, child, [
|
|
309
|
-
...inheritedArgs,
|
|
310
|
-
...this.getMainHookArguments(child)
|
|
311
|
-
]);
|
|
312
|
-
parent.addSubcommandGroup(group);
|
|
313
|
-
} else if (child instanceof SubcommandEntry) {
|
|
314
|
-
const { options } = child;
|
|
315
|
-
const subcommand = new SlashCommandSubcommandBuilder().setName(options.name).setDescription(options.description);
|
|
316
|
-
this.buildSlashCommandOptions(subcommand, [
|
|
317
|
-
...inheritedArgs,
|
|
318
|
-
...this.getMainHookArguments(child)
|
|
319
|
-
]);
|
|
320
|
-
parent.addSubcommand(subcommand);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
static buildSlashCommandOptions(builder, args) {
|
|
325
|
-
const argGroup = Object.groupBy(args, ({ required }) => required ? "required" : "optional");
|
|
326
|
-
const orderedArgs = [...argGroup.required || [], ...argGroup.optional || []];
|
|
327
|
-
for (const arg of orderedArgs) {
|
|
328
|
-
this.attachSlashCommandOption(builder, arg);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
static attachSlashCommandOption(builder, arg) {
|
|
332
|
-
const setupOption = (option) => {
|
|
333
|
-
return option.setName(arg.name).setDescription(arg.description || arg.name).setRequired(Boolean(arg.required));
|
|
334
|
-
};
|
|
335
|
-
switch (arg.type) {
|
|
336
|
-
case "string" /* String */: {
|
|
337
|
-
builder.addStringOption((data) => {
|
|
338
|
-
const option = setupOption(data);
|
|
339
|
-
if (arg.maxLength) {
|
|
340
|
-
option.setMaxLength(arg.maxLength);
|
|
341
|
-
}
|
|
342
|
-
if (arg.minLength) {
|
|
343
|
-
option.setMinLength(arg.minLength);
|
|
344
|
-
}
|
|
345
|
-
return option;
|
|
346
|
-
});
|
|
275
|
+
// src/utils/user.ts
|
|
276
|
+
function extractId(value) {
|
|
277
|
+
let idMatch = value.match(/^<@!?(\d+)>$/);
|
|
278
|
+
if (idMatch)
|
|
279
|
+
return idMatch[1];
|
|
280
|
+
let numericMatch = value.match(/^(\d{17,19})$/);
|
|
281
|
+
return numericMatch ? numericMatch[1] : null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/errors/CommandSyntaxError.ts
|
|
285
|
+
var CommandSyntaxErrorType = /* @__PURE__ */ ((CommandSyntaxErrorType2) => (CommandSyntaxErrorType2.MissingRequireArgument = "MISSING_REQUIRE_ARGUMENT", CommandSyntaxErrorType2.InvalidArgument = "INVALID_ARGUMENT", CommandSyntaxErrorType2.InvalidVariadicArgumentValue = "INVALID_VARIADIC_ARGUMENT_VALUE", CommandSyntaxErrorType2))(CommandSyntaxErrorType || {}), CommandSyntaxError = class extends Error {
|
|
286
|
+
arg;
|
|
287
|
+
type;
|
|
288
|
+
expected;
|
|
289
|
+
received;
|
|
290
|
+
constructor(options) {
|
|
291
|
+
let message, { arg, type, received } = options, expected = Arg.describeArgumentExpectation(arg);
|
|
292
|
+
switch (type) {
|
|
293
|
+
case "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */: {
|
|
294
|
+
message = [`Missing required argument "${arg.name}"`, `> Expected: ${expected}`].join(`
|
|
295
|
+
`);
|
|
347
296
|
break;
|
|
348
297
|
}
|
|
349
|
-
case "
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
option.setMinValue(arg.minValue);
|
|
357
|
-
}
|
|
358
|
-
return option;
|
|
359
|
-
});
|
|
298
|
+
case "INVALID_ARGUMENT" /* InvalidArgument */: {
|
|
299
|
+
message = [
|
|
300
|
+
`Invalid value received for argument "${arg.name}"`,
|
|
301
|
+
`> Expected: ${expected}`,
|
|
302
|
+
`> Received: ${String(received)}`
|
|
303
|
+
].join(`
|
|
304
|
+
`);
|
|
360
305
|
break;
|
|
361
306
|
}
|
|
362
|
-
case "
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
option.setMinValue(arg.minValue);
|
|
370
|
-
}
|
|
371
|
-
return option;
|
|
372
|
-
});
|
|
307
|
+
case "INVALID_VARIADIC_ARGUMENT_VALUE" /* InvalidVariadicArgumentValue */: {
|
|
308
|
+
message = [
|
|
309
|
+
`Invalid value received for variadic argument "${arg.name}"`,
|
|
310
|
+
`> Expected: ${expected}`,
|
|
311
|
+
`> Received: ${String(received)}`
|
|
312
|
+
].join(`
|
|
313
|
+
`);
|
|
373
314
|
break;
|
|
374
315
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
builder.addUserOption((option) => setupOption(option));
|
|
316
|
+
default: {
|
|
317
|
+
message = "Unknown error";
|
|
378
318
|
break;
|
|
379
319
|
}
|
|
380
320
|
}
|
|
321
|
+
super(message), this.arg = arg, this.type = type, this.expected = expected, this.received = received, Error.captureStackTrace(this, this.constructor);
|
|
322
|
+
}
|
|
323
|
+
get name() {
|
|
324
|
+
return `CommandSyntaxError[${this.type}]`;
|
|
381
325
|
}
|
|
382
326
|
};
|
|
383
327
|
|
|
384
|
-
// src/command/
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
constructor(source) {
|
|
391
|
-
this.source = source;
|
|
328
|
+
// src/command/argument/ArgumentResolver.ts
|
|
329
|
+
var ArgumentResolver = class _ArgumentResolver {
|
|
330
|
+
constructor(_values, prefix, message) {
|
|
331
|
+
this._values = _values;
|
|
332
|
+
this.prefix = prefix;
|
|
333
|
+
this.message = message;
|
|
392
334
|
}
|
|
393
|
-
|
|
394
|
-
|
|
335
|
+
_parsedValues = [];
|
|
336
|
+
_args = [];
|
|
337
|
+
get commandName() {
|
|
338
|
+
return this._values[0];
|
|
395
339
|
}
|
|
396
|
-
get
|
|
397
|
-
return this.
|
|
340
|
+
get values() {
|
|
341
|
+
return this._values;
|
|
398
342
|
}
|
|
399
|
-
get
|
|
400
|
-
return this.
|
|
343
|
+
get parsedValues() {
|
|
344
|
+
return this._parsedValues;
|
|
401
345
|
}
|
|
402
|
-
get
|
|
403
|
-
return this.
|
|
404
|
-
}
|
|
405
|
-
get guildId() {
|
|
406
|
-
return this.source.guildId;
|
|
407
|
-
}
|
|
408
|
-
inGuild() {
|
|
409
|
-
return Boolean(this.guildId);
|
|
410
|
-
}
|
|
411
|
-
inCachedGuild() {
|
|
412
|
-
if (this.isChatInput()) {
|
|
413
|
-
return this.source.inCachedGuild();
|
|
414
|
-
} else if (this.isMessage()) {
|
|
415
|
-
return this.source.inGuild();
|
|
416
|
-
} else {
|
|
417
|
-
throw new Error("Invalid source");
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
get author() {
|
|
421
|
-
if (this.isChatInput()) {
|
|
422
|
-
return this.source.user;
|
|
423
|
-
} else if (this.isMessage()) {
|
|
424
|
-
return this.source.author;
|
|
425
|
-
} else {
|
|
426
|
-
throw new Error("Invalid source");
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
isChatInput() {
|
|
430
|
-
return this.source instanceof ChatInputCommandInteraction;
|
|
431
|
-
}
|
|
432
|
-
isMessage() {
|
|
433
|
-
return this.source instanceof Message;
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
var ChatInputContext = class extends BaseContext {
|
|
437
|
-
async send(options) {
|
|
438
|
-
if (typeof options === "string") {
|
|
439
|
-
options = { content: options };
|
|
440
|
-
}
|
|
441
|
-
const sendOptions = {
|
|
442
|
-
...options,
|
|
443
|
-
withResponse: true
|
|
444
|
-
};
|
|
445
|
-
if (this.source.deferred || this.source.replied) {
|
|
446
|
-
return await this.source.followUp(sendOptions);
|
|
447
|
-
}
|
|
448
|
-
const response = await this.source.reply(sendOptions);
|
|
449
|
-
return response.resource?.message;
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
var MessageContext = class extends BaseContext {
|
|
453
|
-
async send(options) {
|
|
454
|
-
const { channel } = this;
|
|
455
|
-
if (!channel?.isSendable()) {
|
|
456
|
-
throw new Error("Invalid channel or channel is not sendable");
|
|
457
|
-
}
|
|
458
|
-
return await channel.send(options);
|
|
459
|
-
}
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
// src/utils/user.ts
|
|
463
|
-
function extractId(value) {
|
|
464
|
-
const idMatch = value.match(/^<@!?(\d+)>$/);
|
|
465
|
-
if (idMatch) {
|
|
466
|
-
return idMatch[1];
|
|
467
|
-
}
|
|
468
|
-
const numericMatch = value.match(/^(\d{17,19})$/);
|
|
469
|
-
if (numericMatch) {
|
|
470
|
-
return numericMatch[1];
|
|
471
|
-
}
|
|
472
|
-
return null;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// src/errors/CommandSyntaxError.ts
|
|
476
|
-
var CommandSyntaxErrorType = /* @__PURE__ */ ((CommandSyntaxErrorType2) => {
|
|
477
|
-
CommandSyntaxErrorType2["MissingRequireArgument"] = "MISSING_REQUIRE_ARGUMENT";
|
|
478
|
-
CommandSyntaxErrorType2["InvalidArgument"] = "INVALID_ARGUMENT";
|
|
479
|
-
CommandSyntaxErrorType2["InvalidVariadicArgumentValue"] = "INVALID_VARIADIC_ARGUMENT_VALUE";
|
|
480
|
-
return CommandSyntaxErrorType2;
|
|
481
|
-
})(CommandSyntaxErrorType || {});
|
|
482
|
-
var CommandSyntaxError = class extends Error {
|
|
483
|
-
arg;
|
|
484
|
-
type;
|
|
485
|
-
expected;
|
|
486
|
-
received;
|
|
487
|
-
constructor(options) {
|
|
488
|
-
let message;
|
|
489
|
-
const { arg, type, received } = options;
|
|
490
|
-
const expected = Arg.describeArgumentExpectation(arg);
|
|
491
|
-
switch (type) {
|
|
492
|
-
case "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */: {
|
|
493
|
-
message = [`Missing required argument "${arg.name}"`, `> Expected: ${expected}`].join("\n");
|
|
494
|
-
break;
|
|
495
|
-
}
|
|
496
|
-
case "INVALID_ARGUMENT" /* InvalidArgument */: {
|
|
497
|
-
message = [
|
|
498
|
-
`Invalid value received for argument "${arg.name}"`,
|
|
499
|
-
`> Expected: ${expected}`,
|
|
500
|
-
`> Received: ${String(received)}`
|
|
501
|
-
].join("\n");
|
|
502
|
-
break;
|
|
503
|
-
}
|
|
504
|
-
case "INVALID_VARIADIC_ARGUMENT_VALUE" /* InvalidVariadicArgumentValue */: {
|
|
505
|
-
message = [
|
|
506
|
-
`Invalid value received for variadic argument "${arg.name}"`,
|
|
507
|
-
`> Expected: ${expected}`,
|
|
508
|
-
`> Received: ${String(received)}`
|
|
509
|
-
].join("\n");
|
|
510
|
-
break;
|
|
511
|
-
}
|
|
512
|
-
default: {
|
|
513
|
-
message = "Unknown error";
|
|
514
|
-
break;
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
super(message);
|
|
518
|
-
this.arg = arg;
|
|
519
|
-
this.type = type;
|
|
520
|
-
this.expected = expected;
|
|
521
|
-
this.received = received;
|
|
522
|
-
Error.captureStackTrace(this, this.constructor);
|
|
523
|
-
}
|
|
524
|
-
get name() {
|
|
525
|
-
return `CommandSyntaxError[${this.type}]`;
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
// src/command/argument/ArgumentResolver.ts
|
|
530
|
-
var ArgumentResolver = class _ArgumentResolver {
|
|
531
|
-
constructor(options) {
|
|
532
|
-
this.options = options;
|
|
533
|
-
}
|
|
534
|
-
parsedValues = [];
|
|
535
|
-
/**
|
|
536
|
-
* Get the first value as the command trigger.
|
|
537
|
-
*/
|
|
538
|
-
get trigger() {
|
|
539
|
-
return this.options.values[0];
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Get amount of specified argument values.
|
|
543
|
-
*/
|
|
544
|
-
get specifiedAmount() {
|
|
545
|
-
return this.options.values.length - this.options.startAt;
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* Get parsed raw values from content.
|
|
549
|
-
*/
|
|
550
|
-
get values() {
|
|
551
|
-
return [...this.options.values];
|
|
346
|
+
get args() {
|
|
347
|
+
return this._args;
|
|
552
348
|
}
|
|
553
349
|
get client() {
|
|
554
|
-
return this.
|
|
555
|
-
}
|
|
556
|
-
static
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
const prefixes = [
|
|
560
|
-
// Custom prefixes specified in options
|
|
561
|
-
...client.options.prefixes ?? [],
|
|
562
|
-
// Use bot mention as prefix if enabled
|
|
563
|
-
...enableMentionPrefix ? [client.user.toString()] : []
|
|
564
|
-
];
|
|
565
|
-
const prefix = prefixes.find((p) => message.content.startsWith(p)) ?? null;
|
|
566
|
-
if (!prefix) {
|
|
350
|
+
return this.message.client;
|
|
351
|
+
}
|
|
352
|
+
static async initialize(message) {
|
|
353
|
+
let prefix = (await message.client.dispatchers.command.getPrefixes(message)).find((p) => message.content.startsWith(p));
|
|
354
|
+
if (!prefix)
|
|
567
355
|
return;
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
return new _ArgumentResolver({
|
|
571
|
-
message,
|
|
572
|
-
startAt: 1,
|
|
573
|
-
// Skip the command trigger
|
|
574
|
-
values,
|
|
575
|
-
args: [],
|
|
576
|
-
prefix
|
|
577
|
-
});
|
|
356
|
+
let values = message.content.slice(prefix.length).trim().split(/\s+/);
|
|
357
|
+
return new _ArgumentResolver(values, prefix, message);
|
|
578
358
|
}
|
|
579
|
-
async resolve(
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
args,
|
|
585
|
-
startAt: this.options.startAt
|
|
586
|
-
});
|
|
587
|
-
child.parsedValues = [...this.parsedValues];
|
|
588
|
-
if (!child.options.args.length) {
|
|
589
|
-
return child;
|
|
359
|
+
async resolve(entry, at = 1) {
|
|
360
|
+
let mainHook = entry.hooks.MAIN, args = mainHook ? [...Arg.getMethodArguments(mainHook.method)] : [], nextAt = at;
|
|
361
|
+
if (args.length) {
|
|
362
|
+
let values = this.values.slice(at), parsedValues = args.length >= values.length ? await this.parseExact(args, values) : await this.parseFlexible(args, values);
|
|
363
|
+
nextAt += parsedValues.length, this._args.push(...args), this._parsedValues.push(...parsedValues);
|
|
590
364
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
let
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (arg.tuple) {
|
|
606
|
-
this.parsedValues.push(...await this.resolveTuple(arg, valueIndex, argIndex));
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
609
|
-
const matchedValue = await this.matchValue(arg, value);
|
|
610
|
-
if (matchedValue === null) {
|
|
365
|
+
let nextValue = this._values[nextAt];
|
|
366
|
+
if (!nextValue || !("children" in entry))
|
|
367
|
+
return;
|
|
368
|
+
let childEntry = entry.children.get(nextValue);
|
|
369
|
+
childEntry && (this._args.push({
|
|
370
|
+
type: "literal" /* Literal */,
|
|
371
|
+
value: nextValue
|
|
372
|
+
}), await this.resolve(childEntry, nextAt + 1));
|
|
373
|
+
}
|
|
374
|
+
async parseExact(args, values) {
|
|
375
|
+
let parsedValues = [];
|
|
376
|
+
for (let i = 0; i < args.length; i++) {
|
|
377
|
+
let arg = args[i], value = values[i], matchedValue = await this.matchValue(arg, value);
|
|
378
|
+
if (matchedValue === null)
|
|
611
379
|
throw new CommandSyntaxError({
|
|
612
380
|
arg,
|
|
613
381
|
type: "INVALID_ARGUMENT" /* InvalidArgument */,
|
|
614
382
|
received: value
|
|
615
383
|
});
|
|
616
|
-
|
|
617
|
-
this.parsedValues.push(matchedValue);
|
|
618
|
-
valueIndex++;
|
|
619
|
-
argIndex++;
|
|
384
|
+
parsedValues.push(matchedValue);
|
|
620
385
|
}
|
|
386
|
+
return parsedValues;
|
|
621
387
|
}
|
|
622
|
-
async
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (arg.tuple) {
|
|
630
|
-
this.parsedValues.push(...await this.resolveTuple(arg, valueIndex, argIndex));
|
|
631
|
-
break;
|
|
632
|
-
}
|
|
633
|
-
const matchedValue = await this.matchValue(arg, value);
|
|
634
|
-
if (matchedValue !== null) {
|
|
635
|
-
this.parsedValues.push(matchedValue);
|
|
636
|
-
valueIndex++;
|
|
637
|
-
} else if (arg.required) {
|
|
638
|
-
throw new CommandSyntaxError({
|
|
639
|
-
arg,
|
|
640
|
-
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
641
|
-
received: value
|
|
642
|
-
});
|
|
643
|
-
}
|
|
644
|
-
argIndex++;
|
|
645
|
-
}
|
|
646
|
-
while (argIndex < args.length) {
|
|
647
|
-
const arg = args[argIndex];
|
|
648
|
-
if (arg.required) {
|
|
388
|
+
async parseFlexible(args, values) {
|
|
389
|
+
let argIndex = 0, valueIndex = 0, parsedValues = [];
|
|
390
|
+
for (; argIndex < args.length; ) {
|
|
391
|
+
let arg = args[argIndex], value = values[valueIndex], matchedValue = await this.matchValue(arg, value);
|
|
392
|
+
if (matchedValue !== null)
|
|
393
|
+
parsedValues.push(matchedValue), valueIndex++;
|
|
394
|
+
else if (arg.required)
|
|
649
395
|
throw new CommandSyntaxError({
|
|
650
|
-
arg,
|
|
651
396
|
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
652
|
-
received:
|
|
397
|
+
received: value,
|
|
398
|
+
arg
|
|
653
399
|
});
|
|
654
|
-
}
|
|
655
400
|
argIndex++;
|
|
656
401
|
}
|
|
657
|
-
|
|
658
|
-
async resolveTuple(arg, startIndex, argIndex) {
|
|
659
|
-
const { args } = this.options;
|
|
660
|
-
if (argIndex !== args.length - 1) {
|
|
661
|
-
throw new SyntaxError("Tuple argument must be the last argument");
|
|
662
|
-
}
|
|
663
|
-
const values = [];
|
|
664
|
-
for (const rest of this.values.slice(startIndex)) {
|
|
665
|
-
const matchedValue = await this.matchValue(arg, rest);
|
|
666
|
-
if (matchedValue === null) {
|
|
667
|
-
throw new CommandSyntaxError({
|
|
668
|
-
arg,
|
|
669
|
-
type: "INVALID_VARIADIC_ARGUMENT_VALUE" /* InvalidVariadicArgumentValue */,
|
|
670
|
-
received: rest
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
values.push(matchedValue);
|
|
674
|
-
}
|
|
675
|
-
if (values.length === 0 && arg.required) {
|
|
676
|
-
throw new CommandSyntaxError({
|
|
677
|
-
arg,
|
|
678
|
-
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
679
|
-
received: "nothing"
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
return values;
|
|
402
|
+
return parsedValues;
|
|
683
403
|
}
|
|
684
404
|
async matchValue(arg, value) {
|
|
685
405
|
switch (arg.type) {
|
|
686
406
|
case "user" /* User */:
|
|
687
407
|
return await this.matchUserValue(arg, value);
|
|
408
|
+
case "member" /* Member */:
|
|
409
|
+
return await this.matchMemberValue(arg, value);
|
|
688
410
|
case "integer" /* Integer */:
|
|
689
411
|
return this.matchIntegerValue(arg, value);
|
|
690
412
|
case "number" /* Number */:
|
|
@@ -696,52 +418,29 @@ var ArgumentResolver = class _ArgumentResolver {
|
|
|
696
418
|
}
|
|
697
419
|
}
|
|
698
420
|
async matchUserValue(arg, value) {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
if (!
|
|
705
|
-
return
|
|
706
|
-
}
|
|
707
|
-
|
|
421
|
+
let userId = extractId(value);
|
|
422
|
+
return userId ? await this.client.users.fetch(userId).catch(() => null) : null;
|
|
423
|
+
}
|
|
424
|
+
async matchMemberValue(arg, value) {
|
|
425
|
+
let userId = extractId(value);
|
|
426
|
+
if (!userId)
|
|
427
|
+
return;
|
|
428
|
+
let { guild } = this.message;
|
|
429
|
+
if (guild)
|
|
430
|
+
return await guild.members.fetch(userId).catch(() => null);
|
|
708
431
|
}
|
|
709
432
|
matchIntegerValue(arg, value) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return null;
|
|
713
|
-
}
|
|
714
|
-
if (arg.minValue !== void 0 && intVal < arg.minValue) {
|
|
715
|
-
return null;
|
|
716
|
-
}
|
|
717
|
-
if (arg.maxValue !== void 0 && intVal > arg.maxValue) {
|
|
718
|
-
return null;
|
|
719
|
-
}
|
|
720
|
-
return intVal;
|
|
433
|
+
let intVal = parseInt(value, 10);
|
|
434
|
+
return isNaN(intVal) || arg.minValue !== void 0 && intVal < arg.minValue || arg.maxValue !== void 0 && intVal > arg.maxValue ? null : intVal;
|
|
721
435
|
}
|
|
722
436
|
matchNumberValue(arg, value) {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
return null;
|
|
726
|
-
}
|
|
727
|
-
if (arg.minValue !== void 0 && numVal < arg.minValue) {
|
|
728
|
-
return null;
|
|
729
|
-
}
|
|
730
|
-
if (arg.maxValue !== void 0 && numVal > arg.maxValue) {
|
|
731
|
-
return null;
|
|
732
|
-
}
|
|
733
|
-
return numVal;
|
|
437
|
+
let numVal = parseFloat(value);
|
|
438
|
+
return isNaN(numVal) || arg.minValue !== void 0 && numVal < arg.minValue || arg.maxValue !== void 0 && numVal > arg.maxValue ? null : numVal;
|
|
734
439
|
}
|
|
735
440
|
matchStringValue(arg, value) {
|
|
736
|
-
|
|
737
|
-
return null;
|
|
738
|
-
}
|
|
739
|
-
if (arg.maxLength !== void 0 && value.length > arg.maxLength) {
|
|
740
|
-
return null;
|
|
741
|
-
}
|
|
742
|
-
return value;
|
|
441
|
+
return arg.minLength !== void 0 && value.length < arg.minLength || arg.maxLength !== void 0 && value.length > arg.maxLength ? null : value;
|
|
743
442
|
}
|
|
744
|
-
static
|
|
443
|
+
static resolveChatInputOption(interaction, arg) {
|
|
745
444
|
switch (arg.type) {
|
|
746
445
|
case "string" /* String */:
|
|
747
446
|
return interaction.options.getString(arg.name, arg.required);
|
|
@@ -758,443 +457,363 @@ var ArgumentResolver = class _ArgumentResolver {
|
|
|
758
457
|
}
|
|
759
458
|
}
|
|
760
459
|
};
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
static STATES_KEY = Symbol("states");
|
|
766
|
-
static storage = new AsyncLocalStorage();
|
|
767
|
-
static getState() {
|
|
768
|
-
const state = this.storage.getStore();
|
|
769
|
-
if (!state) {
|
|
770
|
-
throw new Error("No active context, did you forget to wrap it with StateBox.wrap()?");
|
|
771
|
-
}
|
|
772
|
-
return state;
|
|
460
|
+
var BaseCommandEntry = class extends BaseEntry {
|
|
461
|
+
constructor(options) {
|
|
462
|
+
super();
|
|
463
|
+
this.options = options;
|
|
773
464
|
}
|
|
774
|
-
|
|
775
|
-
|
|
465
|
+
}, BaseCommandGroupEntry = class extends BaseCommandEntry {
|
|
466
|
+
children = new Collection();
|
|
467
|
+
subcommand(options) {
|
|
468
|
+
let fullOptions = typeof options == "string" ? { name: options, description: `${options} command` } : { description: `${options.name} command`, ...options };
|
|
469
|
+
if (this.children.has(fullOptions.name))
|
|
470
|
+
throw new Error(`Entry "${fullOptions.name}" is already existed.`);
|
|
471
|
+
let subcommand = new SubcommandEntry(fullOptions, this);
|
|
472
|
+
return this.children.set(fullOptions.name, subcommand), subcommand;
|
|
776
473
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
474
|
+
}, RootCommandEntry = class extends BaseCommandGroupEntry {
|
|
475
|
+
group(options) {
|
|
476
|
+
let fullOptions = typeof options == "string" ? { name: options, description: `${options} command` } : { description: `${options.name} command`, ...options };
|
|
477
|
+
if (this.children.has(fullOptions.name))
|
|
478
|
+
throw new Error(`Entry "${fullOptions.name}" is already existed.`);
|
|
479
|
+
let group = new CommandGroupEntry(fullOptions, this);
|
|
480
|
+
return this.children.set(fullOptions.name, group), group;
|
|
783
481
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
const states = _StateBox.getState();
|
|
789
|
-
if (!(key in states)) {
|
|
790
|
-
states[key] = defaultValue;
|
|
791
|
-
}
|
|
792
|
-
return states[key];
|
|
793
|
-
},
|
|
794
|
-
set(value) {
|
|
795
|
-
const states = _StateBox.getState();
|
|
796
|
-
states[key] = value;
|
|
797
|
-
},
|
|
798
|
-
enumerable: true,
|
|
799
|
-
configurable: true
|
|
800
|
-
});
|
|
801
|
-
};
|
|
482
|
+
}, CommandGroupEntry = class extends BaseCommandGroupEntry {
|
|
483
|
+
constructor(options, parent) {
|
|
484
|
+
super(options);
|
|
485
|
+
this.parent = parent;
|
|
802
486
|
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
constructor(options) {
|
|
808
|
-
super();
|
|
809
|
-
this.options = options;
|
|
487
|
+
}, SubcommandEntry = class extends BaseCommandEntry {
|
|
488
|
+
constructor(options, parent) {
|
|
489
|
+
super(options);
|
|
490
|
+
this.parent = parent;
|
|
810
491
|
}
|
|
811
492
|
};
|
|
812
493
|
|
|
813
|
-
// src/
|
|
814
|
-
var
|
|
815
|
-
((
|
|
816
|
-
|
|
817
|
-
function use(
|
|
494
|
+
// src/command/Command.ts
|
|
495
|
+
var CommandAPI;
|
|
496
|
+
((CommandAPI2) => {
|
|
497
|
+
let rootEntries = /* @__PURE__ */ new WeakMap();
|
|
498
|
+
function use(root) {
|
|
818
499
|
return (target) => {
|
|
819
|
-
|
|
500
|
+
root.setTarget(target), rootEntries.set(target, root);
|
|
820
501
|
};
|
|
821
502
|
}
|
|
822
|
-
|
|
823
|
-
function
|
|
824
|
-
return
|
|
503
|
+
CommandAPI2.use = use;
|
|
504
|
+
function getRoot(constructor) {
|
|
505
|
+
return rootEntries.get(constructor);
|
|
825
506
|
}
|
|
826
|
-
|
|
827
|
-
})(
|
|
828
|
-
function
|
|
829
|
-
|
|
830
|
-
return new ListenerEntry(fullOptions);
|
|
507
|
+
CommandAPI2.getRoot = getRoot;
|
|
508
|
+
})(CommandAPI ||= {});
|
|
509
|
+
function CommandFactory(options) {
|
|
510
|
+
return typeof options == "string" && (options = { name: options }), options.description || (options.description = options.name), new RootCommandEntry(options);
|
|
831
511
|
}
|
|
832
|
-
var
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
837
|
-
var ListenerRegistry = class {
|
|
838
|
-
static client;
|
|
839
|
-
static constructors = /* @__PURE__ */ new Set();
|
|
840
|
-
static instances = /* @__PURE__ */ new WeakMap();
|
|
841
|
-
static executors = /* @__PURE__ */ new WeakMap();
|
|
512
|
+
var Command = Object.assign(CommandFactory, CommandAPI);
|
|
513
|
+
var CommandRegistry = class _CommandRegistry {
|
|
514
|
+
static constructors = new Collection();
|
|
515
|
+
static instances = new Collection();
|
|
842
516
|
/**
|
|
843
|
-
* Add
|
|
844
|
-
*
|
|
845
|
-
* @param constructor The listener class you want to add.
|
|
517
|
+
* Add a command to the registry.
|
|
518
|
+
* @param constructor The command class you want to add.
|
|
846
519
|
*/
|
|
847
520
|
static add(constructor) {
|
|
848
|
-
|
|
849
|
-
if (!
|
|
850
|
-
throw new Error(`No
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
if (!options.emitter) {
|
|
854
|
-
if (!this.client) {
|
|
855
|
-
throw new Error("Client is not ready.");
|
|
856
|
-
}
|
|
857
|
-
options.emitter = this.client;
|
|
858
|
-
}
|
|
859
|
-
const instance = new constructor();
|
|
860
|
-
const executor = this.createExecutor(constructor, instance);
|
|
861
|
-
this.constructors.add(constructor);
|
|
862
|
-
this.instances.set(constructor, instance);
|
|
863
|
-
this.executors.set(instance, executor);
|
|
864
|
-
options.emitter[options.once ? "once" : "on"](options.name, (...args) => {
|
|
865
|
-
void executor(...args);
|
|
866
|
-
});
|
|
521
|
+
let root = Command.getRoot(constructor);
|
|
522
|
+
if (!root)
|
|
523
|
+
throw new Error(`No root found for "${constructor.name}"`);
|
|
524
|
+
let { options } = root;
|
|
525
|
+
this.constructors.set(options.name, constructor), this.instances.set(options.name, new constructor());
|
|
867
526
|
}
|
|
868
527
|
/**
|
|
869
|
-
*
|
|
870
|
-
* @param
|
|
871
|
-
* @
|
|
528
|
+
* Load and add all commands which matched provided glob pattern to the registry.
|
|
529
|
+
* @param pattern glob pattern to load.
|
|
530
|
+
* @param parallel load all matched results in parallel, enabled by default.
|
|
531
|
+
* @returns All loaded command constructors.
|
|
872
532
|
*/
|
|
873
|
-
static
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
return
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
const executor = this.executors.get(instance);
|
|
885
|
-
if (!executor) {
|
|
886
|
-
return false;
|
|
887
|
-
}
|
|
888
|
-
const { name, emitter } = entry.options;
|
|
889
|
-
emitter?.removeListener(name, executor);
|
|
890
|
-
this.executors.delete(instance);
|
|
891
|
-
return true;
|
|
533
|
+
static async load(pattern, parallel = true) {
|
|
534
|
+
let loaders = (await glob(pattern)).map(async (file) => {
|
|
535
|
+
let fileURL = pathToFileURL(file).toString(), { default: constructor } = await import(fileURL);
|
|
536
|
+
return _CommandRegistry.add(constructor), constructor;
|
|
537
|
+
});
|
|
538
|
+
if (parallel)
|
|
539
|
+
return await Promise.all(loaders);
|
|
540
|
+
let result = [];
|
|
541
|
+
for (let loader of loaders)
|
|
542
|
+
result.push(await loader);
|
|
543
|
+
return result;
|
|
892
544
|
}
|
|
893
545
|
/**
|
|
894
|
-
*
|
|
895
|
-
* @
|
|
546
|
+
* Build a command into application command data.
|
|
547
|
+
* @param constructor The command class you want to build.
|
|
548
|
+
* @returns a REST JSON version of the application command data.
|
|
896
549
|
*/
|
|
897
|
-
static
|
|
898
|
-
let
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
550
|
+
static buildSlashCommand(constructor) {
|
|
551
|
+
let root = Command.getRoot(constructor);
|
|
552
|
+
if (!root)
|
|
553
|
+
throw new Error(`No root found for "${constructor.name}"`);
|
|
554
|
+
let { options } = root, builder = new SlashCommandBuilder().setName(options.name).setDescription(options.description).setNSFW(!!options.nsfw), args = this.getMainHookArguments(root);
|
|
555
|
+
return root.children.size ? this.buildSlashCommandSubcommands(builder, root, args) : this.buildSlashCommandOptions(builder, args), builder.toJSON();
|
|
556
|
+
}
|
|
557
|
+
static getMainHookArguments(entry) {
|
|
558
|
+
let { hooks } = entry, mainHook = hooks.MAIN;
|
|
559
|
+
return mainHook ? Arg.getMethodArguments(mainHook.method) : [];
|
|
560
|
+
}
|
|
561
|
+
static buildSlashCommandSubcommands(parent, entry, inheritedArgs) {
|
|
562
|
+
let { children } = entry;
|
|
563
|
+
for (let child of children.values())
|
|
564
|
+
if (child instanceof CommandGroupEntry && parent instanceof SlashCommandBuilder) {
|
|
565
|
+
let { options } = child, group = new SlashCommandSubcommandGroupBuilder().setName(options.name).setDescription(options.description);
|
|
566
|
+
this.buildSlashCommandSubcommands(group, child, [
|
|
567
|
+
...inheritedArgs,
|
|
568
|
+
...this.getMainHookArguments(child)
|
|
569
|
+
]), parent.addSubcommandGroup(group);
|
|
570
|
+
} else if (child instanceof SubcommandEntry) {
|
|
571
|
+
let { options } = child, subcommand = new SlashCommandSubcommandBuilder().setName(options.name).setDescription(options.description);
|
|
572
|
+
this.buildSlashCommandOptions(subcommand, [
|
|
573
|
+
...inheritedArgs,
|
|
574
|
+
...this.getMainHookArguments(child)
|
|
575
|
+
]), parent.addSubcommand(subcommand);
|
|
902
576
|
}
|
|
903
|
-
}
|
|
904
|
-
return removedAmount;
|
|
905
577
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
static setClient(newClient) {
|
|
911
|
-
this.client = newClient;
|
|
578
|
+
static buildSlashCommandOptions(builder, args) {
|
|
579
|
+
let argGroup = Object.groupBy(args, ({ required }) => required ? "required" : "optional"), orderedArgs = [...argGroup.required || [], ...argGroup.optional || []];
|
|
580
|
+
for (let arg of orderedArgs)
|
|
581
|
+
this.attachSlashCommandOption(builder, arg);
|
|
912
582
|
}
|
|
913
|
-
static
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const postHook = hooks["POST" /* Post */];
|
|
923
|
-
const errorHook = hooks["ERROR" /* Error */];
|
|
924
|
-
if (!mainHook) {
|
|
925
|
-
return;
|
|
583
|
+
static attachSlashCommandOption(builder, arg) {
|
|
584
|
+
let setupOption = (option) => option.setName(arg.name).setDescription(arg.description || arg.name).setRequired(!!arg.required);
|
|
585
|
+
switch (arg.type) {
|
|
586
|
+
case "string" /* String */: {
|
|
587
|
+
builder.addStringOption((data) => {
|
|
588
|
+
let option = setupOption(data);
|
|
589
|
+
return arg.maxLength && option.setMaxLength(arg.maxLength), arg.minLength && option.setMinLength(arg.minLength), option;
|
|
590
|
+
});
|
|
591
|
+
break;
|
|
926
592
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
await postHook.method.call(instance, ...args);
|
|
934
|
-
}
|
|
935
|
-
} catch (error) {
|
|
936
|
-
if (errorHook) {
|
|
937
|
-
await errorHook.method.call(
|
|
938
|
-
instance,
|
|
939
|
-
error,
|
|
940
|
-
...args
|
|
941
|
-
);
|
|
942
|
-
} else {
|
|
943
|
-
throw error;
|
|
944
|
-
}
|
|
593
|
+
case "integer" /* Integer */: {
|
|
594
|
+
builder.addIntegerOption((data) => {
|
|
595
|
+
let option = setupOption(data);
|
|
596
|
+
return arg.maxValue && option.setMaxValue(arg.maxValue), arg.minValue && option.setMinValue(arg.minValue), option;
|
|
597
|
+
});
|
|
598
|
+
break;
|
|
945
599
|
}
|
|
600
|
+
case "number" /* Number */: {
|
|
601
|
+
builder.addNumberOption((data) => {
|
|
602
|
+
let option = setupOption(data);
|
|
603
|
+
return arg.maxValue && option.setMaxValue(arg.maxValue), arg.minValue && option.setMinValue(arg.minValue), option;
|
|
604
|
+
});
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
case "user" /* User */:
|
|
608
|
+
case "member" /* Member */: {
|
|
609
|
+
builder.addUserOption((option) => setupOption(option));
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
var BaseContext = class {
|
|
616
|
+
constructor(source) {
|
|
617
|
+
this.source = source;
|
|
618
|
+
}
|
|
619
|
+
get client() {
|
|
620
|
+
return this.source.client;
|
|
621
|
+
}
|
|
622
|
+
get channel() {
|
|
623
|
+
return this.source.channel;
|
|
624
|
+
}
|
|
625
|
+
get channelId() {
|
|
626
|
+
return this.source.channelId;
|
|
627
|
+
}
|
|
628
|
+
get guild() {
|
|
629
|
+
return this.source.guild;
|
|
630
|
+
}
|
|
631
|
+
get guildId() {
|
|
632
|
+
return this.source.guildId;
|
|
633
|
+
}
|
|
634
|
+
inGuild() {
|
|
635
|
+
return !!this.guildId;
|
|
636
|
+
}
|
|
637
|
+
inCachedGuild() {
|
|
638
|
+
if (this.isChatInput())
|
|
639
|
+
return this.source.inCachedGuild();
|
|
640
|
+
if (this.isMessage())
|
|
641
|
+
return this.source.inGuild();
|
|
642
|
+
throw new Error("Invalid source");
|
|
643
|
+
}
|
|
644
|
+
get author() {
|
|
645
|
+
if (this.isChatInput())
|
|
646
|
+
return this.source.user;
|
|
647
|
+
if (this.isMessage())
|
|
648
|
+
return this.source.author;
|
|
649
|
+
throw new Error("Invalid source");
|
|
650
|
+
}
|
|
651
|
+
isChatInput() {
|
|
652
|
+
return this.source instanceof ChatInputCommandInteraction;
|
|
653
|
+
}
|
|
654
|
+
isMessage() {
|
|
655
|
+
return this.source instanceof Message;
|
|
656
|
+
}
|
|
657
|
+
}, ChatInputContext = class extends BaseContext {
|
|
658
|
+
async send(options) {
|
|
659
|
+
typeof options == "string" && (options = { content: options });
|
|
660
|
+
let sendOptions = {
|
|
661
|
+
...options,
|
|
662
|
+
withResponse: true
|
|
946
663
|
};
|
|
664
|
+
return this.source.deferred || this.source.replied ? await this.source.followUp(sendOptions) : (await this.source.reply(sendOptions)).resource?.message;
|
|
947
665
|
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
static async load(pattern, parallel = true) {
|
|
955
|
-
const files = await glob2(pattern);
|
|
956
|
-
const loaders = files.map(async (file) => {
|
|
957
|
-
const fileURL = pathToFileURL2(file).toString();
|
|
958
|
-
const { default: constructor } = await import(fileURL);
|
|
959
|
-
this.add(constructor);
|
|
960
|
-
return constructor;
|
|
961
|
-
});
|
|
962
|
-
if (parallel) {
|
|
963
|
-
return Promise.all(loaders);
|
|
964
|
-
}
|
|
965
|
-
const result = [];
|
|
966
|
-
for (const loader of loaders) {
|
|
967
|
-
result.push(await loader);
|
|
968
|
-
}
|
|
969
|
-
return result;
|
|
666
|
+
}, MessageContext = class extends BaseContext {
|
|
667
|
+
async send(options) {
|
|
668
|
+
let { channel } = this;
|
|
669
|
+
if (!channel?.isSendable())
|
|
670
|
+
throw new Error("Invalid channel or channel is not sendable");
|
|
671
|
+
return await channel.send(options);
|
|
970
672
|
}
|
|
971
673
|
};
|
|
972
674
|
|
|
973
|
-
// src/
|
|
974
|
-
var
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
super(options);
|
|
980
|
-
ListenerRegistry["setClient"](this);
|
|
981
|
-
this.once(
|
|
982
|
-
Events.ClientReady,
|
|
983
|
-
(client) => void this.registerApplicationCommands(client)
|
|
984
|
-
);
|
|
985
|
-
this.on(Events.InteractionCreate, (interaction) => void this.handleInteraction(interaction));
|
|
986
|
-
this.on(Events.MessageCreate, (message) => void this.handleMessage(message));
|
|
987
|
-
}
|
|
988
|
-
static getSyntaxErrorMessage = (command, error, context, args, prefix) => {
|
|
989
|
-
const requiredSyntax = args.map((x) => Arg.format(x)).join(" ");
|
|
990
|
-
const root = Command.getRoot(command.constructor);
|
|
991
|
-
if (!root) {
|
|
992
|
-
return;
|
|
993
|
-
}
|
|
994
|
-
const content = [
|
|
675
|
+
// src/utils/command.ts
|
|
676
|
+
var defaultGetSyntaxErrorMessage = (command, error, context, resolver) => {
|
|
677
|
+
let requiredSyntax = resolver.args.map((x) => Arg.format(x)).join(" "), root = Command.getRoot(command.constructor);
|
|
678
|
+
return root ? {
|
|
679
|
+
content: [
|
|
995
680
|
codeBlock(error.message),
|
|
996
681
|
"Required Syntax:",
|
|
997
|
-
codeBlock(`${prefix}${root.options.name} ${requiredSyntax}`)
|
|
998
|
-
].join(
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
682
|
+
codeBlock(`${resolver.prefix}${root.options.name} ${requiredSyntax}`)
|
|
683
|
+
].join(`
|
|
684
|
+
`)
|
|
685
|
+
} : void 0;
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
// src/dispatchers/CommandDispatcher.ts
|
|
689
|
+
var CommandDispatcher = class {
|
|
690
|
+
constructor(client) {
|
|
691
|
+
this.client = client;
|
|
692
|
+
}
|
|
693
|
+
async getPrefixes(message) {
|
|
694
|
+
let { options, user: user2 } = this.client, results = await Promise.all(
|
|
695
|
+
(options.prefixes ?? []).map(async (prefix) => {
|
|
696
|
+
if (typeof prefix == "string")
|
|
697
|
+
return [prefix];
|
|
698
|
+
let result = await prefix(message);
|
|
699
|
+
return Array.isArray(result) ? result : [result];
|
|
700
|
+
})
|
|
701
|
+
), prefixes = [...options.enableMentionPrefix && user2 ? [user2.toString()] : [], ...results.flat()];
|
|
702
|
+
return Array.from(new Set(prefixes));
|
|
703
|
+
}
|
|
704
|
+
async handleChatInput(interaction) {
|
|
705
|
+
let { commandName } = interaction, constructor = CommandRegistry.constructors.get(commandName), instance = CommandRegistry.instances.get(commandName);
|
|
706
|
+
if (!constructor || !instance)
|
|
1014
707
|
return;
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const command = CommandRegistry.instances.get(trigger);
|
|
1018
|
-
if (!command) {
|
|
708
|
+
let root = Command.getRoot(constructor);
|
|
709
|
+
if (!root)
|
|
1019
710
|
return;
|
|
1020
|
-
|
|
1021
|
-
await StateBox.run(() => this.
|
|
711
|
+
let context = new ChatInputContext(interaction), triggerChain = this.getChatInputTriggerChain(interaction), chain = this.resolveCommandEntryChain(root, triggerChain), parsedValues = chain.flatMap((entry) => this.resolveChatInputEntry(interaction, entry));
|
|
712
|
+
await StateBox.run(() => this.executeChain(chain, context, instance, parsedValues));
|
|
1022
713
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
}
|
|
1027
|
-
const { commandName } = interaction;
|
|
1028
|
-
const command = CommandRegistry.instances.get(commandName);
|
|
1029
|
-
if (!command) {
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
const context = new ChatInputContext(interaction);
|
|
1033
|
-
await StateBox.run(() => this.handleChatInputHooks(context, command));
|
|
1034
|
-
}
|
|
1035
|
-
async handleChatInputHooks(context, instance) {
|
|
1036
|
-
const targetHooks = this.getChatInputTargetHooks(context.source, instance);
|
|
1037
|
-
let inheritedArgs = [];
|
|
1038
|
-
for (const hooks of [targetHooks.root, targetHooks.group, targetHooks.subcommand]) {
|
|
1039
|
-
if (!hooks) {
|
|
1040
|
-
continue;
|
|
1041
|
-
}
|
|
1042
|
-
const newArgs = await this.runChatInputHooks(context, instance, hooks, inheritedArgs);
|
|
1043
|
-
if (newArgs) {
|
|
1044
|
-
inheritedArgs = newArgs;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
714
|
+
getChatInputTriggerChain(interaction) {
|
|
715
|
+
let chain = [], subcommand = interaction.options.getSubcommand(false), subcommandGroup = interaction.options.getSubcommandGroup(false);
|
|
716
|
+
return subcommandGroup && chain.push(subcommandGroup), subcommand && chain.push(subcommand), chain;
|
|
1047
717
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
const root = Command.getRoot(instance.constructor);
|
|
1053
|
-
if (!root) {
|
|
1054
|
-
return;
|
|
1055
|
-
}
|
|
1056
|
-
resolver = await this.runMessageHooks(context, instance, root.hooks, resolver);
|
|
1057
|
-
if (!resolver) {
|
|
1058
|
-
return;
|
|
1059
|
-
}
|
|
1060
|
-
await this.handleChildMessageHooks(context, root, instance, resolver);
|
|
718
|
+
resolveChatInputEntry(interaction, entry) {
|
|
719
|
+
let mainHook = entry.hooks.MAIN;
|
|
720
|
+
return (mainHook ? Arg.getMethodArguments(mainHook.method) : []).map((arg) => ArgumentResolver.resolveChatInputOption(interaction, arg));
|
|
1061
721
|
}
|
|
1062
|
-
async
|
|
1063
|
-
|
|
722
|
+
async handleMessage(message) {
|
|
723
|
+
let resolver = await ArgumentResolver.initialize(message);
|
|
724
|
+
if (!resolver)
|
|
1064
725
|
return;
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
const nextTrigger = resolver.values[usedValues + skip];
|
|
1068
|
-
const child = parent.children.get(nextTrigger);
|
|
1069
|
-
if (!child) {
|
|
726
|
+
let constructor = CommandRegistry.constructors.get(resolver.commandName), instance = CommandRegistry.instances.get(resolver.commandName);
|
|
727
|
+
if (!constructor || !instance)
|
|
1070
728
|
return;
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
async runMessageHooks(context, instance, hooks, resolver) {
|
|
1078
|
-
const mainHook = hooks["MAIN" /* Main */];
|
|
1079
|
-
if (!mainHook) {
|
|
1080
|
-
return resolver;
|
|
1081
|
-
}
|
|
1082
|
-
const args = Arg.getMethodArguments(mainHook.method);
|
|
729
|
+
let root = Command.getRoot(constructor);
|
|
730
|
+
if (!root)
|
|
731
|
+
return;
|
|
732
|
+
let context = new MessageContext(message);
|
|
1083
733
|
try {
|
|
1084
|
-
|
|
734
|
+
await resolver.resolve(root);
|
|
1085
735
|
} catch (error) {
|
|
1086
736
|
if (error instanceof CommandSyntaxError) {
|
|
1087
|
-
|
|
737
|
+
let payload = await this.client.options.getSyntaxErrorMessage?.(
|
|
1088
738
|
instance,
|
|
1089
739
|
error,
|
|
1090
740
|
context,
|
|
1091
|
-
|
|
1092
|
-
resolver.options.prefix
|
|
741
|
+
resolver
|
|
1093
742
|
);
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
return null;
|
|
1098
|
-
}
|
|
1099
|
-
throw error;
|
|
743
|
+
payload && await context.send(payload);
|
|
744
|
+
} else
|
|
745
|
+
throw error;
|
|
1100
746
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
747
|
+
let literalTriggers = resolver.args.filter((arg) => arg.type === "literal" /* Literal */).map((arg) => arg.value), entryChain = this.resolveCommandEntryChain(root, literalTriggers), values = resolver.parsedValues;
|
|
748
|
+
await StateBox.run(() => this.executeChain(entryChain, context, instance, values));
|
|
1103
749
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
750
|
+
resolveCommandEntryChain(root, triggers) {
|
|
751
|
+
return triggers.reduce(
|
|
752
|
+
(acc, trigger) => {
|
|
753
|
+
let parent = acc.at(-1);
|
|
754
|
+
if (parent && "children" in parent) {
|
|
755
|
+
let child = parent.children.get(trigger);
|
|
756
|
+
child && acc.push(child);
|
|
757
|
+
}
|
|
758
|
+
return acc;
|
|
759
|
+
},
|
|
760
|
+
[root]
|
|
1111
761
|
);
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
const errorHook = hooks["ERROR" /* Error */];
|
|
1121
|
-
if (!mainHook) {
|
|
762
|
+
}
|
|
763
|
+
async executeChain(chain, context, instance, values) {
|
|
764
|
+
for (let entry of chain)
|
|
765
|
+
await this.executeHooks(entry, context, instance, values);
|
|
766
|
+
}
|
|
767
|
+
async executeHooks(entry, context, instance, values) {
|
|
768
|
+
let { hooks } = entry;
|
|
769
|
+
if (!hooks.MAIN)
|
|
1122
770
|
return;
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
await hook.method.call(instance,
|
|
1130
|
-
} else {
|
|
1131
|
-
await hook.method.call(instance, context, ...args);
|
|
771
|
+
let execute = async (hook, error) => {
|
|
772
|
+
if (hook) {
|
|
773
|
+
if (hook.state === "ERROR" /* Error */) {
|
|
774
|
+
await hook.method.call(instance, error, context, ...values);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
await hook.method.call(instance, context, ...values);
|
|
1132
778
|
}
|
|
1133
779
|
};
|
|
1134
780
|
try {
|
|
1135
|
-
await execute(
|
|
1136
|
-
await execute(mainHook);
|
|
1137
|
-
await execute(postHook);
|
|
781
|
+
await execute(hooks.PRE), await execute(hooks.MAIN), await execute(hooks.POST);
|
|
1138
782
|
} catch (error) {
|
|
1139
|
-
if (
|
|
1140
|
-
await execute(
|
|
1141
|
-
|
|
783
|
+
if (hooks.ERROR)
|
|
784
|
+
await execute(hooks.ERROR, error);
|
|
785
|
+
else
|
|
1142
786
|
throw error;
|
|
1143
|
-
}
|
|
1144
787
|
}
|
|
1145
788
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
let group;
|
|
1154
|
-
if (groupName) {
|
|
1155
|
-
const child = root.children.get(groupName);
|
|
1156
|
-
if (child instanceof CommandGroupEntry) {
|
|
1157
|
-
group = child;
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
let subcommand;
|
|
1161
|
-
if (subcommandName) {
|
|
1162
|
-
const parent = group || root;
|
|
1163
|
-
const child = parent.children.get(subcommandName);
|
|
1164
|
-
if (child instanceof SubcommandEntry) {
|
|
1165
|
-
subcommand = child;
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
return {
|
|
1169
|
-
root: root.hooks,
|
|
1170
|
-
group: group?.hooks,
|
|
1171
|
-
subcommand: subcommand?.hooks
|
|
1172
|
-
};
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// src/dispatchers/DispatcherManager.ts
|
|
792
|
+
var DispatcherManager = class {
|
|
793
|
+
constructor(client) {
|
|
794
|
+
this.client = client;
|
|
795
|
+
this.command = new CommandDispatcher(client);
|
|
1173
796
|
}
|
|
797
|
+
command;
|
|
1174
798
|
};
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
ListenerFactory,
|
|
1194
|
-
ListenerRegistry,
|
|
1195
|
-
MessageContext,
|
|
1196
|
-
RootCommandEntry,
|
|
1197
|
-
StateBox,
|
|
1198
|
-
SubcommandEntry,
|
|
1199
|
-
extractId
|
|
799
|
+
|
|
800
|
+
// src/BakitClient.ts
|
|
801
|
+
var BakitClient = class extends Client {
|
|
802
|
+
dispatchers;
|
|
803
|
+
constructor(options) {
|
|
804
|
+
options.getSyntaxErrorMessage === void 0 && (options.getSyntaxErrorMessage = defaultGetSyntaxErrorMessage), super(options), ListenerRegistry.setClient(this), this.dispatchers = new DispatcherManager(this), this.initializeHandlers();
|
|
805
|
+
}
|
|
806
|
+
isReady() {
|
|
807
|
+
return super.isReady();
|
|
808
|
+
}
|
|
809
|
+
initializeHandlers() {
|
|
810
|
+
this.on(
|
|
811
|
+
Events.MessageCreate,
|
|
812
|
+
(message) => void this.dispatchers.command.handleMessage(message)
|
|
813
|
+
), this.on(Events.InteractionCreate, (interaction) => {
|
|
814
|
+
interaction.isChatInputCommand() && this.dispatchers.command.handleChatInput(interaction);
|
|
815
|
+
});
|
|
816
|
+
}
|
|
1200
817
|
};
|
|
818
|
+
|
|
819
|
+
export { Arg, ArgumentResolver, ArgumentType, BakitClient, BaseCommandEntry, BaseCommandGroupEntry, BaseContext, ChatInputContext, Command, CommandAPI, CommandFactory, CommandGroupEntry, CommandRegistry, CommandSyntaxError, CommandSyntaxErrorType, Listener, ListenerAPI, ListenerEntry, ListenerFactory, ListenerRegistry, MessageContext, RootCommandEntry, StateBox, SubcommandEntry, defaultGetSyntaxErrorMessage, extractId };
|