stoatx 0.2.1 → 0.4.0

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { Client, Message } from 'stoat.js';
1
+ import { Client as Client$1, Message } from 'stoat.js';
2
2
 
3
3
  /**
4
4
  * Permission types for commands
@@ -44,7 +44,7 @@ interface CommandMetadata {
44
44
  */
45
45
  interface CommandContext {
46
46
  /** The client instance */
47
- client: Client;
47
+ client: Client$1;
48
48
  /** The raw message content */
49
49
  content: string;
50
50
  /** The author ID */
@@ -60,7 +60,7 @@ interface CommandContext {
60
60
  /** The command name used (could be an alias) */
61
61
  commandName: string;
62
62
  /** Reply to the message */
63
- reply: (content: string) => Promise<void>;
63
+ reply: (content: string) => Promise<Message>;
64
64
  /** The original message object (platform-specific) */
65
65
  message: Message;
66
66
  }
@@ -73,14 +73,14 @@ interface StoatLifecycle {
73
73
  /** Optional: Called when a cooldown is active */
74
74
  onCooldown?(ctx: CommandContext, remaining: number): Promise<void>;
75
75
  }
76
- interface MallyGuard {
76
+ interface StoatxGuard {
77
77
  run(ctx: CommandContext): Promise<boolean> | boolean;
78
78
  guardFail?(ctx: CommandContext): Promise<void> | void;
79
79
  }
80
80
  /**
81
81
  * Discovery options for automatic command module loading
82
82
  */
83
- interface MallyDiscoveryOptions {
83
+ interface StoatxDiscoveryOptions {
84
84
  /** Root directories to scan (default: [process.cwd()]) */
85
85
  roots?: string[];
86
86
  /** Glob patterns relative to each root */
@@ -91,13 +91,13 @@ interface MallyDiscoveryOptions {
91
91
  /**
92
92
  * Handler options
93
93
  */
94
- interface MallyHandlerOptions {
94
+ interface StoatxHandlerOptions {
95
95
  /** The client instance */
96
- client: Client;
96
+ client: Client$1;
97
97
  /** Directory to scan for command modules (absolute path) */
98
98
  commandsDir?: string;
99
99
  /** Auto-discovery options used when commandsDir is not provided */
100
- discovery?: MallyDiscoveryOptions;
100
+ discovery?: StoatxDiscoveryOptions;
101
101
  /** Command prefix or prefix resolver function */
102
102
  prefix: string | ((ctx: {
103
103
  serverId?: string;
@@ -183,7 +183,7 @@ declare function getSimpleCommands(target: Function): SimpleCommandDefinition[];
183
183
  * import { Guard, Stoat, SimpleCommand, CommandContext } from 'stoatx';
184
184
  *
185
185
  * // Define a guard
186
- * class NotBot implements MallyGuard {
186
+ * class NotBot implements StoatxGuard {
187
187
  * run(ctx: CommandContext): boolean {
188
188
  * return !ctx.message.author.bot;
189
189
  * }
@@ -209,6 +209,60 @@ declare function Guard(guardClass: Function): ClassDecorator;
209
209
  */
210
210
  declare function getGuards(target: Function): Function[];
211
211
 
212
+ interface EventDefinition {
213
+ methodName: string;
214
+ event: string;
215
+ type: "on" | "once";
216
+ }
217
+ /**
218
+ * @On
219
+ * Triggered on every occurrence of the event.
220
+ * Marks a method to be executed whenever the specified client event is emitted.
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import { Stoat, On } from 'stoatx';
225
+ * import { Message, Client } from 'stoat.js';
226
+ *
227
+ * @Stoat()
228
+ * class BotEvents {
229
+ * @On('messageCreate')
230
+ * async onMessage(message: Message, client: Client) {
231
+ * console.log('New message received:', message.content);
232
+ * }
233
+ * }
234
+ * ```
235
+ *
236
+ * @param event The name of the client event to listen to
237
+ */
238
+ declare function On(event: string): MethodDecorator;
239
+ /**
240
+ * @Once
241
+ * Triggered only fully once.
242
+ * Marks a method to be executed only the FIRST time the specified client event is emitted.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * import { Stoat, Once } from 'stoatx';
247
+ * import { Client } from 'stoat.js';
248
+ *
249
+ * @Stoat()
250
+ * class BotEvents {
251
+ * @Once('ready')
252
+ * async onReady(client: Client) {
253
+ * console.log('Bot successfully started and logged in!');
254
+ * }
255
+ * }
256
+ * ```
257
+ *
258
+ * @param event The name of the client event to listen to
259
+ */
260
+ declare function Once(event: string): MethodDecorator;
261
+ /**
262
+ * Get all event definitions from a @Stoat class
263
+ */
264
+ declare function getEventsMetadata(target: Function): EventDefinition[];
265
+
212
266
  /**
213
267
  * Build CommandMetadata from SimpleCommandOptions
214
268
  */
@@ -220,7 +274,8 @@ declare function buildSimpleCommandMetadata(options: SimpleCommandOptions, metho
220
274
  declare const METADATA_KEYS: {
221
275
  readonly IS_STOAT_CLASS: symbol;
222
276
  readonly SIMPLE_COMMANDS: symbol;
223
- readonly GUARDS: "mally:command:guards";
277
+ readonly GUARDS: "stoatx:command:guards";
278
+ readonly EVENTS: symbol;
224
279
  };
225
280
 
226
281
  interface AutoDiscoveryOptions {
@@ -241,6 +296,15 @@ interface RegisteredCommand {
241
296
  /** The original class constructor (for guard validation) */
242
297
  classConstructor: Function;
243
298
  }
299
+ /**
300
+ * Stored event entry from @On/@Once registration.
301
+ */
302
+ interface RegisteredEvent {
303
+ instance: object;
304
+ methodName: string;
305
+ event: string;
306
+ type: "on" | "once";
307
+ }
244
308
  /**
245
309
  * CommandRegistry - Scans directories and stores commands in a Map
246
310
  *
@@ -257,6 +321,7 @@ declare class CommandRegistry {
257
321
  private static readonly DEFAULT_AUTO_DISCOVERY_IGNORES;
258
322
  private readonly commands;
259
323
  private readonly aliases;
324
+ private readonly registeredEvents;
260
325
  private readonly extensions;
261
326
  private readonly processedStoatClasses;
262
327
  constructor(extensions?: string[]);
@@ -294,6 +359,10 @@ declare class CommandRegistry {
294
359
  * Get all command metadata
295
360
  */
296
361
  getAllMetadata(): CommandMetadata[];
362
+ /**
363
+ * Get all registered events
364
+ */
365
+ getEvents(): RegisteredEvent[];
297
366
  /**
298
367
  * Get commands grouped by category
299
368
  */
@@ -333,44 +402,53 @@ declare class CommandRegistry {
333
402
  }
334
403
 
335
404
  /**
336
- * MallyHandler - The execution engine for commands
337
- *
338
- * Handles message parsing, middleware execution, and command dispatching
405
+ * Client - An extended Client that integrates StoatxHandler directly
339
406
  *
340
407
  * @example
341
408
  * ```ts
342
- * import { MallyHandler } from 'stoatx';
343
- * import { Client } from 'stoat.js';
344
- *
345
- * const client = new Client();
409
+ * import { Client } from 'stoatx';
346
410
  *
347
- * const handler = new MallyHandler({
348
- * client,
411
+ * const client = new Client({
349
412
  * prefix: '!',
350
413
  * owners: ['owner-user-id'],
351
414
  * });
352
415
  *
353
- * await handler.init();
354
- *
355
- * client.on('message', (message) => {
356
- * handler.handleMessage(message);
357
- * });
416
+ * await client.initCommands();
358
417
  * ```
359
418
  */
360
- declare class MallyHandler {
361
- private readonly commandsDir?;
362
- private readonly discoveryOptions?;
419
+ declare class Client extends Client$1 {
420
+ readonly handler: StoatxHandler;
421
+ constructor(options: Omit<StoatxHandlerOptions, "client">);
422
+ /**
423
+ * Initialize the StoatxHandler commands
424
+ */
425
+ initCommands(): Promise<void>;
426
+ }
427
+ /**
428
+ * StoatxHandler - The execution engine for commands
429
+ *
430
+ * Handles message parsing, middleware execution, and command dispatching
431
+ *
432
+ * @internal This class is not intended to be instantiated directly. Use the `Client` from `stoatx` instead.
433
+ */
434
+ declare class StoatxHandler {
435
+ private readonly commandsDir;
436
+ private readonly discoveryOptions;
363
437
  private readonly prefixResolver;
364
438
  private readonly owners;
365
439
  private readonly registry;
366
440
  private readonly cooldowns;
367
441
  private readonly disableMentionPrefix;
368
442
  private readonly client;
369
- constructor(options: MallyHandlerOptions);
443
+ constructor(options: StoatxHandlerOptions);
370
444
  /**
371
445
  * Initialize the handler - load all commands
372
446
  */
373
447
  init(): Promise<void>;
448
+ /**
449
+ * Attach registered events to the client
450
+ */
451
+ private attachEvents;
374
452
  /**
375
453
  * Parse a raw message into command context
376
454
  */
@@ -378,7 +456,7 @@ declare class MallyHandler {
378
456
  authorId: string;
379
457
  channelId: string;
380
458
  serverId?: string;
381
- reply: (content: string) => Promise<void>;
459
+ reply: (content: string) => Promise<Message>;
382
460
  }): Promise<CommandContext | null>;
383
461
  /**
384
462
  * Handle a message object using the configured message adapter
@@ -412,7 +490,7 @@ declare class MallyHandler {
412
490
  authorId: string;
413
491
  channelId: string;
414
492
  serverId?: string;
415
- reply: (content: string) => Promise<void>;
493
+ reply: (content: string) => Promise<Message>;
416
494
  }): Promise<boolean>;
417
495
  /**
418
496
  * Execute a command with the given context
@@ -464,4 +542,4 @@ declare class MallyHandler {
464
542
  private setCooldown;
465
543
  }
466
544
 
467
- export { type CommandContext, type CommandMetadata, CommandRegistry, type CommandContext as Context, Guard, METADATA_KEYS, type MallyDiscoveryOptions, type MallyGuard, MallyHandler, type MallyHandlerOptions, type Permission, type RegisteredCommand, SimpleCommand, type SimpleCommandDefinition, type SimpleCommandOptions, Stoat, type StoatLifecycle, buildSimpleCommandMetadata, getGuards, getSimpleCommands, isStoatClass };
545
+ export { Client, type CommandContext, type CommandMetadata, CommandRegistry, type EventDefinition, Guard, METADATA_KEYS, On, Once, type Permission, type RegisteredCommand, type RegisteredEvent, SimpleCommand, type SimpleCommandDefinition, type SimpleCommandOptions, Stoat, type StoatLifecycle, type StoatxDiscoveryOptions, type StoatxGuard, StoatxHandler, type StoatxHandlerOptions, buildSimpleCommandMetadata, getEventsMetadata, getGuards, getSimpleCommands, isStoatClass };
package/dist/index.js CHANGED
@@ -30,13 +30,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ Client: () => Client,
33
34
  CommandRegistry: () => CommandRegistry,
34
35
  Guard: () => Guard,
35
36
  METADATA_KEYS: () => METADATA_KEYS,
36
- MallyHandler: () => MallyHandler,
37
+ On: () => On,
38
+ Once: () => Once,
37
39
  SimpleCommand: () => SimpleCommand,
38
40
  Stoat: () => Stoat,
39
41
  buildSimpleCommandMetadata: () => buildSimpleCommandMetadata,
42
+ getEventsMetadata: () => getEventsMetadata,
40
43
  getGuards: () => getGuards,
41
44
  getSimpleCommands: () => getSimpleCommands,
42
45
  isStoatClass: () => isStoatClass
@@ -48,9 +51,10 @@ var import_reflect_metadata = require("reflect-metadata");
48
51
 
49
52
  // src/decorators/keys.ts
50
53
  var METADATA_KEYS = {
51
- IS_STOAT_CLASS: /* @__PURE__ */ Symbol("mally:stoat:isClass"),
52
- SIMPLE_COMMANDS: /* @__PURE__ */ Symbol("mally:stoat:simpleCommands"),
53
- GUARDS: "mally:command:guards"
54
+ IS_STOAT_CLASS: /* @__PURE__ */ Symbol("stoatx:stoat:isClass"),
55
+ SIMPLE_COMMANDS: /* @__PURE__ */ Symbol("stoatx:stoat:simpleCommands"),
56
+ GUARDS: "stoatx:command:guards",
57
+ EVENTS: /* @__PURE__ */ Symbol("stoatx:stoat:events")
54
58
  };
55
59
 
56
60
  // src/decorators/store.ts
@@ -161,6 +165,31 @@ function getGuards(target) {
161
165
  return Reflect.getMetadata(METADATA_KEYS.GUARDS, target) || [];
162
166
  }
163
167
 
168
+ // src/decorators/Events.ts
169
+ var import_reflect_metadata4 = require("reflect-metadata");
170
+ function createEventDecorator(event, type) {
171
+ return (target, propertyKey, descriptor) => {
172
+ const constructor = target.constructor;
173
+ const existingEvents = Reflect.getMetadata(METADATA_KEYS.EVENTS, constructor) || [];
174
+ existingEvents.push({
175
+ methodName: String(propertyKey),
176
+ event,
177
+ type
178
+ });
179
+ Reflect.defineMetadata(METADATA_KEYS.EVENTS, existingEvents, constructor);
180
+ return descriptor;
181
+ };
182
+ }
183
+ function On(event) {
184
+ return createEventDecorator(event, "on");
185
+ }
186
+ function Once(event) {
187
+ return createEventDecorator(event, "once");
188
+ }
189
+ function getEventsMetadata(target) {
190
+ return Reflect.getMetadata(METADATA_KEYS.EVENTS, target) || [];
191
+ }
192
+
164
193
  // src/decorators/utils.ts
165
194
  function buildSimpleCommandMetadata(options, methodName, category) {
166
195
  return {
@@ -184,6 +213,7 @@ var _CommandRegistry = class _CommandRegistry {
184
213
  constructor(extensions = [".js", ".mjs", ".cjs"]) {
185
214
  this.commands = /* @__PURE__ */ new Map();
186
215
  this.aliases = /* @__PURE__ */ new Map();
216
+ this.registeredEvents = [];
187
217
  this.processedStoatClasses = /* @__PURE__ */ new Set();
188
218
  this.extensions = extensions;
189
219
  }
@@ -207,7 +237,7 @@ var _CommandRegistry = class _CommandRegistry {
207
237
  await this.loadFile(file, directory);
208
238
  }
209
239
  }
210
- console.log(`[Mally] Loaded ${this.commands.size} command(s)`);
240
+ console.log(`[Stoatx] Loaded ${this.commands.size} command(s) and ${this.registeredEvents.length} event(s)`);
211
241
  }
212
242
  /**
213
243
  * Auto-discover command files across one or more roots.
@@ -235,7 +265,7 @@ var _CommandRegistry = class _CommandRegistry {
235
265
  }) ?? roots[0];
236
266
  await this.loadFile(file, baseDir);
237
267
  }
238
- console.log(`[Mally] Auto-discovered ${candidateFiles} candidate file(s), loaded ${this.commands.size} command(s)`);
268
+ console.log(`[Stoatx] Loaded ${this.commands.size} command(s) and ${this.registeredEvents.length} event(s)`);
239
269
  }
240
270
  getDefaultAutoDiscoveryPatterns() {
241
271
  return this.extensions.map((ext) => `**/*${ext}`);
@@ -243,7 +273,7 @@ var _CommandRegistry = class _CommandRegistry {
243
273
  async isLikelyCommandModule(filePath) {
244
274
  try {
245
275
  const source = await fs.readFile(filePath, "utf8");
246
- return source.includes("Stoat") || source.includes("SimpleCommand") || source.includes("Command") || source.includes("mally:command");
276
+ return source.includes("Stoat") || source.includes("SimpleCommand") || source.includes("Command") || source.includes("stoatx:command");
247
277
  } catch {
248
278
  return true;
249
279
  }
@@ -254,7 +284,7 @@ var _CommandRegistry = class _CommandRegistry {
254
284
  register(instance, metadata, classConstructor, methodName) {
255
285
  const name = metadata.name.toLowerCase();
256
286
  if (this.commands.has(name)) {
257
- console.warn(`[Mally] Duplicate command name: ${name}. Skipping...`);
287
+ console.warn(`[Stoatx] Duplicate command name: ${name}. Skipping...`);
258
288
  return;
259
289
  }
260
290
  this.validateGuards(classConstructor, metadata.name);
@@ -262,7 +292,7 @@ var _CommandRegistry = class _CommandRegistry {
262
292
  for (const alias of metadata.aliases) {
263
293
  const aliasLower = alias.toLowerCase();
264
294
  if (this.aliases.has(aliasLower) || this.commands.has(aliasLower)) {
265
- console.warn(`[Mally] Duplicate alias: ${aliasLower}. Skipping...`);
295
+ console.warn(`[Stoatx] Duplicate alias: ${aliasLower}. Skipping...`);
266
296
  continue;
267
297
  }
268
298
  this.aliases.set(aliasLower, name);
@@ -295,6 +325,12 @@ var _CommandRegistry = class _CommandRegistry {
295
325
  getAllMetadata() {
296
326
  return this.getAll().map((c) => c.metadata);
297
327
  }
328
+ /**
329
+ * Get all registered events
330
+ */
331
+ getEvents() {
332
+ return this.registeredEvents;
333
+ }
298
334
  /**
299
335
  * Get commands grouped by category
300
336
  */
@@ -314,6 +350,7 @@ var _CommandRegistry = class _CommandRegistry {
314
350
  clear() {
315
351
  this.commands.clear();
316
352
  this.aliases.clear();
353
+ this.registeredEvents.length = 0;
317
354
  this.processedStoatClasses.clear();
318
355
  }
319
356
  /**
@@ -341,20 +378,20 @@ var _CommandRegistry = class _CommandRegistry {
341
378
  * @private
342
379
  */
343
380
  validateGuards(commandClass, commandName) {
344
- const guards = Reflect.getMetadata("mally:command:guards", commandClass) || [];
381
+ const guards = Reflect.getMetadata("stoatx:command:guards", commandClass) || [];
345
382
  for (const GuardClass of guards) {
346
383
  const guardInstance = new GuardClass();
347
384
  if (typeof guardInstance.run !== "function") {
348
385
  console.error(
349
- `[Mally] FATAL: Guard "${GuardClass.name}" on command "${commandName}" does not have a run() method.`
386
+ `[Stoatx] FATAL: Guard "${GuardClass.name}" on command "${commandName}" does not have a run() method.`
350
387
  );
351
388
  process.exit(1);
352
389
  }
353
390
  if (typeof guardInstance.guardFail !== "function") {
354
391
  console.error(
355
- `[Mally] FATAL: Guard "${GuardClass.name}" on command "${commandName}" does not have a guardFail() method.`
392
+ `[Stoatx] FATAL: Guard "${GuardClass.name}" on command "${commandName}" does not have a guardFail() method.`
356
393
  );
357
- console.error(`[Mally] All guards must implement guardFail() to handle failed checks.`);
394
+ console.error(`[Stoatx] All guards must implement guardFail() to handle failed checks.`);
358
395
  process.exit(1);
359
396
  }
360
397
  }
@@ -375,15 +412,16 @@ var _CommandRegistry = class _CommandRegistry {
375
412
  this.registerStoatClassCommands(stoatClass, stoatInstance, filePath, baseDir);
376
413
  }
377
414
  } catch (error) {
378
- console.error(`[Mally] Failed to load command file: ${filePath}`, error);
415
+ console.error(`[Stoatx] Failed to load command file: ${filePath}`, error);
379
416
  }
380
417
  }
381
418
  registerStoatClassCommands(stoatClass, instance, filePath, baseDir) {
382
419
  const simpleCommands = getSimpleCommands(stoatClass);
420
+ const events = getEventsMetadata(stoatClass);
383
421
  const category = this.getCategoryFromPath(filePath, baseDir);
384
- if (simpleCommands.length === 0) {
422
+ if (simpleCommands.length === 0 && events.length === 0) {
385
423
  console.warn(
386
- `[Mally] Class ${stoatClass.name} is decorated with @Stoat but has no @SimpleCommand methods. Skipping...`
424
+ `[Stoatx] Class ${stoatClass.name} is decorated with @Stoat but has no @SimpleCommand, @On or @Once methods. Skipping...`
387
425
  );
388
426
  this.processedStoatClasses.add(stoatClass);
389
427
  return;
@@ -391,12 +429,25 @@ var _CommandRegistry = class _CommandRegistry {
391
429
  for (const cmdDef of simpleCommands) {
392
430
  const method = instance[cmdDef.methodName];
393
431
  if (typeof method !== "function") {
394
- console.warn(`[Mally] Method ${cmdDef.methodName} not found on ${stoatClass.name}. Skipping...`);
432
+ console.warn(`[Stoatx] Method ${cmdDef.methodName} not found on ${stoatClass.name}. Skipping...`);
395
433
  continue;
396
434
  }
397
435
  const metadata = buildSimpleCommandMetadata(cmdDef.options, cmdDef.methodName, category);
398
436
  this.register(instance, metadata, stoatClass, cmdDef.methodName);
399
437
  }
438
+ for (const eventDef of events) {
439
+ const method = instance[eventDef.methodName];
440
+ if (typeof method !== "function") {
441
+ console.warn(`[Stoatx] Method ${eventDef.methodName} not found on ${stoatClass.name}. Skipping...`);
442
+ continue;
443
+ }
444
+ this.registeredEvents.push({
445
+ instance,
446
+ methodName: eventDef.methodName,
447
+ event: eventDef.event,
448
+ type: eventDef.type
449
+ });
450
+ }
400
451
  this.processedStoatClasses.add(stoatClass);
401
452
  }
402
453
  /**
@@ -421,8 +472,24 @@ _CommandRegistry.DEFAULT_AUTO_DISCOVERY_IGNORES = [
421
472
  var CommandRegistry = _CommandRegistry;
422
473
 
423
474
  // src/handler.ts
424
- var import_reflect_metadata4 = require("reflect-metadata");
425
- var MallyHandler = class {
475
+ var import_reflect_metadata5 = require("reflect-metadata");
476
+ var import_stoat = require("stoat.js");
477
+ var Client = class extends import_stoat.Client {
478
+ constructor(options) {
479
+ super();
480
+ this.handler = new StoatxHandler({ ...options, client: this });
481
+ this.on("messageCreate", async (message) => {
482
+ await this.handler.handle(message);
483
+ });
484
+ }
485
+ /**
486
+ * Initialize the StoatxHandler commands
487
+ */
488
+ async initCommands() {
489
+ await this.handler.init();
490
+ }
491
+ };
492
+ var StoatxHandler = class {
426
493
  constructor(options) {
427
494
  this.cooldowns = /* @__PURE__ */ new Map();
428
495
  this.client = options.client;
@@ -439,9 +506,33 @@ var MallyHandler = class {
439
506
  async init() {
440
507
  if (this.commandsDir) {
441
508
  await this.registry.loadFromDirectory(this.commandsDir);
442
- return;
509
+ } else {
510
+ await this.registry.autoDiscover(this.discoveryOptions);
511
+ }
512
+ this.attachEvents();
513
+ }
514
+ /**
515
+ * Attach registered events to the client
516
+ */
517
+ attachEvents() {
518
+ const events = this.registry.getEvents();
519
+ for (const eventDef of events) {
520
+ const handler = async (...args) => {
521
+ try {
522
+ await eventDef.instance[eventDef.methodName](...args, this.client);
523
+ } catch (error) {
524
+ console.error(
525
+ `[Stoatx] Event Handler Error in @${eventDef.type === "on" ? "On" : "Once"}('${eventDef.event}'):`,
526
+ error
527
+ );
528
+ }
529
+ };
530
+ if (eventDef.type === "once") {
531
+ this.client.once(eventDef.event, handler);
532
+ } else {
533
+ this.client.on(eventDef.event, handler);
534
+ }
443
535
  }
444
- await this.registry.autoDiscover(this.discoveryOptions);
445
536
  }
446
537
  /**
447
538
  * Parse a raw message into command context
@@ -508,7 +599,7 @@ var MallyHandler = class {
508
599
  const channelId = message.channel.id;
509
600
  const serverId = message.server?.id;
510
601
  const reply = async (content) => {
511
- await message.channel.sendMessage(content);
602
+ return await message.channel.sendMessage(content);
512
603
  };
513
604
  return this.handleMessage(rawContent, message, {
514
605
  authorId,
@@ -553,7 +644,7 @@ var MallyHandler = class {
553
644
  await ctx.reply("This command is owner-only.");
554
645
  return false;
555
646
  }
556
- const guards = Reflect.getMetadata("mally:command:guards", classConstructor) || [];
647
+ const guards = Reflect.getMetadata("stoatx:command:guards", classConstructor) || [];
557
648
  for (const guardClass of guards) {
558
649
  const guardInstance = new guardClass();
559
650
  if (typeof guardInstance.run === "function") {
@@ -562,7 +653,7 @@ var MallyHandler = class {
562
653
  if (typeof guardInstance.guardFail === "function") {
563
654
  await guardInstance.guardFail(ctx);
564
655
  } else {
565
- console.error("[Mally] Guard check failed but no guardFail method defined on", guardClass.name);
656
+ console.error("[Stoatx] Guard check failed but no guardFail method defined on", guardClass.name);
566
657
  }
567
658
  return false;
568
659
  }
@@ -587,7 +678,7 @@ var MallyHandler = class {
587
678
  if (typeof instance.onError === "function") {
588
679
  await instance.onError(ctx, error);
589
680
  } else {
590
- console.error(`[Mally] Error in command ${metadata.name}:`, error);
681
+ console.error(`[Stoatx] Error in command ${metadata.name}:`, error);
591
682
  await ctx.reply(`An error occurred: ${error.message}`);
592
683
  }
593
684
  return false;
@@ -684,13 +775,16 @@ var MallyHandler = class {
684
775
  };
685
776
  // Annotate the CommonJS export names for ESM import in node:
686
777
  0 && (module.exports = {
778
+ Client,
687
779
  CommandRegistry,
688
780
  Guard,
689
781
  METADATA_KEYS,
690
- MallyHandler,
782
+ On,
783
+ Once,
691
784
  SimpleCommand,
692
785
  Stoat,
693
786
  buildSimpleCommandMetadata,
787
+ getEventsMetadata,
694
788
  getGuards,
695
789
  getSimpleCommands,
696
790
  isStoatClass