bakit 1.0.0-beta.14 → 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 +547 -578
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as discord_js from 'discord.js';
|
|
2
|
-
import { Awaitable, ChatInputCommandInteraction, CacheType, Message, InteractionReplyOptions, MessageCreateOptions, User, Collection, RESTPostAPIApplicationCommandsJSONBody,
|
|
3
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { Awaitable, ChatInputCommandInteraction, CacheType, Message, InteractionReplyOptions, MessageCreateOptions, User, Collection, RESTPostAPIApplicationCommandsJSONBody, ClientOptions, Client, IntentsBitField, ClientEvents } from 'discord.js';
|
|
4
3
|
import { SetOptional } from 'type-fest';
|
|
4
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
5
5
|
import EventEmitter from 'node:events';
|
|
6
6
|
|
|
7
7
|
type ConstructorLike = new (...args: unknown[]) => object;
|
|
@@ -91,13 +91,15 @@ declare class SubcommandEntry extends BaseCommandEntry {
|
|
|
91
91
|
parent: BaseCommandGroupEntry;
|
|
92
92
|
constructor(options: BaseCommandEntryOptions, parent: BaseCommandGroupEntry);
|
|
93
93
|
}
|
|
94
|
+
type CommandEntry = RootCommandEntry | CommandGroupEntry | SubcommandEntry;
|
|
94
95
|
|
|
95
96
|
declare enum ArgumentType {
|
|
96
97
|
String = "string",
|
|
97
98
|
Integer = "integer",
|
|
98
99
|
Number = "number",
|
|
99
100
|
User = "user",
|
|
100
|
-
Member = "member"
|
|
101
|
+
Member = "member",
|
|
102
|
+
Literal = "literal"
|
|
101
103
|
}
|
|
102
104
|
interface BaseArgumentOptions {
|
|
103
105
|
type: ArgumentType;
|
|
@@ -127,13 +129,17 @@ interface UserArgumentOptions extends BaseArgumentOptions {
|
|
|
127
129
|
interface MemberArgumentOptions extends BaseArgumentOptions {
|
|
128
130
|
type: ArgumentType.Member;
|
|
129
131
|
}
|
|
132
|
+
interface LiteralArgumentOptions extends Omit<BaseArgumentOptions, "name"> {
|
|
133
|
+
type: ArgumentType.Literal;
|
|
134
|
+
value: string;
|
|
135
|
+
}
|
|
130
136
|
type ArgumentOptions = StringArgumentOptions | IntegerArgumentOptions | NumberArgumentOptions | UserArgumentOptions | MemberArgumentOptions;
|
|
131
137
|
|
|
132
138
|
declare function getMethodArguments(method: CommandHook["method"]): readonly ArgumentOptions[];
|
|
133
139
|
declare function getMethodArguments(method: CommandHook["method"], init: true): ArgumentOptions[];
|
|
134
140
|
declare function createArgument<Options extends ArgumentOptions>(type: Options["type"]): (options: Omit<Options, "type"> | string) => (target: object, key: string | symbol, _index: number) => void;
|
|
135
|
-
declare function describeArgumentExpectation(arg: ArgumentOptions): string;
|
|
136
|
-
declare function format(arg: ArgumentOptions): string;
|
|
141
|
+
declare function describeArgumentExpectation(arg: ArgumentOptions | LiteralArgumentOptions): string;
|
|
142
|
+
declare function format(arg: ArgumentOptions | LiteralArgumentOptions): string;
|
|
137
143
|
declare const Arg: {
|
|
138
144
|
getMethodArguments: typeof getMethodArguments;
|
|
139
145
|
createArgument: typeof createArgument;
|
|
@@ -146,6 +152,36 @@ declare const Arg: {
|
|
|
146
152
|
member: (options: string | Omit<MemberArgumentOptions, "type">) => (target: object, key: string | symbol, _index: number) => void;
|
|
147
153
|
};
|
|
148
154
|
|
|
155
|
+
interface ArgumentResolverOptions {
|
|
156
|
+
message: Message;
|
|
157
|
+
values: string[];
|
|
158
|
+
prefix: string;
|
|
159
|
+
}
|
|
160
|
+
declare class ArgumentResolver {
|
|
161
|
+
private _values;
|
|
162
|
+
prefix: string;
|
|
163
|
+
message: Message;
|
|
164
|
+
private _parsedValues;
|
|
165
|
+
private _args;
|
|
166
|
+
constructor(_values: string[], prefix: string, message: Message);
|
|
167
|
+
get commandName(): string;
|
|
168
|
+
get values(): readonly string[];
|
|
169
|
+
get parsedValues(): readonly unknown[];
|
|
170
|
+
get args(): readonly (ArgumentOptions | LiteralArgumentOptions)[];
|
|
171
|
+
get client(): BakitClient<true>;
|
|
172
|
+
static initialize(message: Message): Promise<ArgumentResolver | undefined>;
|
|
173
|
+
resolve(entry: CommandEntry, at?: number): Promise<void>;
|
|
174
|
+
protected parseExact(args: ArgumentOptions[], values: string[]): Promise<unknown[]>;
|
|
175
|
+
protected parseFlexible(args: ArgumentOptions[], values: string[]): Promise<unknown[]>;
|
|
176
|
+
private matchValue;
|
|
177
|
+
private matchUserValue;
|
|
178
|
+
private matchMemberValue;
|
|
179
|
+
private matchIntegerValue;
|
|
180
|
+
private matchNumberValue;
|
|
181
|
+
private matchStringValue;
|
|
182
|
+
static resolveChatInputOption(interaction: ChatInputCommandInteraction, arg: ArgumentOptions): string | number | discord_js.GuildMember | discord_js.User | discord_js.APIInteractionDataResolvedGuildMember | null;
|
|
183
|
+
}
|
|
184
|
+
|
|
149
185
|
declare namespace CommandAPI {
|
|
150
186
|
function use(root: RootCommandEntry): (target: ConstructorLike) => void;
|
|
151
187
|
function getRoot(constructor: ConstructorLike): RootCommandEntry | undefined;
|
|
@@ -199,9 +235,31 @@ declare class CommandSyntaxError extends Error {
|
|
|
199
235
|
get name(): string;
|
|
200
236
|
}
|
|
201
237
|
|
|
202
|
-
type GetSyntaxErrorMessageFunction = (command: object, error: CommandSyntaxError, context: MessageContext,
|
|
238
|
+
type GetSyntaxErrorMessageFunction = (command: object, error: CommandSyntaxError, context: MessageContext, resolver: ArgumentResolver) => Awaitable<MessageCreateOptions | undefined>;
|
|
239
|
+
declare const defaultGetSyntaxErrorMessage: GetSyntaxErrorMessageFunction;
|
|
240
|
+
|
|
241
|
+
declare class CommandDispatcher {
|
|
242
|
+
client: BakitClient;
|
|
243
|
+
constructor(client: BakitClient);
|
|
244
|
+
getPrefixes(message: Message): Promise<string[]>;
|
|
245
|
+
handleChatInput(interaction: ChatInputCommandInteraction): Promise<void>;
|
|
246
|
+
private getChatInputTriggerChain;
|
|
247
|
+
private resolveChatInputEntry;
|
|
248
|
+
handleMessage(message: Message): Promise<void>;
|
|
249
|
+
private resolveCommandEntryChain;
|
|
250
|
+
private executeChain;
|
|
251
|
+
private executeHooks;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
declare class DispatcherManager {
|
|
255
|
+
client: BakitClient;
|
|
256
|
+
command: CommandDispatcher;
|
|
257
|
+
constructor(client: BakitClient);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
type GetPrefixFunction = (message: Message) => Awaitable<string[] | string>;
|
|
203
261
|
interface BakitClientOptions extends ClientOptions {
|
|
204
|
-
prefixes?: string[];
|
|
262
|
+
prefixes?: (string | GetPrefixFunction)[];
|
|
205
263
|
enableMentionPrefix?: boolean;
|
|
206
264
|
getSyntaxErrorMessage?: GetSyntaxErrorMessageFunction | null;
|
|
207
265
|
}
|
|
@@ -209,25 +267,16 @@ declare class BakitClient<Ready extends boolean = boolean> extends Client<Ready>
|
|
|
209
267
|
options: Omit<BakitClientOptions, "intents"> & {
|
|
210
268
|
intents: IntentsBitField;
|
|
211
269
|
};
|
|
270
|
+
dispatchers: DispatcherManager;
|
|
212
271
|
constructor(options: BakitClientOptions);
|
|
213
|
-
|
|
214
|
-
private
|
|
215
|
-
private handleMessage;
|
|
216
|
-
private handleInteraction;
|
|
217
|
-
private handleChatInputHooks;
|
|
218
|
-
private handleMessageHooks;
|
|
219
|
-
private handleChildMessageHooks;
|
|
220
|
-
private runMessageHooks;
|
|
221
|
-
private runChatInputHooks;
|
|
222
|
-
private runHooks;
|
|
223
|
-
private getChatInputTargetHooks;
|
|
272
|
+
isReady(): this is BakitClient<true>;
|
|
273
|
+
private initializeHandlers;
|
|
224
274
|
}
|
|
225
275
|
|
|
226
276
|
declare function extractId(value: string): string | null;
|
|
227
277
|
|
|
228
278
|
type States = Record<string | symbol, unknown>;
|
|
229
279
|
declare class StateBox {
|
|
230
|
-
private static readonly STATES_KEY;
|
|
231
280
|
static storage: AsyncLocalStorage<States>;
|
|
232
281
|
private static getState;
|
|
233
282
|
static run<R>(fn: () => R, store?: {}): R;
|
|
@@ -298,16 +347,4 @@ declare abstract class ListenerRegistry {
|
|
|
298
347
|
static load(pattern: string, parallel?: boolean): Promise<ConstructorLike[]>;
|
|
299
348
|
}
|
|
300
349
|
|
|
301
|
-
|
|
302
|
-
* This file is used to redeclare original client to the custom one
|
|
303
|
-
* Most of the structure is from Base, but some might be not
|
|
304
|
-
*/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
declare module "discord.js" {
|
|
308
|
-
interface Base {
|
|
309
|
-
client: BakitClient<true>;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
export { Arg, type ArgumentOptions, ArgumentType, BakitClient, type BakitClientOptions, type BaseArgumentOptions, BaseCommandEntry, type BaseCommandEntryOptions, BaseCommandGroupEntry, BaseContext, ChatInputContext, type ChatInputContextSendOptions, Command, CommandAPI, CommandFactory, CommandGroupEntry, type CommandHook, CommandRegistry, CommandSyntaxError, type CommandSyntaxErrorOptions, CommandSyntaxErrorType, type Context, type ContextSendOptions, type CreateCommandOptions, type ErrorCommandHookMethod, type ErrorListenerHookMethod, type EventsLike, type GetSyntaxErrorMessageFunction, type IntegerArgumentOptions, Listener, ListenerAPI, ListenerEntry, type ListenerEntryOptions, ListenerFactory, type ListenerHook, ListenerRegistry, type MainCommandHookMethod, type MainListenerHookMethod, type MemberArgumentOptions, MessageContext, type MessageContextSendOptions, type NumberArgumentOptions, RootCommandEntry, StateBox, type States, type StringArgumentOptions, SubcommandEntry, type UserArgumentOptions, extractId };
|
|
350
|
+
export { Arg, type ArgumentOptions, ArgumentResolver, type ArgumentResolverOptions, ArgumentType, BakitClient, type BakitClientOptions, type BaseArgumentOptions, BaseCommandEntry, type BaseCommandEntryOptions, BaseCommandGroupEntry, BaseContext, ChatInputContext, type ChatInputContextSendOptions, Command, CommandAPI, type CommandEntry, CommandFactory, CommandGroupEntry, type CommandHook, CommandRegistry, CommandSyntaxError, type CommandSyntaxErrorOptions, CommandSyntaxErrorType, type Context, type ContextSendOptions, type CreateCommandOptions, type ErrorCommandHookMethod, type ErrorListenerHookMethod, type EventsLike, type GetPrefixFunction, type GetSyntaxErrorMessageFunction, type IntegerArgumentOptions, Listener, ListenerAPI, ListenerEntry, type ListenerEntryOptions, ListenerFactory, type ListenerHook, ListenerRegistry, type LiteralArgumentOptions, type MainCommandHookMethod, type MainListenerHookMethod, type MemberArgumentOptions, MessageContext, type MessageContextSendOptions, type NumberArgumentOptions, RootCommandEntry, StateBox, type States, type StringArgumentOptions, SubcommandEntry, type UserArgumentOptions, defaultGetSyntaxErrorMessage, extractId };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Collection, SlashCommandBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandBuilder, ChatInputCommandInteraction, Message, Client, Events
|
|
1
|
+
import { Collection, SlashCommandBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandBuilder, ChatInputCommandInteraction, Message, codeBlock, Client, Events } from 'discord.js';
|
|
2
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
3
|
import glob from 'tiny-glob';
|
|
3
4
|
import { pathToFileURL } from 'url';
|
|
4
|
-
import { AsyncLocalStorage } from 'async_hooks';
|
|
5
5
|
|
|
6
6
|
// src/BakitClient.ts
|
|
7
7
|
|
|
@@ -49,63 +49,177 @@ var BaseEntry = class {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
// src/
|
|
53
|
-
var
|
|
52
|
+
// src/listener/ListenerEntry.ts
|
|
53
|
+
var ListenerEntry = class extends BaseEntry {
|
|
54
54
|
constructor(options) {
|
|
55
55
|
super();
|
|
56
56
|
this.options = options;
|
|
57
57
|
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return
|
|
58
|
+
};
|
|
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
|
+
};
|
|
66
68
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (this.children.has(fullOptions.name))
|
|
71
|
-
throw new Error(`Entry "${fullOptions.name}" is already existed.`);
|
|
72
|
-
let group = new CommandGroupEntry(fullOptions, this);
|
|
73
|
-
return this.children.set(fullOptions.name, group), group;
|
|
69
|
+
ListenerAPI2.use = use;
|
|
70
|
+
function getEntry(target) {
|
|
71
|
+
return entries.get(target);
|
|
74
72
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
79
87
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
static run(fn, store2 = {}) {
|
|
89
|
+
return this.storage.run(store2, fn);
|
|
90
|
+
}
|
|
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
|
+
});
|
|
112
|
+
};
|
|
84
113
|
}
|
|
85
114
|
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
+
});
|
|
139
|
+
}
|
|
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;
|
|
159
|
+
}
|
|
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;
|
|
169
|
+
}
|
|
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));
|
|
94
199
|
};
|
|
95
200
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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;
|
|
99
218
|
}
|
|
100
|
-
|
|
101
|
-
})(CommandAPI ||= {});
|
|
102
|
-
function CommandFactory(options) {
|
|
103
|
-
return typeof options == "string" && (options = { name: options }), options.description || (options.description = options.name), new RootCommandEntry(options);
|
|
104
|
-
}
|
|
105
|
-
var Command = Object.assign(CommandFactory, CommandAPI);
|
|
219
|
+
};
|
|
106
220
|
|
|
107
221
|
// src/command/argument/Argument.ts
|
|
108
|
-
var ArgumentType = /* @__PURE__ */ ((ArgumentType2) => (ArgumentType2.String = "string", ArgumentType2.Integer = "integer", ArgumentType2.Number = "number", ArgumentType2.User = "user", ArgumentType2.Member = "member", ArgumentType2))(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 || {});
|
|
109
223
|
|
|
110
224
|
// src/command/argument/Arg.ts
|
|
111
225
|
var store = /* @__PURE__ */ new WeakMap();
|
|
@@ -141,7 +255,9 @@ function describeArgumentExpectation(arg) {
|
|
|
141
255
|
return parts.join(", ");
|
|
142
256
|
}
|
|
143
257
|
function format(arg) {
|
|
144
|
-
|
|
258
|
+
if (arg.type === "literal" /* Literal */)
|
|
259
|
+
return arg.value;
|
|
260
|
+
let { required, tuple, name } = arg, opening = required ? "<" : "[", closing = required ? ">" : "]";
|
|
145
261
|
return `${opening}${tuple ? "..." : ""}${name}: ${describeArgumentExpectation(arg)}${closing}`;
|
|
146
262
|
}
|
|
147
263
|
var Arg = {
|
|
@@ -156,24 +272,261 @@ var Arg = {
|
|
|
156
272
|
member
|
|
157
273
|
};
|
|
158
274
|
|
|
159
|
-
// src/
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
+
`);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
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
|
+
`);
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
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
|
+
`);
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
default: {
|
|
317
|
+
message = "Unknown error";
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
super(message), this.arg = arg, this.type = type, this.expected = expected, this.received = received, Error.captureStackTrace(this, this.constructor);
|
|
173
322
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
323
|
+
get name() {
|
|
324
|
+
return `CommandSyntaxError[${this.type}]`;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
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;
|
|
334
|
+
}
|
|
335
|
+
_parsedValues = [];
|
|
336
|
+
_args = [];
|
|
337
|
+
get commandName() {
|
|
338
|
+
return this._values[0];
|
|
339
|
+
}
|
|
340
|
+
get values() {
|
|
341
|
+
return this._values;
|
|
342
|
+
}
|
|
343
|
+
get parsedValues() {
|
|
344
|
+
return this._parsedValues;
|
|
345
|
+
}
|
|
346
|
+
get args() {
|
|
347
|
+
return this._args;
|
|
348
|
+
}
|
|
349
|
+
get client() {
|
|
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)
|
|
355
|
+
return;
|
|
356
|
+
let values = message.content.slice(prefix.length).trim().split(/\s+/);
|
|
357
|
+
return new _ArgumentResolver(values, prefix, message);
|
|
358
|
+
}
|
|
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);
|
|
364
|
+
}
|
|
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)
|
|
379
|
+
throw new CommandSyntaxError({
|
|
380
|
+
arg,
|
|
381
|
+
type: "INVALID_ARGUMENT" /* InvalidArgument */,
|
|
382
|
+
received: value
|
|
383
|
+
});
|
|
384
|
+
parsedValues.push(matchedValue);
|
|
385
|
+
}
|
|
386
|
+
return parsedValues;
|
|
387
|
+
}
|
|
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)
|
|
395
|
+
throw new CommandSyntaxError({
|
|
396
|
+
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
397
|
+
received: value,
|
|
398
|
+
arg
|
|
399
|
+
});
|
|
400
|
+
argIndex++;
|
|
401
|
+
}
|
|
402
|
+
return parsedValues;
|
|
403
|
+
}
|
|
404
|
+
async matchValue(arg, value) {
|
|
405
|
+
switch (arg.type) {
|
|
406
|
+
case "user" /* User */:
|
|
407
|
+
return await this.matchUserValue(arg, value);
|
|
408
|
+
case "member" /* Member */:
|
|
409
|
+
return await this.matchMemberValue(arg, value);
|
|
410
|
+
case "integer" /* Integer */:
|
|
411
|
+
return this.matchIntegerValue(arg, value);
|
|
412
|
+
case "number" /* Number */:
|
|
413
|
+
return this.matchNumberValue(arg, value);
|
|
414
|
+
case "string" /* String */:
|
|
415
|
+
return this.matchStringValue(arg, value);
|
|
416
|
+
default:
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async matchUserValue(arg, value) {
|
|
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);
|
|
431
|
+
}
|
|
432
|
+
matchIntegerValue(arg, value) {
|
|
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;
|
|
435
|
+
}
|
|
436
|
+
matchNumberValue(arg, value) {
|
|
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;
|
|
439
|
+
}
|
|
440
|
+
matchStringValue(arg, value) {
|
|
441
|
+
return arg.minLength !== void 0 && value.length < arg.minLength || arg.maxLength !== void 0 && value.length > arg.maxLength ? null : value;
|
|
442
|
+
}
|
|
443
|
+
static resolveChatInputOption(interaction, arg) {
|
|
444
|
+
switch (arg.type) {
|
|
445
|
+
case "string" /* String */:
|
|
446
|
+
return interaction.options.getString(arg.name, arg.required);
|
|
447
|
+
case "integer" /* Integer */:
|
|
448
|
+
return interaction.options.getInteger(arg.name, arg.required);
|
|
449
|
+
case "number" /* Number */:
|
|
450
|
+
return interaction.options.getNumber(arg.name, arg.required);
|
|
451
|
+
case "user" /* User */:
|
|
452
|
+
return interaction.options.getUser(arg.name, arg.required);
|
|
453
|
+
case "member" /* Member */:
|
|
454
|
+
return interaction.options.getMember(arg.name);
|
|
455
|
+
default:
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
var BaseCommandEntry = class extends BaseEntry {
|
|
461
|
+
constructor(options) {
|
|
462
|
+
super();
|
|
463
|
+
this.options = options;
|
|
464
|
+
}
|
|
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;
|
|
473
|
+
}
|
|
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;
|
|
481
|
+
}
|
|
482
|
+
}, CommandGroupEntry = class extends BaseCommandGroupEntry {
|
|
483
|
+
constructor(options, parent) {
|
|
484
|
+
super(options);
|
|
485
|
+
this.parent = parent;
|
|
486
|
+
}
|
|
487
|
+
}, SubcommandEntry = class extends BaseCommandEntry {
|
|
488
|
+
constructor(options, parent) {
|
|
489
|
+
super(options);
|
|
490
|
+
this.parent = parent;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// src/command/Command.ts
|
|
495
|
+
var CommandAPI;
|
|
496
|
+
((CommandAPI2) => {
|
|
497
|
+
let rootEntries = /* @__PURE__ */ new WeakMap();
|
|
498
|
+
function use(root) {
|
|
499
|
+
return (target) => {
|
|
500
|
+
root.setTarget(target), rootEntries.set(target, root);
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
CommandAPI2.use = use;
|
|
504
|
+
function getRoot(constructor) {
|
|
505
|
+
return rootEntries.get(constructor);
|
|
506
|
+
}
|
|
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);
|
|
511
|
+
}
|
|
512
|
+
var Command = Object.assign(CommandFactory, CommandAPI);
|
|
513
|
+
var CommandRegistry = class _CommandRegistry {
|
|
514
|
+
static constructors = new Collection();
|
|
515
|
+
static instances = new Collection();
|
|
516
|
+
/**
|
|
517
|
+
* Add a command to the registry.
|
|
518
|
+
* @param constructor The command class you want to add.
|
|
519
|
+
*/
|
|
520
|
+
static add(constructor) {
|
|
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());
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Load and add all commands which matched provided glob pattern to the registry.
|
|
529
|
+
* @param pattern glob pattern to load.
|
|
177
530
|
* @param parallel load all matched results in parallel, enabled by default.
|
|
178
531
|
* @returns All loaded command constructors.
|
|
179
532
|
*/
|
|
@@ -319,532 +672,148 @@ var BaseContext = class {
|
|
|
319
672
|
}
|
|
320
673
|
};
|
|
321
674
|
|
|
322
|
-
// src/utils/
|
|
323
|
-
|
|
324
|
-
let
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
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: [
|
|
680
|
+
codeBlock(error.message),
|
|
681
|
+
"Required Syntax:",
|
|
682
|
+
codeBlock(`${resolver.prefix}${root.options.name} ${requiredSyntax}`)
|
|
683
|
+
].join(`
|
|
684
|
+
`)
|
|
685
|
+
} : void 0;
|
|
686
|
+
};
|
|
330
687
|
|
|
331
|
-
// src/
|
|
332
|
-
var
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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)
|
|
707
|
+
return;
|
|
708
|
+
let root = Command.getRoot(constructor);
|
|
709
|
+
if (!root)
|
|
710
|
+
return;
|
|
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));
|
|
713
|
+
}
|
|
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;
|
|
717
|
+
}
|
|
718
|
+
resolveChatInputEntry(interaction, entry) {
|
|
719
|
+
let mainHook = entry.hooks.MAIN;
|
|
720
|
+
return (mainHook ? Arg.getMethodArguments(mainHook.method) : []).map((arg) => ArgumentResolver.resolveChatInputOption(interaction, arg));
|
|
721
|
+
}
|
|
722
|
+
async handleMessage(message) {
|
|
723
|
+
let resolver = await ArgumentResolver.initialize(message);
|
|
724
|
+
if (!resolver)
|
|
725
|
+
return;
|
|
726
|
+
let constructor = CommandRegistry.constructors.get(resolver.commandName), instance = CommandRegistry.instances.get(resolver.commandName);
|
|
727
|
+
if (!constructor || !instance)
|
|
728
|
+
return;
|
|
729
|
+
let root = Command.getRoot(constructor);
|
|
730
|
+
if (!root)
|
|
731
|
+
return;
|
|
732
|
+
let context = new MessageContext(message);
|
|
733
|
+
try {
|
|
734
|
+
await resolver.resolve(root);
|
|
735
|
+
} catch (error) {
|
|
736
|
+
if (error instanceof CommandSyntaxError) {
|
|
737
|
+
let payload = await this.client.options.getSyntaxErrorMessage?.(
|
|
738
|
+
instance,
|
|
739
|
+
error,
|
|
740
|
+
context,
|
|
741
|
+
resolver
|
|
742
|
+
);
|
|
743
|
+
payload && await context.send(payload);
|
|
744
|
+
} else
|
|
745
|
+
throw error;
|
|
746
|
+
}
|
|
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));
|
|
749
|
+
}
|
|
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]
|
|
761
|
+
);
|
|
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)
|
|
770
|
+
return;
|
|
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);
|
|
366
778
|
}
|
|
779
|
+
};
|
|
780
|
+
try {
|
|
781
|
+
await execute(hooks.PRE), await execute(hooks.MAIN), await execute(hooks.POST);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
if (hooks.ERROR)
|
|
784
|
+
await execute(hooks.ERROR, error);
|
|
785
|
+
else
|
|
786
|
+
throw error;
|
|
367
787
|
}
|
|
368
|
-
super(message), this.arg = arg, this.type = type, this.expected = expected, this.received = received, Error.captureStackTrace(this, this.constructor);
|
|
369
788
|
}
|
|
370
|
-
|
|
371
|
-
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// src/dispatchers/DispatcherManager.ts
|
|
792
|
+
var DispatcherManager = class {
|
|
793
|
+
constructor(client) {
|
|
794
|
+
this.client = client;
|
|
795
|
+
this.command = new CommandDispatcher(client);
|
|
372
796
|
}
|
|
797
|
+
command;
|
|
373
798
|
};
|
|
374
799
|
|
|
375
|
-
// src/
|
|
376
|
-
var
|
|
800
|
+
// src/BakitClient.ts
|
|
801
|
+
var BakitClient = class extends Client {
|
|
802
|
+
dispatchers;
|
|
377
803
|
constructor(options) {
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
parsedValues = [];
|
|
381
|
-
/**
|
|
382
|
-
* Get the first value as the command trigger.
|
|
383
|
-
*/
|
|
384
|
-
get trigger() {
|
|
385
|
-
return this.options.values[0];
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Get amount of specified argument values.
|
|
389
|
-
*/
|
|
390
|
-
get specifiedAmount() {
|
|
391
|
-
return this.options.values.length - this.options.startAt;
|
|
804
|
+
options.getSyntaxErrorMessage === void 0 && (options.getSyntaxErrorMessage = defaultGetSyntaxErrorMessage), super(options), ListenerRegistry.setClient(this), this.dispatchers = new DispatcherManager(this), this.initializeHandlers();
|
|
392
805
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
*/
|
|
396
|
-
get values() {
|
|
397
|
-
return [...this.options.values];
|
|
806
|
+
isReady() {
|
|
807
|
+
return super.isReady();
|
|
398
808
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
...client.options.prefixes ?? [],
|
|
406
|
-
// Use bot mention as prefix if enabled
|
|
407
|
-
...enableMentionPrefix ? [client.user.toString()] : []
|
|
408
|
-
].find((p) => message.content.startsWith(p)) ?? null;
|
|
409
|
-
if (!prefix)
|
|
410
|
-
return;
|
|
411
|
-
let values = message.content.slice(prefix.length).trim().split(/\s+/);
|
|
412
|
-
return new _ArgumentResolver({
|
|
413
|
-
message,
|
|
414
|
-
startAt: 1,
|
|
415
|
-
// Skip the command trigger
|
|
416
|
-
values,
|
|
417
|
-
args: [],
|
|
418
|
-
prefix
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
async resolve(args) {
|
|
422
|
-
let child = new _ArgumentResolver({
|
|
423
|
-
prefix: this.options.prefix,
|
|
424
|
-
message: this.options.message,
|
|
425
|
-
values: this.options.values,
|
|
426
|
-
args,
|
|
427
|
-
startAt: this.options.startAt
|
|
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);
|
|
428
815
|
});
|
|
429
|
-
return child.parsedValues = [...this.parsedValues], child.options.args.length && (this.specifiedAmount >= child.options.args.length ? await child.absoluteParse() : await child.dynamicParse()), child;
|
|
430
|
-
}
|
|
431
|
-
async absoluteParse() {
|
|
432
|
-
let { args, values, startAt } = this.options, valueIndex = startAt, argIndex = 0;
|
|
433
|
-
for (; valueIndex < values.length && argIndex < args.length; ) {
|
|
434
|
-
let value = values[valueIndex], arg = args[argIndex];
|
|
435
|
-
if (arg.tuple) {
|
|
436
|
-
this.parsedValues.push(...await this.resolveTuple(arg, valueIndex, argIndex));
|
|
437
|
-
break;
|
|
438
|
-
}
|
|
439
|
-
let matchedValue = await this.matchValue(arg, value);
|
|
440
|
-
if (matchedValue === null)
|
|
441
|
-
throw new CommandSyntaxError({
|
|
442
|
-
arg,
|
|
443
|
-
type: "INVALID_ARGUMENT" /* InvalidArgument */,
|
|
444
|
-
received: value
|
|
445
|
-
});
|
|
446
|
-
this.parsedValues.push(matchedValue), valueIndex++, argIndex++;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
async dynamicParse() {
|
|
450
|
-
let { args, values } = this.options, argIndex = 0, valueIndex = this.options.startAt + 1;
|
|
451
|
-
for (; valueIndex < values.length && argIndex < args.length; ) {
|
|
452
|
-
let value = values[valueIndex], arg = args[argIndex];
|
|
453
|
-
if (arg.tuple) {
|
|
454
|
-
this.parsedValues.push(...await this.resolveTuple(arg, valueIndex, argIndex));
|
|
455
|
-
break;
|
|
456
|
-
}
|
|
457
|
-
let matchedValue = await this.matchValue(arg, value);
|
|
458
|
-
if (matchedValue !== null)
|
|
459
|
-
this.parsedValues.push(matchedValue), valueIndex++;
|
|
460
|
-
else if (arg.required)
|
|
461
|
-
throw new CommandSyntaxError({
|
|
462
|
-
arg,
|
|
463
|
-
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
464
|
-
received: value
|
|
465
|
-
});
|
|
466
|
-
argIndex++;
|
|
467
|
-
}
|
|
468
|
-
for (; argIndex < args.length; ) {
|
|
469
|
-
let arg = args[argIndex];
|
|
470
|
-
if (arg.required)
|
|
471
|
-
throw new CommandSyntaxError({
|
|
472
|
-
arg,
|
|
473
|
-
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
474
|
-
received: "nothing"
|
|
475
|
-
});
|
|
476
|
-
argIndex++;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
async resolveTuple(arg, startIndex, argIndex) {
|
|
480
|
-
let { args } = this.options;
|
|
481
|
-
if (argIndex !== args.length - 1)
|
|
482
|
-
throw new SyntaxError("Tuple argument must be the last argument");
|
|
483
|
-
let values = [];
|
|
484
|
-
for (let rest of this.values.slice(startIndex)) {
|
|
485
|
-
let matchedValue = await this.matchValue(arg, rest);
|
|
486
|
-
if (matchedValue === null)
|
|
487
|
-
throw new CommandSyntaxError({
|
|
488
|
-
arg,
|
|
489
|
-
type: "INVALID_VARIADIC_ARGUMENT_VALUE" /* InvalidVariadicArgumentValue */,
|
|
490
|
-
received: rest
|
|
491
|
-
});
|
|
492
|
-
values.push(matchedValue);
|
|
493
|
-
}
|
|
494
|
-
if (values.length === 0 && arg.required)
|
|
495
|
-
throw new CommandSyntaxError({
|
|
496
|
-
arg,
|
|
497
|
-
type: "MISSING_REQUIRE_ARGUMENT" /* MissingRequireArgument */,
|
|
498
|
-
received: "nothing"
|
|
499
|
-
});
|
|
500
|
-
return values;
|
|
501
|
-
}
|
|
502
|
-
async matchValue(arg, value) {
|
|
503
|
-
switch (arg.type) {
|
|
504
|
-
case "user" /* User */:
|
|
505
|
-
return await this.matchUserValue(arg, value);
|
|
506
|
-
case "integer" /* Integer */:
|
|
507
|
-
return this.matchIntegerValue(arg, value);
|
|
508
|
-
case "number" /* Number */:
|
|
509
|
-
return this.matchNumberValue(arg, value);
|
|
510
|
-
case "string" /* String */:
|
|
511
|
-
return this.matchStringValue(arg, value);
|
|
512
|
-
default:
|
|
513
|
-
return null;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
async matchUserValue(arg, value) {
|
|
517
|
-
let userId = extractId(value);
|
|
518
|
-
if (!userId)
|
|
519
|
-
return null;
|
|
520
|
-
let user2 = await this.client.users.fetch(userId).catch(() => null);
|
|
521
|
-
return user2 || null;
|
|
522
|
-
}
|
|
523
|
-
matchIntegerValue(arg, value) {
|
|
524
|
-
let intVal = parseInt(value, 10);
|
|
525
|
-
return isNaN(intVal) || arg.minValue !== void 0 && intVal < arg.minValue || arg.maxValue !== void 0 && intVal > arg.maxValue ? null : intVal;
|
|
526
|
-
}
|
|
527
|
-
matchNumberValue(arg, value) {
|
|
528
|
-
let numVal = parseFloat(value);
|
|
529
|
-
return isNaN(numVal) || arg.minValue !== void 0 && numVal < arg.minValue || arg.maxValue !== void 0 && numVal > arg.maxValue ? null : numVal;
|
|
530
|
-
}
|
|
531
|
-
matchStringValue(arg, value) {
|
|
532
|
-
return arg.minLength !== void 0 && value.length < arg.minLength || arg.maxLength !== void 0 && value.length > arg.maxLength ? null : value;
|
|
533
|
-
}
|
|
534
|
-
static resolveChatInput(interaction, arg) {
|
|
535
|
-
switch (arg.type) {
|
|
536
|
-
case "string" /* String */:
|
|
537
|
-
return interaction.options.getString(arg.name, arg.required);
|
|
538
|
-
case "integer" /* Integer */:
|
|
539
|
-
return interaction.options.getInteger(arg.name, arg.required);
|
|
540
|
-
case "number" /* Number */:
|
|
541
|
-
return interaction.options.getNumber(arg.name, arg.required);
|
|
542
|
-
case "user" /* User */:
|
|
543
|
-
return interaction.options.getUser(arg.name, arg.required);
|
|
544
|
-
case "member" /* Member */:
|
|
545
|
-
return interaction.options.getMember(arg.name);
|
|
546
|
-
default:
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
var StateBox = class _StateBox {
|
|
552
|
-
static STATES_KEY = Symbol("states");
|
|
553
|
-
static storage = new AsyncLocalStorage();
|
|
554
|
-
static getState() {
|
|
555
|
-
let state = this.storage.getStore();
|
|
556
|
-
if (!state)
|
|
557
|
-
throw new Error("No active context, did you forget to wrap it with StateBox.wrap()?");
|
|
558
|
-
return state;
|
|
559
|
-
}
|
|
560
|
-
static run(fn, store2 = {}) {
|
|
561
|
-
return this.storage.run(store2, fn);
|
|
562
|
-
}
|
|
563
|
-
static wrap(fn) {
|
|
564
|
-
let currentStore = this.storage.getStore();
|
|
565
|
-
if (!currentStore)
|
|
566
|
-
throw new Error("No active context, cannot wrap function outside a StateBox.run()");
|
|
567
|
-
return () => this.run(fn, currentStore);
|
|
568
|
-
}
|
|
569
|
-
static use(defaultValue) {
|
|
570
|
-
return (target, key) => {
|
|
571
|
-
Object.defineProperty(target, key, {
|
|
572
|
-
get() {
|
|
573
|
-
let states = _StateBox.getState();
|
|
574
|
-
return key in states || (states[key] = defaultValue), states[key];
|
|
575
|
-
},
|
|
576
|
-
set(value) {
|
|
577
|
-
let states = _StateBox.getState();
|
|
578
|
-
states[key] = value;
|
|
579
|
-
},
|
|
580
|
-
enumerable: true,
|
|
581
|
-
configurable: true
|
|
582
|
-
});
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
// src/listener/ListenerEntry.ts
|
|
588
|
-
var ListenerEntry = class extends BaseEntry {
|
|
589
|
-
constructor(options) {
|
|
590
|
-
super();
|
|
591
|
-
this.options = options;
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
// src/listener/Listener.ts
|
|
596
|
-
var ListenerAPI;
|
|
597
|
-
((ListenerAPI2) => {
|
|
598
|
-
let entries = /* @__PURE__ */ new WeakMap();
|
|
599
|
-
function use(entry) {
|
|
600
|
-
return (target) => {
|
|
601
|
-
entries.set(target, entry);
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
ListenerAPI2.use = use;
|
|
605
|
-
function getEntry(target) {
|
|
606
|
-
return entries.get(target);
|
|
607
|
-
}
|
|
608
|
-
ListenerAPI2.getEntry = getEntry;
|
|
609
|
-
})(ListenerAPI ||= {});
|
|
610
|
-
function ListenerFactory(options) {
|
|
611
|
-
let fullOptions = typeof options != "object" ? { name: options, once: false } : { once: false, ...options };
|
|
612
|
-
return new ListenerEntry(fullOptions);
|
|
613
|
-
}
|
|
614
|
-
var Listener = Object.assign(ListenerFactory, ListenerAPI);
|
|
615
|
-
var ListenerRegistry = class {
|
|
616
|
-
static client;
|
|
617
|
-
static constructors = /* @__PURE__ */ new Set();
|
|
618
|
-
static instances = /* @__PURE__ */ new WeakMap();
|
|
619
|
-
static executors = /* @__PURE__ */ new WeakMap();
|
|
620
|
-
/**
|
|
621
|
-
* Add and register a listener to the registry.
|
|
622
|
-
* If `options.emitter` is not provided, the registry will use the base `client` by default.
|
|
623
|
-
* @param constructor The listener class you want to add.
|
|
624
|
-
*/
|
|
625
|
-
static add(constructor) {
|
|
626
|
-
let entry = Listener.getEntry(constructor);
|
|
627
|
-
if (!entry)
|
|
628
|
-
throw new Error(`No entry found for "${constructor.name}"`);
|
|
629
|
-
let { options } = entry;
|
|
630
|
-
if (!options.emitter) {
|
|
631
|
-
if (!this.client)
|
|
632
|
-
throw new Error("Client is not ready.");
|
|
633
|
-
options.emitter = this.client;
|
|
634
|
-
}
|
|
635
|
-
let instance = new constructor(), executor = this.createExecutor(constructor, instance);
|
|
636
|
-
this.constructors.add(constructor), this.instances.set(constructor, instance), this.executors.set(instance, executor), options.emitter[options.once ? "once" : "on"](options.name, (...args) => {
|
|
637
|
-
executor(...args);
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
|
-
* Remove and unregister a listener from the registry.
|
|
642
|
-
* @param constructor The listener class you want to remove.
|
|
643
|
-
* @returns `boolean`, returns `true` if the listener is removed successfully.
|
|
644
|
-
*/
|
|
645
|
-
static remove(constructor) {
|
|
646
|
-
let entry = Listener.getEntry(constructor);
|
|
647
|
-
if (!entry)
|
|
648
|
-
return false;
|
|
649
|
-
this.constructors.delete(constructor);
|
|
650
|
-
let instance = this.instances.get(constructor);
|
|
651
|
-
if (!instance)
|
|
652
|
-
return false;
|
|
653
|
-
this.instances.delete(constructor);
|
|
654
|
-
let executor = this.executors.get(instance);
|
|
655
|
-
if (!executor)
|
|
656
|
-
return false;
|
|
657
|
-
let { name, emitter } = entry.options;
|
|
658
|
-
return emitter?.removeListener(name, executor), this.executors.delete(instance), true;
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Remove and unregister all listeners from the registry.
|
|
662
|
-
* @returns Amount of removed listeners.
|
|
663
|
-
*/
|
|
664
|
-
static removeAll() {
|
|
665
|
-
let removedAmount = 0;
|
|
666
|
-
for (let constructor of this.constructors)
|
|
667
|
-
this.remove(constructor) && removedAmount++;
|
|
668
|
-
return removedAmount;
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* Set base client for the registry to fallback as default emitter. This should be used only by BakitClient and stay untouched.
|
|
672
|
-
* @param newClient base client to set for the registry.
|
|
673
|
-
*/
|
|
674
|
-
static setClient(newClient) {
|
|
675
|
-
this.client = newClient;
|
|
676
|
-
}
|
|
677
|
-
static createExecutor(constructor, instance) {
|
|
678
|
-
let entry = Listener.getEntry(constructor);
|
|
679
|
-
if (!entry)
|
|
680
|
-
throw new Error("Missing listener entry");
|
|
681
|
-
let { hooks } = entry;
|
|
682
|
-
return async function(...args) {
|
|
683
|
-
let mainHook = hooks.MAIN, preHook = hooks.PRE, postHook = hooks.POST, errorHook = hooks.ERROR;
|
|
684
|
-
if (mainHook)
|
|
685
|
-
try {
|
|
686
|
-
preHook && await preHook.method.call(instance, ...args), await mainHook.method.call(instance, ...args), postHook && await postHook.method.call(instance, ...args);
|
|
687
|
-
} catch (error) {
|
|
688
|
-
if (errorHook)
|
|
689
|
-
await errorHook.method.call(
|
|
690
|
-
instance,
|
|
691
|
-
error,
|
|
692
|
-
...args
|
|
693
|
-
);
|
|
694
|
-
else
|
|
695
|
-
throw error;
|
|
696
|
-
}
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
/**
|
|
700
|
-
* Load and add all listeners which matched provided glob pattern to the registry.
|
|
701
|
-
* @param pattern glob pattern to load.
|
|
702
|
-
* @param parallel load all matched results in parallel, enabled by default.
|
|
703
|
-
* @returns All loaded listener constructors.
|
|
704
|
-
*/
|
|
705
|
-
static async load(pattern, parallel = true) {
|
|
706
|
-
let loaders = (await glob(pattern)).map(async (file) => {
|
|
707
|
-
let fileURL = pathToFileURL(file).toString(), { default: constructor } = await import(fileURL);
|
|
708
|
-
return this.add(constructor), constructor;
|
|
709
|
-
});
|
|
710
|
-
if (parallel)
|
|
711
|
-
return Promise.all(loaders);
|
|
712
|
-
let result = [];
|
|
713
|
-
for (let loader of loaders)
|
|
714
|
-
result.push(await loader);
|
|
715
|
-
return result;
|
|
716
|
-
}
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
// src/BakitClient.ts
|
|
720
|
-
var BakitClient = class _BakitClient extends Client {
|
|
721
|
-
constructor(options) {
|
|
722
|
-
options.getSyntaxErrorMessage === void 0 && (options.getSyntaxErrorMessage = _BakitClient.getSyntaxErrorMessage), super(options), ListenerRegistry.setClient(this), this.once(
|
|
723
|
-
Events.ClientReady,
|
|
724
|
-
(client) => void this.registerApplicationCommands(client)
|
|
725
|
-
), this.on(Events.InteractionCreate, (interaction) => void this.handleInteraction(interaction)), this.on(Events.MessageCreate, (message) => void this.handleMessage(message));
|
|
726
|
-
}
|
|
727
|
-
static getSyntaxErrorMessage = (command, error, context, args, prefix) => {
|
|
728
|
-
let requiredSyntax = args.map((x) => Arg.format(x)).join(" "), root = Command.getRoot(command.constructor);
|
|
729
|
-
return root ? {
|
|
730
|
-
content: [
|
|
731
|
-
codeBlock(error.message),
|
|
732
|
-
"Required Syntax:",
|
|
733
|
-
codeBlock(`${prefix}${root.options.name} ${requiredSyntax}`)
|
|
734
|
-
].join(`
|
|
735
|
-
`)
|
|
736
|
-
} : void 0;
|
|
737
|
-
};
|
|
738
|
-
async registerApplicationCommands(client) {
|
|
739
|
-
let commands = CommandRegistry.constructors.map((c) => CommandRegistry.buildSlashCommand(c));
|
|
740
|
-
await client.application.commands.set(commands);
|
|
741
|
-
}
|
|
742
|
-
async handleMessage(message) {
|
|
743
|
-
if (message.author.bot)
|
|
744
|
-
return;
|
|
745
|
-
let context = new MessageContext(message), resolver = ArgumentResolver.create(message);
|
|
746
|
-
if (!resolver)
|
|
747
|
-
return;
|
|
748
|
-
let { trigger } = resolver, command = CommandRegistry.instances.get(trigger);
|
|
749
|
-
command && await StateBox.run(() => this.handleMessageHooks(context, command, resolver));
|
|
750
|
-
}
|
|
751
|
-
async handleInteraction(interaction) {
|
|
752
|
-
if (!interaction.isChatInputCommand())
|
|
753
|
-
return;
|
|
754
|
-
let { commandName } = interaction, command = CommandRegistry.instances.get(commandName);
|
|
755
|
-
if (!command)
|
|
756
|
-
return;
|
|
757
|
-
let context = new ChatInputContext(interaction);
|
|
758
|
-
await StateBox.run(() => this.handleChatInputHooks(context, command));
|
|
759
|
-
}
|
|
760
|
-
async handleChatInputHooks(context, instance) {
|
|
761
|
-
let targetHooks = this.getChatInputTargetHooks(context.source, instance), inheritedArgs = [];
|
|
762
|
-
for (let hooks of [targetHooks.root, targetHooks.group, targetHooks.subcommand]) {
|
|
763
|
-
if (!hooks)
|
|
764
|
-
continue;
|
|
765
|
-
let newArgs = await this.runChatInputHooks(context, instance, hooks, inheritedArgs);
|
|
766
|
-
newArgs && (inheritedArgs = newArgs);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
async handleMessageHooks(context, instance, resolver) {
|
|
770
|
-
if (!resolver)
|
|
771
|
-
return;
|
|
772
|
-
let root = Command.getRoot(instance.constructor);
|
|
773
|
-
root && (resolver = await this.runMessageHooks(context, instance, root.hooks, resolver), resolver && await this.handleChildMessageHooks(context, root, instance, resolver));
|
|
774
|
-
}
|
|
775
|
-
async handleChildMessageHooks(context, parent, instance, resolver, skip = 1) {
|
|
776
|
-
if (!resolver)
|
|
777
|
-
return;
|
|
778
|
-
let usedValues = resolver.parsedValues.length, nextTrigger = resolver.values[usedValues + skip], child = parent.children.get(nextTrigger);
|
|
779
|
-
child && (resolver = await this.runMessageHooks(context, instance, child.hooks, resolver), child instanceof CommandGroupEntry && await this.handleChildMessageHooks(context, child, instance, resolver, skip + 1));
|
|
780
|
-
}
|
|
781
|
-
async runMessageHooks(context, instance, hooks, resolver) {
|
|
782
|
-
let mainHook = hooks.MAIN;
|
|
783
|
-
if (!mainHook)
|
|
784
|
-
return resolver;
|
|
785
|
-
let args = Arg.getMethodArguments(mainHook.method);
|
|
786
|
-
try {
|
|
787
|
-
resolver = await resolver.resolve(args);
|
|
788
|
-
} catch (error) {
|
|
789
|
-
if (error instanceof CommandSyntaxError) {
|
|
790
|
-
let errorContent = await this.options.getSyntaxErrorMessage?.(
|
|
791
|
-
instance,
|
|
792
|
-
error,
|
|
793
|
-
context,
|
|
794
|
-
args,
|
|
795
|
-
resolver.options.prefix
|
|
796
|
-
);
|
|
797
|
-
return errorContent && await context.send(errorContent), null;
|
|
798
|
-
}
|
|
799
|
-
throw error;
|
|
800
|
-
}
|
|
801
|
-
return await this.runHooks(context, instance, hooks, resolver.parsedValues), resolver;
|
|
802
|
-
}
|
|
803
|
-
async runChatInputHooks(context, instance, hooks, inheritedArgs) {
|
|
804
|
-
let mainHook = hooks.MAIN;
|
|
805
|
-
if (!mainHook)
|
|
806
|
-
return;
|
|
807
|
-
let newArgs = Arg.getMethodArguments(mainHook.method).map(
|
|
808
|
-
(arg) => ArgumentResolver.resolveChatInput(context.source, arg)
|
|
809
|
-
), argValues = [...inheritedArgs, ...newArgs];
|
|
810
|
-
return await this.runHooks(context, instance, hooks, argValues), argValues;
|
|
811
|
-
}
|
|
812
|
-
async runHooks(context, instance, hooks, args) {
|
|
813
|
-
let mainHook = hooks.MAIN, preHook = hooks.PRE, postHook = hooks.POST, errorHook = hooks.ERROR;
|
|
814
|
-
if (!mainHook)
|
|
815
|
-
return;
|
|
816
|
-
let execute = async (hook, error) => {
|
|
817
|
-
hook && (hook.state === "ERROR" /* Error */ ? await hook.method.call(instance, error, context, ...args) : await hook.method.call(instance, context, ...args));
|
|
818
|
-
};
|
|
819
|
-
try {
|
|
820
|
-
await execute(preHook), await execute(mainHook), await execute(postHook);
|
|
821
|
-
} catch (error) {
|
|
822
|
-
if (errorHook)
|
|
823
|
-
await execute(errorHook, error);
|
|
824
|
-
else
|
|
825
|
-
throw error;
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
getChatInputTargetHooks(interaction, instance) {
|
|
829
|
-
let subcommandName = interaction.options.getSubcommand(false), groupName = interaction.options.getSubcommandGroup(false), root = Command.getRoot(instance.constructor);
|
|
830
|
-
if (!root)
|
|
831
|
-
throw new Error("No root found.");
|
|
832
|
-
let group;
|
|
833
|
-
if (groupName) {
|
|
834
|
-
let child = root.children.get(groupName);
|
|
835
|
-
child instanceof CommandGroupEntry && (group = child);
|
|
836
|
-
}
|
|
837
|
-
let subcommand;
|
|
838
|
-
if (subcommandName) {
|
|
839
|
-
let child = (group || root).children.get(subcommandName);
|
|
840
|
-
child instanceof SubcommandEntry && (subcommand = child);
|
|
841
|
-
}
|
|
842
|
-
return {
|
|
843
|
-
root: root.hooks,
|
|
844
|
-
group: group?.hooks,
|
|
845
|
-
subcommand: subcommand?.hooks
|
|
846
|
-
};
|
|
847
816
|
}
|
|
848
817
|
};
|
|
849
818
|
|
|
850
|
-
export { Arg, ArgumentType, BakitClient, BaseCommandEntry, BaseCommandGroupEntry, BaseContext, ChatInputContext, Command, CommandAPI, CommandFactory, CommandGroupEntry, CommandRegistry, CommandSyntaxError, CommandSyntaxErrorType, Listener, ListenerAPI, ListenerEntry, ListenerFactory, ListenerRegistry, MessageContext, RootCommandEntry, StateBox, SubcommandEntry, extractId };
|
|
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 };
|