stoatx 0.3.0 → 0.5.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.
Files changed (56) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/decorators/Events.d.ts +55 -0
  3. package/dist/decorators/Events.d.ts.map +1 -0
  4. package/dist/decorators/Events.js +71 -0
  5. package/dist/decorators/Events.js.map +1 -0
  6. package/dist/decorators/Guard.d.ts +38 -0
  7. package/dist/decorators/Guard.d.ts.map +1 -0
  8. package/dist/decorators/Guard.js +47 -0
  9. package/dist/decorators/Guard.js.map +1 -0
  10. package/dist/decorators/SimpleCommand.d.ts +35 -0
  11. package/dist/decorators/SimpleCommand.d.ts.map +1 -0
  12. package/dist/decorators/SimpleCommand.js +43 -0
  13. package/dist/decorators/SimpleCommand.js.map +1 -0
  14. package/dist/decorators/Stoat.d.ts +30 -0
  15. package/dist/decorators/Stoat.d.ts.map +1 -0
  16. package/dist/decorators/Stoat.js +39 -0
  17. package/dist/decorators/Stoat.js.map +1 -0
  18. package/dist/decorators/index.d.ts +9 -0
  19. package/dist/decorators/index.d.ts.map +1 -0
  20. package/dist/decorators/index.js +10 -0
  21. package/dist/decorators/index.js.map +1 -0
  22. package/dist/decorators/keys.d.ts +10 -0
  23. package/dist/decorators/keys.d.ts.map +1 -0
  24. package/dist/decorators/keys.js +10 -0
  25. package/dist/decorators/keys.js.map +1 -0
  26. package/dist/decorators/store.d.ts +46 -0
  27. package/dist/decorators/store.d.ts.map +1 -0
  28. package/dist/decorators/store.js +70 -0
  29. package/dist/decorators/store.js.map +1 -0
  30. package/dist/decorators/utils.d.ts +6 -0
  31. package/dist/decorators/utils.d.ts.map +1 -0
  32. package/dist/decorators/utils.js +16 -0
  33. package/dist/decorators/utils.js.map +1 -0
  34. package/dist/decorators.d.ts +9 -0
  35. package/dist/decorators.d.ts.map +1 -0
  36. package/dist/decorators.js +21 -0
  37. package/dist/decorators.js.map +1 -0
  38. package/dist/handler.d.ts +145 -0
  39. package/dist/handler.d.ts.map +1 -0
  40. package/dist/handler.js +355 -0
  41. package/dist/handler.js.map +1 -0
  42. package/dist/index.d.mts +5 -4
  43. package/dist/index.d.ts +5 -4
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +42 -27
  46. package/dist/index.js.map +1 -0
  47. package/dist/index.mjs +38 -25
  48. package/dist/registry.d.ts +125 -0
  49. package/dist/registry.d.ts.map +1 -0
  50. package/dist/registry.js +279 -0
  51. package/dist/registry.js.map +1 -0
  52. package/dist/types.d.ts +111 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -0
  56. package/package.json +3 -3
@@ -0,0 +1,355 @@
1
+ import "reflect-metadata";
2
+ import { CommandRegistry } from "./registry";
3
+ import { Client as StoatClient } from "stoat.js";
4
+ /**
5
+ * Client - An extended Client that integrates StoatxHandler directly
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Client } from 'stoatx';
10
+ *
11
+ * const client = new Client({
12
+ * prefix: '!',
13
+ * owners: ['owner-user-id'],
14
+ * });
15
+ *
16
+ * await client.initCommands();
17
+ * ```
18
+ */
19
+ export class Client extends StoatClient {
20
+ handler;
21
+ constructor(options) {
22
+ super();
23
+ this.handler = new StoatxHandler({ ...options, client: this });
24
+ // Automatically hook up the message handler
25
+ this.on("messageCreate", async (message) => {
26
+ await this.handler.handle(message);
27
+ });
28
+ }
29
+ /**
30
+ * Initialize the StoatxHandler commands
31
+ */
32
+ async initCommands() {
33
+ await this.handler.init();
34
+ }
35
+ }
36
+ /**
37
+ * StoatxHandler - The execution engine for commands
38
+ *
39
+ * Handles message parsing, middleware execution, and command dispatching
40
+ *
41
+ * @internal This class is not intended to be instantiated directly. Use the `Client` from `stoatx` instead.
42
+ */
43
+ export class StoatxHandler {
44
+ commandsDir;
45
+ discoveryOptions;
46
+ prefixResolver;
47
+ owners;
48
+ registry;
49
+ cooldowns = new Map();
50
+ disableMentionPrefix;
51
+ client;
52
+ constructor(options) {
53
+ this.client = options.client;
54
+ this.commandsDir = options.commandsDir;
55
+ this.discoveryOptions = options.discovery;
56
+ this.prefixResolver = options.prefix;
57
+ this.owners = new Set(options.owners ?? []);
58
+ this.registry = new CommandRegistry(options.extensions);
59
+ this.disableMentionPrefix = options.disableMentionPrefix ?? false;
60
+ }
61
+ /**
62
+ * Initialize the handler - load all commands
63
+ */
64
+ async init() {
65
+ if (this.commandsDir) {
66
+ await this.registry.loadFromDirectory(this.commandsDir);
67
+ }
68
+ else {
69
+ await this.registry.autoDiscover(this.discoveryOptions);
70
+ }
71
+ this.attachEvents();
72
+ }
73
+ /**
74
+ * Attach registered events to the client
75
+ */
76
+ attachEvents() {
77
+ const events = this.registry.getEvents();
78
+ for (const eventDef of events) {
79
+ const handler = async (...args) => {
80
+ try {
81
+ await eventDef.instance[eventDef.methodName](...args, this.client);
82
+ }
83
+ catch (error) {
84
+ console.error(`[Stoatx] Event Handler Error in @${eventDef.type === "on" ? "On" : "Once"}('${eventDef.event}'):`, error);
85
+ }
86
+ };
87
+ if (eventDef.type === "once") {
88
+ this.client.once(eventDef.event, handler);
89
+ }
90
+ else {
91
+ this.client.on(eventDef.event, handler);
92
+ }
93
+ }
94
+ }
95
+ /**
96
+ * Parse a raw message into command context
97
+ */
98
+ async parseMessage(rawContent, message, meta) {
99
+ const prefix = await this.resolvePrefix(meta.serverId);
100
+ let usedPrefix = prefix;
101
+ let withoutPrefix = "";
102
+ // Check for string prefix
103
+ if (rawContent.startsWith(prefix)) {
104
+ withoutPrefix = rawContent.slice(prefix.length).trim();
105
+ usedPrefix = prefix;
106
+ }
107
+ // Check for mention prefix (e.g., "<@bot-id> command") - unless disabled
108
+ else if (!this.disableMentionPrefix && rawContent.match(/^<@!?[\w]+>/)) {
109
+ const mentionMatch = rawContent.match(/^<@!?([\w]+)>\s*/);
110
+ if (mentionMatch) {
111
+ const mentionedId = mentionMatch[1];
112
+ const botId = this.client.user?.id;
113
+ // Only process if mentioned user is the bot
114
+ if (botId && mentionedId === botId) {
115
+ usedPrefix = mentionMatch[0];
116
+ withoutPrefix = rawContent.slice(mentionMatch[0].length).trim();
117
+ }
118
+ else {
119
+ }
120
+ }
121
+ }
122
+ if (!withoutPrefix) {
123
+ return null;
124
+ }
125
+ const [commandName, ...args] = withoutPrefix.split(/\s+/);
126
+ if (!commandName) {
127
+ return null;
128
+ }
129
+ return {
130
+ client: this.client,
131
+ content: rawContent,
132
+ authorId: meta.authorId,
133
+ channelId: meta.channelId,
134
+ serverId: meta.serverId,
135
+ args,
136
+ prefix: usedPrefix,
137
+ commandName: commandName.toLowerCase(),
138
+ reply: meta.reply,
139
+ message,
140
+ };
141
+ }
142
+ /**
143
+ * Handle a message object using the configured message adapter
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * // With message adapter configured
148
+ * client.on('messageCreate', (message) => {
149
+ * handler.handle(message);
150
+ * });
151
+ * ```
152
+ */
153
+ async handle(message) {
154
+ if (!message.channel || !message.author) {
155
+ return false;
156
+ }
157
+ // Skip messages from bots
158
+ if (message.author.bot) {
159
+ return false;
160
+ }
161
+ const rawContent = message.content;
162
+ const authorId = message.author.id;
163
+ const channelId = message.channel.id;
164
+ const serverId = message.server?.id;
165
+ const reply = async (content) => {
166
+ return await message.channel.sendMessage(content);
167
+ };
168
+ return this.handleMessage(rawContent, message, {
169
+ authorId,
170
+ channelId,
171
+ serverId,
172
+ reply,
173
+ });
174
+ }
175
+ /**
176
+ * Handle a raw message string with metadata
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * // Manual usage without message adapter
181
+ * client.on('messageCreate', (message) => {
182
+ * handler.handleMessage(message.content, message, {
183
+ * authorId: message.author.id,
184
+ * channelId: message.channel.id,
185
+ * serverId: message.server?.id,
186
+ * reply: (content) => message.channel.sendMessage(content),
187
+ * });
188
+ * });
189
+ * ```
190
+ */
191
+ async handleMessage(rawContent, message, meta) {
192
+ const ctx = await this.parseMessage(rawContent, message, meta);
193
+ if (!ctx) {
194
+ return false;
195
+ }
196
+ return this.execute(ctx);
197
+ }
198
+ /**
199
+ * Execute a command with the given context
200
+ */
201
+ async execute(ctx) {
202
+ const registered = this.registry.get(ctx.commandName);
203
+ if (!registered) {
204
+ return false;
205
+ }
206
+ const { instance, metadata, methodName, classConstructor } = registered;
207
+ // Owner-only check
208
+ if (metadata.ownerOnly && !this.owners.has(ctx.authorId)) {
209
+ await ctx.reply("This command is owner-only.");
210
+ return false;
211
+ }
212
+ // Guard checks - use classConstructor for guard metadata
213
+ const guards = Reflect.getMetadata("stoatx:command:guards", classConstructor) || [];
214
+ for (const guardClass of guards) {
215
+ const guardInstance = new guardClass();
216
+ if (typeof guardInstance.run === "function") {
217
+ const guardResult = await guardInstance.run(ctx);
218
+ if (!guardResult) {
219
+ if (typeof guardInstance.guardFail === "function") {
220
+ await guardInstance.guardFail(ctx);
221
+ }
222
+ else {
223
+ console.error("[Stoatx] Guard check failed but no guardFail method defined on", guardClass.name);
224
+ }
225
+ return false;
226
+ }
227
+ }
228
+ }
229
+ // Cooldown check
230
+ if (!this.checkCooldown(ctx.authorId, metadata)) {
231
+ const remaining = this.getRemainingCooldown(ctx.authorId, metadata);
232
+ // For method-based commands, check if instance has onCooldown
233
+ if (typeof instance.onCooldown === "function") {
234
+ await instance.onCooldown(ctx, remaining);
235
+ }
236
+ else {
237
+ await ctx.reply(`Please wait ${(remaining / 1000).toFixed(1)} seconds before using this command again.`);
238
+ }
239
+ return false;
240
+ }
241
+ try {
242
+ await instance[methodName](ctx);
243
+ // Set cooldown after successful execution
244
+ if (metadata.cooldown > 0) {
245
+ this.setCooldown(ctx.authorId, metadata);
246
+ }
247
+ return true;
248
+ }
249
+ catch (error) {
250
+ // Handle errors
251
+ if (typeof instance.onError === "function") {
252
+ await instance.onError(ctx, error);
253
+ }
254
+ else {
255
+ console.error(`[Stoatx] Error in command ${metadata.name}:`, error);
256
+ await ctx.reply(`An error occurred: ${error.message}`);
257
+ }
258
+ return false;
259
+ }
260
+ }
261
+ /**
262
+ * Get the command registry
263
+ */
264
+ getRegistry() {
265
+ return this.registry;
266
+ }
267
+ /**
268
+ * Get a command by name or alias
269
+ */
270
+ getCommand(name) {
271
+ return this.registry.get(name);
272
+ }
273
+ /**
274
+ * Get all commands
275
+ */
276
+ getCommands() {
277
+ return this.registry.getAll();
278
+ }
279
+ /**
280
+ * Reload all commands
281
+ */
282
+ async reload() {
283
+ this.registry.clear();
284
+ this.cooldowns.clear();
285
+ if (this.commandsDir) {
286
+ await this.registry.loadFromDirectory(this.commandsDir);
287
+ return;
288
+ }
289
+ await this.registry.autoDiscover(this.discoveryOptions);
290
+ }
291
+ /**
292
+ * Check if a user is an owner
293
+ */
294
+ isOwner(userId) {
295
+ return this.owners.has(userId);
296
+ }
297
+ /**
298
+ * Add an owner
299
+ */
300
+ addOwner(userId) {
301
+ this.owners.add(userId);
302
+ }
303
+ /**
304
+ * Remove an owner
305
+ */
306
+ removeOwner(userId) {
307
+ this.owners.delete(userId);
308
+ }
309
+ /**
310
+ * Resolve the prefix for a context
311
+ */
312
+ async resolvePrefix(serverId) {
313
+ if (typeof this.prefixResolver === "function") {
314
+ return this.prefixResolver({ serverId });
315
+ }
316
+ return this.prefixResolver;
317
+ }
318
+ /**
319
+ * Check if user is on cooldown
320
+ */
321
+ checkCooldown(userId, metadata) {
322
+ if (metadata.cooldown <= 0)
323
+ return true;
324
+ const commandCooldowns = this.cooldowns.get(metadata.name);
325
+ if (!commandCooldowns)
326
+ return true;
327
+ const userCooldown = commandCooldowns.get(userId);
328
+ if (!userCooldown)
329
+ return true;
330
+ return Date.now() >= userCooldown;
331
+ }
332
+ /**
333
+ * Get remaining cooldown time in ms
334
+ */
335
+ getRemainingCooldown(userId, metadata) {
336
+ const commandCooldowns = this.cooldowns.get(metadata.name);
337
+ if (!commandCooldowns)
338
+ return 0;
339
+ const userCooldown = commandCooldowns.get(userId);
340
+ if (!userCooldown)
341
+ return 0;
342
+ return Math.max(0, userCooldown - Date.now());
343
+ }
344
+ /**
345
+ * Set cooldown for a user
346
+ */
347
+ setCooldown(userId, metadata) {
348
+ if (!this.cooldowns.has(metadata.name)) {
349
+ this.cooldowns.set(metadata.name, new Map());
350
+ }
351
+ const commandCooldowns = this.cooldowns.get(metadata.name);
352
+ commandCooldowns.set(userId, Date.now() + metadata.cooldown);
353
+ }
354
+ }
355
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { Client as Client$1, Message } from 'stoat.js';
1
+ import { Client as Client$1, Message } from '@stoatx/client';
2
+ export * from '@stoatx/client';
2
3
 
3
4
  /**
4
5
  * Permission types for commands
@@ -60,7 +61,7 @@ interface CommandContext {
60
61
  /** The command name used (could be an alias) */
61
62
  commandName: string;
62
63
  /** Reply to the message */
63
- reply: (content: string) => Promise<void>;
64
+ reply: (content: string) => Promise<Message>;
64
65
  /** The original message object (platform-specific) */
65
66
  message: Message;
66
67
  }
@@ -456,7 +457,7 @@ declare class StoatxHandler {
456
457
  authorId: string;
457
458
  channelId: string;
458
459
  serverId?: string;
459
- reply: (content: string) => Promise<void>;
460
+ reply: (content: string) => Promise<Message>;
460
461
  }): Promise<CommandContext | null>;
461
462
  /**
462
463
  * Handle a message object using the configured message adapter
@@ -490,7 +491,7 @@ declare class StoatxHandler {
490
491
  authorId: string;
491
492
  channelId: string;
492
493
  serverId?: string;
493
- reply: (content: string) => Promise<void>;
494
+ reply: (content: string) => Promise<Message>;
494
495
  }): Promise<boolean>;
495
496
  /**
496
497
  * Execute a command with the given context
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Client as Client$1, Message } from 'stoat.js';
1
+ import { Client as Client$1, Message } from '@stoatx/client';
2
+ export * from '@stoatx/client';
2
3
 
3
4
  /**
4
5
  * Permission types for commands
@@ -60,7 +61,7 @@ interface CommandContext {
60
61
  /** The command name used (could be an alias) */
61
62
  commandName: string;
62
63
  /** Reply to the message */
63
- reply: (content: string) => Promise<void>;
64
+ reply: (content: string) => Promise<Message>;
64
65
  /** The original message object (platform-specific) */
65
66
  message: Message;
66
67
  }
@@ -456,7 +457,7 @@ declare class StoatxHandler {
456
457
  authorId: string;
457
458
  channelId: string;
458
459
  serverId?: string;
459
- reply: (content: string) => Promise<void>;
460
+ reply: (content: string) => Promise<Message>;
460
461
  }): Promise<CommandContext | null>;
461
462
  /**
462
463
  * Handle a message object using the configured message adapter
@@ -490,7 +491,7 @@ declare class StoatxHandler {
490
491
  authorId: string;
491
492
  channelId: string;
492
493
  serverId?: string;
493
- reply: (content: string) => Promise<void>;
494
+ reply: (content: string) => Promise<Message>;
494
495
  }): Promise<boolean>;
495
496
  /**
496
497
  * Execute a command with the given context
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,cAAc,CAAC;AAG7B,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
21
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
22
  // If the importer is in node compatibility mode or this is not an ESM
22
23
  // file that has been converted to a CommonJS file using a Babel-
@@ -59,13 +60,14 @@ var METADATA_KEYS = {
59
60
 
60
61
  // src/decorators/store.ts
61
62
  var DecoratorStore = class _DecoratorStore {
63
+ static instance;
64
+ /** Stoat classes with their SimpleCommand methods */
65
+ stoatClasses = /* @__PURE__ */ new Map();
66
+ /** Registered commands from @Stoat/@SimpleCommand decorators */
67
+ commands = [];
68
+ /** Whether the store has been initialized */
69
+ initialized = false;
62
70
  constructor() {
63
- /** Stoat classes with their SimpleCommand methods */
64
- this.stoatClasses = /* @__PURE__ */ new Map();
65
- /** Registered commands from @Stoat/@SimpleCommand decorators */
66
- this.commands = [];
67
- /** Whether the store has been initialized */
68
- this.initialized = false;
69
71
  }
70
72
  static getInstance() {
71
73
  if (!_DecoratorStore.instance) {
@@ -209,12 +211,20 @@ var path = __toESM(require("path"));
209
211
  var fs = __toESM(require("fs/promises"));
210
212
  var import_node_url = require("url");
211
213
  var import_tinyglobby = require("tinyglobby");
212
- var _CommandRegistry = class _CommandRegistry {
214
+ var CommandRegistry = class _CommandRegistry {
215
+ static DEFAULT_AUTO_DISCOVERY_IGNORES = [
216
+ "**/node_modules/**",
217
+ "**/.git/**",
218
+ "**/*.d.ts",
219
+ "**/*.test.*",
220
+ "**/*.spec.*"
221
+ ];
222
+ commands = /* @__PURE__ */ new Map();
223
+ aliases = /* @__PURE__ */ new Map();
224
+ registeredEvents = [];
225
+ extensions;
226
+ processedStoatClasses = /* @__PURE__ */ new Set();
213
227
  constructor(extensions = [".js", ".mjs", ".cjs"]) {
214
- this.commands = /* @__PURE__ */ new Map();
215
- this.aliases = /* @__PURE__ */ new Map();
216
- this.registeredEvents = [];
217
- this.processedStoatClasses = /* @__PURE__ */ new Set();
218
228
  this.extensions = extensions;
219
229
  }
220
230
  /**
@@ -273,7 +283,7 @@ var _CommandRegistry = class _CommandRegistry {
273
283
  async isLikelyCommandModule(filePath) {
274
284
  try {
275
285
  const source = await fs.readFile(filePath, "utf8");
276
- return source.includes("Stoat") || source.includes("SimpleCommand") || source.includes("Command") || source.includes("stoatx:command");
286
+ return source.includes("Stoat") || source.includes("SimpleCommand") || source.includes("stoatx:command");
277
287
  } catch {
278
288
  return true;
279
289
  }
@@ -462,19 +472,12 @@ var _CommandRegistry = class _CommandRegistry {
462
472
  return void 0;
463
473
  }
464
474
  };
465
- _CommandRegistry.DEFAULT_AUTO_DISCOVERY_IGNORES = [
466
- "**/node_modules/**",
467
- "**/.git/**",
468
- "**/*.d.ts",
469
- "**/*.test.*",
470
- "**/*.spec.*"
471
- ];
472
- var CommandRegistry = _CommandRegistry;
473
475
 
474
476
  // src/handler.ts
475
477
  var import_reflect_metadata5 = require("reflect-metadata");
476
- var import_stoat = require("stoat.js");
477
- var Client = class extends import_stoat.Client {
478
+ var import_client = require("@stoatx/client");
479
+ var Client = class extends import_client.Client {
480
+ handler;
478
481
  constructor(options) {
479
482
  super();
480
483
  this.handler = new StoatxHandler({ ...options, client: this });
@@ -490,8 +493,15 @@ var Client = class extends import_stoat.Client {
490
493
  }
491
494
  };
492
495
  var StoatxHandler = class {
496
+ commandsDir;
497
+ discoveryOptions;
498
+ prefixResolver;
499
+ owners;
500
+ registry;
501
+ cooldowns = /* @__PURE__ */ new Map();
502
+ disableMentionPrefix;
503
+ client;
493
504
  constructor(options) {
494
- this.cooldowns = /* @__PURE__ */ new Map();
495
505
  this.client = options.client;
496
506
  this.commandsDir = options.commandsDir;
497
507
  this.discoveryOptions = options.discovery;
@@ -527,10 +537,11 @@ var StoatxHandler = class {
527
537
  );
528
538
  }
529
539
  };
540
+ const eventName = eventDef.event;
530
541
  if (eventDef.type === "once") {
531
- this.client.once(eventDef.event, handler);
542
+ this.client.once(eventName, handler);
532
543
  } else {
533
- this.client.on(eventDef.event, handler);
544
+ this.client.on(eventName, handler);
534
545
  }
535
546
  }
536
547
  }
@@ -599,7 +610,7 @@ var StoatxHandler = class {
599
610
  const channelId = message.channel.id;
600
611
  const serverId = message.server?.id;
601
612
  const reply = async (content) => {
602
- await message.channel.sendMessage(content);
613
+ return await message.channel.sendMessage(content);
603
614
  };
604
615
  return this.handleMessage(rawContent, message, {
605
616
  authorId,
@@ -773,6 +784,9 @@ var StoatxHandler = class {
773
784
  commandCooldowns.set(userId, Date.now() + metadata.cooldown);
774
785
  }
775
786
  };
787
+
788
+ // src/index.ts
789
+ __reExport(index_exports, require("@stoatx/client"), module.exports);
776
790
  // Annotate the CommonJS export names for ESM import in node:
777
791
  0 && (module.exports = {
778
792
  Client,
@@ -787,5 +801,6 @@ var StoatxHandler = class {
787
801
  getEventsMetadata,
788
802
  getGuards,
789
803
  getSimpleCommands,
790
- isStoatClass
804
+ isStoatClass,
805
+ ...require("@stoatx/client")
791
806
  });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,SAAS,CAAC;AAExB,aAAa;AACb,cAAc,cAAc,CAAC;AAE7B,WAAW;AACX,cAAc,YAAY,CAAC;AAE3B,UAAU;AACV,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}