qaut.js 1.0.6 → 1.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qaut.js",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Official QauT bot framework for building bots and integrations.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ class CommandHandler {
4
+ constructor(client, options = {}) {
5
+ this.client = client;
6
+ this.prefix = options.prefix || '!';
7
+ this.commands = new Map();
8
+ this.cooldowns = new Map();
9
+ }
10
+
11
+ register(name, execute, options = {}) {
12
+ if (!name || typeof execute !== 'function') throw new TypeError('Command name and execute function are required');
13
+ this.commands.set(String(name).toLowerCase(), {
14
+ name: String(name).toLowerCase(),
15
+ aliases: (options.aliases || []).map(alias => String(alias).toLowerCase()),
16
+ description: options.description || '',
17
+ cooldown: Number(options.cooldown || 0),
18
+ execute
19
+ });
20
+ return this;
21
+ }
22
+
23
+ unregister(name) {
24
+ return this.commands.delete(String(name).toLowerCase());
25
+ }
26
+
27
+ find(name) {
28
+ const key = String(name || '').toLowerCase();
29
+ return this.commands.get(key) || [...this.commands.values()].find(command => command.aliases.includes(key));
30
+ }
31
+
32
+ async handleMessage(message) {
33
+ const content = String(message?.content || '');
34
+ if (!content.startsWith(this.prefix)) return false;
35
+ const [rawName, ...args] = content.slice(this.prefix.length).trim().split(/\s+/);
36
+ const command = this.find(rawName);
37
+ if (!command) return false;
38
+ if (command.cooldown && this.isCoolingDown(message.author?.id || message.authorId, command)) return true;
39
+ if (command.cooldown) this.setCooldown(message.author?.id || message.authorId, command);
40
+ await command.execute(message, args, this.client);
41
+ return true;
42
+ }
43
+
44
+ isCoolingDown(userId, command) {
45
+ const key = `${userId}:${command.name}`;
46
+ return (this.cooldowns.get(key) || 0) > Date.now();
47
+ }
48
+
49
+ setCooldown(userId, command) {
50
+ const key = `${userId}:${command.name}`;
51
+ this.cooldowns.set(key, Date.now() + command.cooldown);
52
+ setTimeout(() => this.cooldowns.delete(key), command.cooldown).unref?.();
53
+ }
54
+ }
55
+
56
+ module.exports = { CommandHandler };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ class EventHandler {
4
+ constructor(client) {
5
+ this.client = client;
6
+ this.listeners = new Map();
7
+ }
8
+
9
+ register(eventName, listener, options = {}) {
10
+ if (!eventName || typeof listener !== 'function') throw new TypeError('Event name and listener function are required');
11
+ const method = options.once ? 'once' : 'on';
12
+ this.client[method](eventName, listener);
13
+ if (!this.listeners.has(eventName)) this.listeners.set(eventName, new Set());
14
+ this.listeners.get(eventName).add(listener);
15
+ return this;
16
+ }
17
+
18
+ unregister(eventName, listener) {
19
+ this.client.off(eventName, listener);
20
+ this.listeners.get(eventName)?.delete(listener);
21
+ return this;
22
+ }
23
+
24
+ clear(eventName) {
25
+ const names = eventName ? [eventName] : [...this.listeners.keys()];
26
+ names.forEach(name => {
27
+ for (const listener of this.listeners.get(name) || []) this.client.off(name, listener);
28
+ this.listeners.delete(name);
29
+ });
30
+ return this;
31
+ }
32
+ }
33
+
34
+ module.exports = { EventHandler };
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ class GatewayHandler {
4
+ constructor(client, options = {}) {
5
+ this.client = client;
6
+ this.intervalMs = Number(options.intervalMs || client.pollIntervalMs || 1500);
7
+ this.timer = null;
8
+ }
9
+
10
+ start() {
11
+ this.client.pollIntervalMs = this.intervalMs;
12
+ this.client.startPolling();
13
+ this.timer = this.client.pollInterval;
14
+ return this;
15
+ }
16
+
17
+ stop() {
18
+ if (this.client.pollInterval) clearInterval(this.client.pollInterval);
19
+ this.client.pollInterval = null;
20
+ this.timer = null;
21
+ return this;
22
+ }
23
+ }
24
+
25
+ module.exports = { GatewayHandler };
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const { CommandHandler } = require('./CommandHandler');
4
+ const { EventHandler } = require('./EventHandler');
5
+ const { GatewayHandler } = require('./GatewayHandler');
6
+
7
+ module.exports = {
8
+ CommandHandler,
9
+ EventHandler,
10
+ GatewayHandler
11
+ };
package/src/index.d.ts CHANGED
@@ -114,9 +114,28 @@ export declare class Sticker extends Entity { [key: string]: any; }
114
114
  export declare class Emoji extends Entity { [key: string]: any; }
115
115
  export declare class ScheduledEvent extends Entity { [key: string]: any; }
116
116
  export declare class Collector extends EventEmitter { collected: Collection; next: Promise<any>; stop(reason?: string): void; resetTimer(): this; }
117
+ export declare class CommandHandler {
118
+ constructor(client: Client, options?: { prefix?: string });
119
+ register(name: string, execute: Function, options?: { aliases?: string[]; description?: string; cooldown?: number }): this;
120
+ unregister(name: string): boolean;
121
+ find(name: string): any;
122
+ handleMessage(message: any): Promise<boolean>;
123
+ }
124
+ export declare class EventHandler {
125
+ constructor(client: Client);
126
+ register(eventName: string, listener: Function, options?: { once?: boolean }): this;
127
+ unregister(eventName: string, listener: Function): this;
128
+ clear(eventName?: string): this;
129
+ }
130
+ export declare class GatewayHandler {
131
+ constructor(client: Client, options?: { intervalMs?: number });
132
+ start(): this;
133
+ stop(): this;
134
+ }
117
135
 
118
136
  export declare class Client extends EventEmitter {
119
137
  token: string; rest: REST; user: any; guilds: Collection; channels: Collection; users: Collection;
138
+ commands: CommandHandler; events: EventHandler; gateway: GatewayHandler;
120
139
  constructor(options?: { token?: string; intents?: any; restBaseUrl?: string; keepAlive?: boolean; polling?: boolean; pollIntervalMs?: number; registerProcessShutdown?: boolean });
121
140
  login(token?: string): Promise<string>; destroy(options?: { setOffline?: boolean }): Promise<this>; isReady(): boolean;
122
141
  generateInvite(options?: any): string; fetchInvite(code: string): Promise<any>; fetchWebhook(id: string): Promise<any>; fetchGuildPreview(id: string): Promise<any>;
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const { EventEmitter } = require('events');
4
+ const { CommandHandler, EventHandler, GatewayHandler } = require('./handlers');
4
5
 
5
6
  const DefaultRestBase = 'https://qaut.gg/api';
6
7
 
@@ -471,6 +472,10 @@ class Client extends EventEmitter {
471
472
  this.destroyed = false;
472
473
  this.registerProcessShutdown = options.registerProcessShutdown !== false;
473
474
  this.boundShutdown = null;
475
+ this.commands = new CommandHandler(this, options.commands || {});
476
+ this.events = new EventHandler(this);
477
+ this.gateway = new GatewayHandler(this, options.gateway || {});
478
+ this.on(Events.MessageCreate, message => this.commands.handleMessage(message).catch(err => this.emit(Events.Error, err)));
474
479
  }
475
480
  isReady() { return Boolean(this.user && !this.destroyed); }
476
481
  async login(token = this.token) { if (!token) throw new QauTError('Bot token is required'); this.token = token; this.rest.setToken(token); this.user = await this.rest.get('/bot/me'); if (this.keepAlive) this.startKeepAlive(); if (this.polling) this.startPolling(); if (this.registerProcessShutdown) this.attachProcessShutdown(); this.emit(Events.ClientReady, this.user); return token; }
@@ -551,6 +556,7 @@ Object.defineProperty(User.prototype, 'displayName', {
551
556
  module.exports = {
552
557
  ActionRowBuilder, ActivityType, AttachmentBuilder, BitField, ButtonBuilder, Channel, ChannelSelectMenuBuilder,
553
558
  Client, Collection, ContextMenuCommandBuilder, CreateEmbed, DefaultRestBase, EmbedBuilder, Emoji, Events,
559
+ CommandHandler, EventHandler, GatewayHandler,
554
560
  GatewayIntentBits, Guild, GuildMember, IntentBitField, Interaction, Invite, Message, ModalBuilder,
555
561
  PermissionBitField, PermissionsBitField, PermissionFlagsBits, Partials, QauTError, REST, Reaction, Role,
556
562
  RoleSelectMenuBuilder, ScheduledEvent, SelectMenuBuilder, SlashCommandBuilder, Status, Sticker,