@guardbot/framework 1.1.3 → 2.0.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/build/index.js CHANGED
@@ -1,260 +1,119 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- AttachmentOption: () => import_discord7.SlashCommandAttachmentOption,
34
- Autocompleter: () => Autocompleter,
35
- BooleanOption: () => import_discord7.SlashCommandBooleanOption,
36
- ChannelOption: () => import_discord7.SlashCommandChannelOption,
37
- ContextCommand: () => ContextCommand,
38
- FrameworkClient: () => FrameworkClient,
39
- IntegerOption: () => import_discord7.SlashCommandIntegerOption,
40
- Listener: () => Listener,
41
- MentionableOption: () => import_discord7.SlashCommandMentionableOption,
42
- MessageCommand: () => MessageCommand,
43
- NumberOption: () => import_discord7.SlashCommandNumberOption,
44
- RoleOption: () => import_discord7.SlashCommandRoleOption,
45
- SlashCommand: () => SlashCommand,
46
- StringOption: () => import_discord7.SlashCommandStringOption,
47
- SubcommandBuilder: () => import_discord7.SlashCommandSubcommandBuilder,
48
- SubcommandGroupBuilder: () => import_discord7.SlashCommandSubcommandGroupBuilder,
49
- UserOption: () => import_discord7.SlashCommandUserOption
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
50
6
  });
51
- module.exports = __toCommonJS(index_exports);
52
7
 
53
- // src/utils/errors.ts
54
- var import_util = require("util");
55
- var messages = {
56
- NoOptions: () => `No options object was provided.`,
57
- InvalidOption: (name) => `No "${name}" option was provided.`,
58
- InvalidType: (name, expected, actual) => `Expected "${name}" to be of type "${expected}", but got "${actual}".`,
59
- InvalidValue: (name, expected) => `Expected "${name}" to be any one of the listed values: ${expected.map((v) => `"${v}"`).join(" | ")}`,
60
- InvalidValues: (name, expected) => `Expected "${name}" to contain only the listed values: ${expected.map((v) => `"${v}"`).join(" | ")}`,
61
- UnknownComponent: (type, id) => `Encountered an error as there is no "${type}" loaded with the id "${id}".`,
62
- ComponentLoadError: (type, error) => `Encountered an error while loading the "${type}":
63
- ${(0, import_util.inspect)(error)}`,
64
- ComponentAlreadyLoaded: (type, id) => `Encountered an error as a "${type}" with the id "${id}" is already loaded.`,
65
- AppCommandRegister: (error, guildId) => `Encountered an error while registering commands ${guildId ? `to guild "${guildId}"` : ""}:
66
- ${(0, import_util.inspect)(error)}`
67
- };
68
- var FrameworkError = class extends Error {
69
- constructor(id, ...values) {
70
- const message = messages[id](...values);
71
- super(message);
72
- this.name = `Error [ ${id} ]`;
73
- }
74
- };
75
- var FrameworkTypeError = class extends TypeError {
76
- constructor(id, ...values) {
77
- const message = messages[id](...values);
78
- super(message);
79
- this.name = `TypeError [ ${id} ]`;
80
- }
81
- };
8
+ // src/core/FrameworkClient.ts
9
+ import { Collection as Collection2, Client as DiscordClient } from "discord.js";
82
10
 
83
- // src/autocomplete/Autocompleter.ts
84
- function Autocompleter(options) {
85
- if (!options) throw new FrameworkError("NoOptions");
86
- if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
87
- if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
88
- if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
89
- if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
90
- if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
91
- if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
92
- return {
93
- id: options.name,
94
- name: options.name,
95
- disabled: options.disabled ?? false,
96
- execute: options.execute
97
- };
98
- }
99
-
100
- // src/commands/ContextCommand.ts
101
- var import_discord2 = require("discord.js");
102
-
103
- // src/utils/utils.ts
104
- var import_discord = require("discord.js");
105
- var import_path = __toESM(require("path"));
106
- var import_fs = __toESM(require("fs"));
11
+ // src/utils/files.ts
12
+ import path from "path";
13
+ import url from "url";
14
+ import fs from "fs";
107
15
  async function listFiles(dir) {
108
- if (!import_fs.default.existsSync(dir)) return [];
16
+ if (!fs.existsSync(dir)) return [];
109
17
  const files = [];
110
- const items = import_fs.default.readdirSync(dir, { withFileTypes: true });
18
+ const items = fs.readdirSync(dir, { withFileTypes: true });
111
19
  for (const item of items) {
112
- const fullPath = import_path.default.join(dir, item.name);
20
+ const fullPath = path.join(dir, item.name);
113
21
  if (item.isDirectory()) files.push(...await listFiles(fullPath));
114
22
  else if (item.name.endsWith(".js") || item.name.endsWith(".ts")) files.push(fullPath);
115
23
  }
116
24
  return files;
117
25
  }
118
- function isPermissionResolvable(option) {
119
- try {
120
- import_discord.PermissionsBitField.resolve(option);
121
- return true;
122
- } catch {
123
- return false;
124
- }
26
+ function dirExists(dir) {
27
+ return fs.existsSync(dir);
28
+ }
29
+ function resolvePath(...paths) {
30
+ return path.resolve(...paths);
125
31
  }
32
+ function pathToFileURL(filepath) {
33
+ return url.pathToFileURL(filepath);
34
+ }
35
+
36
+ // src/utils/helpers.ts
37
+ import { ApplicationIntegrationType, InteractionContextType, SlashCommandBuilder } from "discord.js";
126
38
  function unixTimestamp(date, type = "f") {
127
39
  return `<t:${Math.floor(new Date(date).valueOf() / 1e3)}:${type}>`;
128
40
  }
129
- function resolveCommandType(type) {
130
- return type === "Slash" ? import_discord.ApplicationCommandType.ChatInput : type === "ContextUser" ? import_discord.ApplicationCommandType.User : import_discord.ApplicationCommandType.Message;
41
+ function createPrefixRegex(userId, prefix2) {
42
+ return new RegExp(`^(<@!?${userId}>${prefix2 ? `|${prefix2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}` : ""})\\s*`);
43
+ }
44
+ function normalizeCommandName(name, type) {
45
+ if (type === "ContextUser" || type === "ContextMessage") return name;
46
+ return name.trim().toLowerCase().replace(/\s+/g, "-");
131
47
  }
132
48
  function resolveCommandContexts(contexts) {
133
- return contexts?.length ? contexts.map((c) => typeof c === "string" ? import_discord.InteractionContextType[c] : c) : [import_discord.InteractionContextType.Guild];
49
+ return contexts?.length ? contexts.map((c) => typeof c === "string" ? InteractionContextType[c] : c) : [InteractionContextType.Guild];
134
50
  }
135
51
  function resolveIntegrationTypes(types) {
136
- return types?.length ? types.map((c) => typeof c === "string" ? import_discord.ApplicationIntegrationType[c] : c) : [import_discord.ApplicationIntegrationType.GuildInstall];
52
+ return types?.length ? types.map((t) => typeof t === "string" ? ApplicationIntegrationType[t] : t) : [ApplicationIntegrationType.GuildInstall];
137
53
  }
138
-
139
- // src/commands/Command.ts
140
- var CommandTypes = ["Slash", "Message", "ContextMessage", "ContextUser"];
141
- function Command(options) {
142
- if (!options) throw new FrameworkError("NoOptions");
143
- if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
144
- if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
145
- if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
146
- if (!options.description || !options.description?.length) throw new FrameworkError("InvalidOption", "description");
147
- if (typeof options.description !== "string") throw new FrameworkTypeError("InvalidType", "description", "string", typeof options.name);
148
- if (!options.commandType) throw new FrameworkError("InvalidOption", "commandType");
149
- if (!CommandTypes.includes(options.commandType)) throw new FrameworkError("InvalidValue", "commandType", CommandTypes);
150
- if (options.memberPermissions !== void 0 && !isPermissionResolvable(options.memberPermissions)) throw new FrameworkTypeError("InvalidType", "memberPermissions", "PermissionResolvable", typeof options.memberPermissions);
151
- if (options.clientPermissions !== void 0 && !isPermissionResolvable(options.clientPermissions)) throw new FrameworkTypeError("InvalidType", "clientPermissions", "PermissionResolvable", typeof options.clientPermissions);
152
- if (options.cooldown && typeof options.cooldown !== "number") throw new FrameworkTypeError("InvalidType", "cooldown", "number", typeof options.cooldown);
153
- if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
154
- return {
155
- ...options,
156
- id: `${options.commandType}:${options.name}`,
157
- name: options.name,
158
- description: options.description,
159
- commandType: options.commandType,
160
- memberPermissions: options.memberPermissions ?? void 0,
161
- clientPermissions: options.clientPermissions ?? void 0,
162
- cooldown: options.cooldown ?? void 0,
163
- disabled: options.disabled ?? false
164
- };
165
- }
166
-
167
- // src/commands/ContextCommand.ts
168
- var CommandScope = ["default", "guild", "global"];
169
- var CommandTypes2 = ["ContextUser", "ContextMessage"];
170
- var CommandContexts = ["Guild", "BotDM", "PrivateChannel", 0, 1, 2];
171
- var IntegrationTypes = ["GuildInstall", "UserInstall", 0, 1];
172
- function ContextCommand(options) {
173
- if (!options.commandType) throw new FrameworkError("InvalidOption", "commandType");
174
- if (typeof options.commandScope !== "string" || !CommandTypes2.includes(options.commandType)) throw new FrameworkError("InvalidValue", "commandType", CommandTypes2);
175
- if (!options.commandScope) throw new FrameworkError("InvalidOption", "commandScope");
176
- if (typeof options.commandScope !== "string" || !CommandScope.includes(options.commandScope)) throw new FrameworkError("InvalidValue", "commandScope", CommandScope);
177
- if (options.commandContexts && !Array.isArray(options.commandContexts)) throw new FrameworkTypeError("InvalidType", "commandContexts", "Array", typeof options.commandContexts);
178
- if (options.commandContexts && options.commandContexts.some((c) => !CommandContexts.includes(c))) throw new FrameworkError("InvalidValues", "commandContexts", CommandContexts);
179
- if (options.integrationTypes && !Array.isArray(options.integrationTypes)) throw new FrameworkTypeError("InvalidType", "integrationTypes", "Array", typeof options.integrationTypes);
180
- if (options.integrationTypes && options.integrationTypes.some((c) => !IntegrationTypes.includes(c))) throw new FrameworkError("InvalidValues", "integrationTypes", IntegrationTypes);
181
- if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
182
- if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
183
- if (!options.commandContexts) options.commandContexts = [import_discord2.InteractionContextType.Guild];
184
- if (!options.integrationTypes) options.integrationTypes = [import_discord2.ApplicationIntegrationType.GuildInstall];
185
- return Command({
186
- ...options,
187
- commandType: options.commandType
188
- });
54
+ function normalizeOptions(options) {
55
+ if (!options || !options?.length) return [];
56
+ if (typeof options === "function") {
57
+ const built = options(new SlashCommandBuilder());
58
+ return built.options?.map((o) => o.toJSON()) ?? [];
59
+ }
60
+ if (Array.isArray(options)) {
61
+ return options.map((o) => "toJSON" in o ? o.toJSON() : o);
62
+ }
63
+ return [];
189
64
  }
190
65
 
191
- // src/commands/MessageCommand.ts
192
- var Contexts = ["BotDM", "Guild"];
193
- function MessageCommand(options) {
194
- if (options.aliases && !Array.isArray(options.aliases)) throw new FrameworkTypeError("InvalidType", "aliases", "array", typeof options.aliases);
195
- if (options.usage && typeof options.usage !== "string") throw new FrameworkTypeError("InvalidType", "usage", "string", typeof options.usage);
196
- if (options.contexts && !Array.isArray(options.contexts)) throw new FrameworkTypeError("InvalidType", "contexts", "array", typeof options.contexts);
197
- if (options.contexts && options.contexts.some((c) => !Contexts.includes(c))) throw new FrameworkError("InvalidValues", "contexts", Contexts);
198
- if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
199
- if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
200
- if (options.devOnly !== void 0 && typeof options.devOnly !== "boolean") throw new FrameworkTypeError("InvalidType", "devOnly", "boolean", typeof options.devOnly);
201
- if (!options.contexts) options.contexts = ["Guild"];
202
- if (options.devOnly === void 0) options.devOnly = false;
203
- return Command({
204
- ...options,
205
- commandType: "Message"
206
- });
66
+ // src/utils/perms.ts
67
+ import { PermissionsBitField } from "discord.js";
68
+ function isPermissionResolvable(option) {
69
+ try {
70
+ PermissionsBitField.resolve(option);
71
+ return true;
72
+ } catch {
73
+ return false;
74
+ }
75
+ ;
207
76
  }
208
-
209
- // src/commands/SlashCommand.ts
210
- var import_discord3 = require("discord.js");
211
- var CommandScope2 = ["default", "guild", "global"];
212
- var CommandContexts2 = ["Guild", "BotDM", "PrivateChannel", 0, 1, 2];
213
- var IntegrationTypes2 = ["GuildInstall", "UserInstall", 0, 1];
214
- function SlashCommand(options) {
215
- if (!options.commandScope) throw new FrameworkError("InvalidOption", "commandScope");
216
- if (typeof options.commandScope !== "string" || !CommandScope2.includes(options.commandScope)) throw new FrameworkError("InvalidValue", "commandScope", CommandScope2);
217
- if (options.commandContexts && !Array.isArray(options.commandContexts)) throw new FrameworkTypeError("InvalidType", "commandContexts", "Array", typeof options.commandContexts);
218
- if (options.commandContexts && options.commandContexts.some((c) => !CommandContexts2.includes(c))) throw new FrameworkError("InvalidValues", "commandContexts", CommandContexts2);
219
- if (options.integrationTypes && !Array.isArray(options.integrationTypes)) throw new FrameworkTypeError("InvalidType", "integrationTypes", "Array", typeof options.integrationTypes);
220
- if (options.integrationTypes && options.integrationTypes.some((c) => !IntegrationTypes2.includes(c))) throw new FrameworkError("InvalidType", "integrationTypes", IntegrationTypes2);
221
- if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
222
- if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
223
- if (!options.commandContexts) options.commandContexts = [import_discord3.InteractionContextType.Guild];
224
- if (!options.integrationTypes) options.integrationTypes = [import_discord3.ApplicationIntegrationType.GuildInstall];
225
- return Command({
226
- ...options,
227
- commandType: "Slash"
228
- });
77
+ function resolvePermissions(member, channel) {
78
+ return (channel && member.permissionsIn(channel)) ?? member.permissions;
229
79
  }
230
-
231
- // src/listeners/Listener.ts
232
- function Listener(options) {
233
- if (!options) throw new FrameworkError("NoOptions");
234
- if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
235
- if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
236
- if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
237
- if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
238
- if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
239
- if (options.once !== void 0 && typeof options.once !== "boolean") throw new FrameworkTypeError("InvalidType", "once", "boolean", typeof options.once);
240
- if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
241
- return {
242
- id: `Client:${options.name}`,
243
- name: options.name,
244
- once: options.once ?? false,
245
- disabled: options.disabled ?? false,
246
- execute: options.execute
247
- };
80
+ function formatPermissions(perms) {
81
+ return perms.map(
82
+ (p) => `\`${p.replace(/([A-Z])/g, (m, l, i) => i === 0 ? l : ` ${l}`)}\``
83
+ ).join(", ");
248
84
  }
249
85
 
250
- // src/FrameworkClient.ts
251
- var import_discord5 = require("discord.js");
86
+ // src/core/FrameworkError.ts
87
+ import { inspect } from "util";
88
+ var messages = {
89
+ NoOptions: () => `No options object was provided.`,
90
+ InvalidOption: (name) => `No "${name}" option was provided.`,
91
+ InvalidType: (name, expected, actual) => `Expected "${name}" to be of type "${expected}", but got "${actual}".`,
92
+ InvalidValue: (name, expected) => `Expected "${name}" to be any one of the listed values: ${expected.map((v) => `"${v}"`).join(" | ")}`,
93
+ InvalidValues: (name, expected) => `Expected "${name}" to contain only the listed values: ${expected.map((v) => `"${v}"`).join(" | ")}`,
94
+ UnknownComponent: (type, id) => `Encountered an error as there is no "${type}" loaded with the id "${id}".`,
95
+ ComponentLoadError: (type, error) => `Encountered an error while loading the "${type}":
96
+ ${inspect(error)}`,
97
+ ComponentAlreadyLoaded: (type, id) => `Encountered an error as a "${type}" with the id "${id}" is already loaded.`,
98
+ AppCommandRegister: (error, guildId) => `Encountered an error while registering commands ${guildId ? `to guild "${guildId}"` : ""}:
99
+ ${inspect(error)}`
100
+ };
101
+ var FrameworkError = class extends Error {
102
+ constructor(id, ...values) {
103
+ super(messages[id](...values));
104
+ this.name = `FrameworkError [${id}]`;
105
+ }
106
+ };
107
+ var FrameworkTypeError = class extends TypeError {
108
+ constructor(id, ...values) {
109
+ super(messages[id](...values));
110
+ this.name = `FrameworkTypeError [${id}]`;
111
+ }
112
+ };
252
113
 
253
- // src/autocomplete/AutocompleteModule.ts
254
- var import_node_url = require("url");
255
- var import_events = __toESM(require("events"));
256
- var import_path2 = __toESM(require("path"));
257
- var AutocompleteModule = class extends import_events.default {
114
+ // src/modules/AutocompletersModule.ts
115
+ import EventEmitter from "events";
116
+ var AutocompletersModule = class extends EventEmitter {
258
117
  client;
259
118
  constructor(client) {
260
119
  super();
@@ -262,53 +121,54 @@ var AutocompleteModule = class extends import_events.default {
262
121
  this.client.on("interactionCreate", (interaction) => this._handleInteraction(interaction));
263
122
  }
264
123
  async load(filepath, reload = false) {
265
- const completerModule = reload ? require(filepath) : await import((0, import_node_url.pathToFileURL)(filepath).href);
266
- const completer = completerModule.autocomplete ?? completerModule.default?.default ?? completerModule.default ?? completerModule;
124
+ const module = await import(pathToFileURL(filepath).href + `?update=${Date.now()}`);
125
+ const completer = module.autocomplete ?? module.default?.default ?? module.default ?? module;
267
126
  if (typeof completer !== "object" || !completer.name || completer.disabled) return false;
268
- if (!reload && this.client.autocomplete.has(completer.id)) throw new FrameworkError("ComponentAlreadyLoaded", "autocomplete", completer.id);
127
+ if (!reload && this.client.autocompleters.has(completer.id)) throw new FrameworkError("ComponentAlreadyLoaded", "autocomplete", completer.id);
269
128
  completer.filepath = filepath;
270
- this.client.autocomplete.set(completer.id, completer);
129
+ this.client.autocompleters.set(completer.id, completer);
271
130
  return true;
272
131
  }
273
132
  async loadAll() {
274
- const listenerDirs = import_path2.default.resolve(this.client.rootDir, "autocomplete");
275
- const files = await listFiles(listenerDirs);
133
+ const files = await listFiles(this.client.autocompletersDir);
276
134
  for (const file of files) {
277
135
  try {
278
- await this.load(import_path2.default.resolve(file));
136
+ await this.load(resolvePath(file));
279
137
  } catch (error) {
280
138
  this.client.emit("error", new FrameworkError("ComponentLoadError", "autocomplete", error));
281
139
  }
282
140
  }
283
141
  }
284
142
  async reload(id) {
285
- const completer = this.client.autocomplete.get(id);
143
+ const completer = this.client.autocompleters.get(id);
286
144
  if (!completer) throw new FrameworkError("UnknownComponent", "autocomplete", id);
287
145
  this.unload(id, true);
288
146
  await this.load(completer.filepath, true);
289
147
  }
290
148
  unload(id, reload = false) {
291
- if (!this.client.autocomplete.has(id)) throw new FrameworkError("UnknownComponent", "autocomplete", id);
292
- const completer = this.client.autocomplete.get(id);
293
- delete require.cache[require.resolve(completer.filepath)];
294
- if (!reload) this.client.autocomplete.delete(id);
149
+ if (!this.client.autocompleters.has(id)) throw new FrameworkError("UnknownComponent", "autocomplete", id);
150
+ const completer = this.client.autocompleters.get(id);
151
+ delete __require.cache[__require.resolve(completer.filepath)];
152
+ if (!reload) this.client.autocompleters.delete(id);
295
153
  }
296
154
  async _handleInteraction(interaction) {
297
155
  if (!interaction.isAutocomplete()) return;
298
156
  const option = interaction.options.getFocused(true);
299
157
  const command = this.client.commands.get(`Slash:${interaction.commandName}`);
300
- const completer = this.client.autocomplete.get(option.name);
301
- if (!option || !command || command.commandType !== "Slash") {
158
+ const completer = this.client.autocompleters.get(option.name);
159
+ if (!command || command.commandType !== "Slash") {
302
160
  this.emit("unknown", interaction);
303
161
  return;
304
162
  }
305
- if (completer && !completer.disabled) {
163
+ if (!interaction.inCachedGuild()) return;
164
+ const allowed = !completer?.commands?.length || completer.commands.includes(command.name);
165
+ if (completer && !completer.disabled && allowed) {
306
166
  try {
307
167
  this.emit("execute", { interaction, command, completer });
308
168
  await completer.execute(this.client, interaction, command, option.value);
309
169
  this.emit("success", { interaction, command, completer });
310
170
  } catch (error) {
311
- this.emit("success", { interaction, command, completer, error });
171
+ this.emit("error", { interaction, command, completer, error });
312
172
  }
313
173
  } else if (typeof command.autocomplete === "function" && !command.disabled) {
314
174
  try {
@@ -316,7 +176,7 @@ var AutocompleteModule = class extends import_events.default {
316
176
  await command.autocomplete(this.client, interaction);
317
177
  this.emit("success", { interaction, command, completer });
318
178
  } catch (error) {
319
- this.emit("success", { interaction, command, completer, error });
179
+ this.emit("error", { interaction, command, completer, error });
320
180
  }
321
181
  } else {
322
182
  this.emit("unknown", interaction);
@@ -324,17 +184,15 @@ var AutocompleteModule = class extends import_events.default {
324
184
  }
325
185
  };
326
186
 
327
- // src/listeners/ListenersModule.ts
328
- var import_node_url2 = require("url");
329
- var import_path3 = __toESM(require("path"));
187
+ // src/modules/ListenersModule.ts
330
188
  var ListenerModule = class {
331
189
  client;
332
190
  constructor(client) {
333
191
  this.client = client;
334
192
  }
335
193
  async load(filepath, reload = false) {
336
- const listenerModule = reload ? require(filepath) : await import((0, import_node_url2.pathToFileURL)(filepath).href);
337
- const listener = listenerModule.listener ?? listenerModule.default?.default ?? listenerModule.default ?? listenerModule;
194
+ const module = await import(pathToFileURL(filepath).href + `?update=${Date.now()}`);
195
+ const listener = module?.listener ?? module?.default?.default ?? module?.default ?? module;
338
196
  if (typeof listener !== "object" || !listener.name || listener.disabled) return false;
339
197
  if (!reload && this.client.events.has(listener.id)) throw new FrameworkError("ComponentAlreadyLoaded", "listener", listener.id);
340
198
  listener.filepath = filepath;
@@ -344,11 +202,10 @@ var ListenerModule = class {
344
202
  return true;
345
203
  }
346
204
  async loadAll() {
347
- const listenerDirs = import_path3.default.resolve(this.client.rootDir, "listeners");
348
- const files = await listFiles(listenerDirs);
205
+ const files = await listFiles(this.client.listenersDir);
349
206
  for (const file of files) {
350
207
  try {
351
- await this.load(import_path3.default.resolve(file));
208
+ await this.load(resolvePath(file));
352
209
  } catch (error) {
353
210
  this.client.emit("error", new FrameworkError("ComponentLoadError", "listener", error));
354
211
  }
@@ -364,19 +221,19 @@ var ListenerModule = class {
364
221
  if (!this.client.events.has(id)) throw new FrameworkError("UnknownComponent", "listener", id);
365
222
  const listener = this.client.events.get(id);
366
223
  if (listener._execute) this.client.off(listener.name, listener._execute);
367
- delete require.cache[require.resolve(listener.filepath)];
224
+ delete __require.cache[__require.resolve(listener.filepath)];
368
225
  if (!reload) this.client.events.delete(id);
369
226
  }
370
227
  };
371
228
 
372
- // src/commands/CommandsModule.ts
373
- var import_discord4 = require("discord.js");
374
- var import_node_url3 = require("url");
375
- var import_events2 = __toESM(require("events"));
376
- var import_path4 = __toESM(require("path"));
377
- var CommandsModule = class extends import_events2.default {
229
+ // src/modules/CommandsModule.ts
230
+ import { ApplicationCommandType, Collection, MessageFlags } from "discord.js";
231
+ import EventEmitter2 from "events";
232
+ var CommandsModule = class extends EventEmitter2 {
378
233
  client;
379
- handler = {};
234
+ handlers = {};
235
+ middleware;
236
+ prefixRegex;
380
237
  constructor(client) {
381
238
  super();
382
239
  this.client = client;
@@ -384,17 +241,16 @@ var CommandsModule = class extends import_events2.default {
384
241
  this.client.on("interactionCreate", (interaction) => this._handleInteraction(interaction));
385
242
  }
386
243
  setHandler(key, callback) {
387
- return this.handler[key] = callback;
388
- }
389
- setMessageInterceptor(callback) {
390
- return this.handler.MessageCommandInterceptor = callback;
244
+ this.handlers[key] = callback;
245
+ return true;
391
246
  }
392
- setInteractionInterceptor(callback) {
393
- return this.handler.InteractionCommandInterceptor = callback;
247
+ setMiddleware(callback) {
248
+ this.middleware = callback;
249
+ return true;
394
250
  }
395
251
  async load(filepath, reload = false) {
396
- const commandModule = reload ? require(filepath) : await import((0, import_node_url3.pathToFileURL)(filepath).href);
397
- const command = commandModule?.command ?? commandModule?.default?.default ?? commandModule?.default ?? commandModule;
252
+ const module = await import(pathToFileURL(filepath).href + `?update=${Date.now()}`);
253
+ const command = module?.command ?? module?.default?.default ?? module?.default ?? module;
398
254
  if (typeof command !== "object" || !command.name || command.disabled) return false;
399
255
  if (!reload && this.client.commands.has(command.id)) throw new FrameworkError("ComponentAlreadyLoaded", "command", command.id);
400
256
  command.filepath = filepath;
@@ -405,11 +261,10 @@ var CommandsModule = class extends import_events2.default {
405
261
  return true;
406
262
  }
407
263
  async loadAll() {
408
- const commandsDir = import_path4.default.resolve(this.client.rootDir, "commands");
409
- const files = await listFiles(commandsDir);
264
+ const files = await listFiles(this.client.commandsDir);
410
265
  for (const file of files) {
411
266
  try {
412
- await this.load(import_path4.default.resolve(file));
267
+ await this.load(resolvePath(file));
413
268
  } catch (error) {
414
269
  this.client.emit("error", new FrameworkError("ComponentLoadError", "commands", error));
415
270
  }
@@ -424,7 +279,7 @@ var CommandsModule = class extends import_events2.default {
424
279
  unload(id, reload = false) {
425
280
  if (!this.client.commands.has(id)) throw new FrameworkError("UnknownComponent", "commands", id);
426
281
  const command = this.client.commands.get(id);
427
- delete require.cache[require.resolve(command.filepath)];
282
+ delete __require.cache[__require.resolve(command.filepath)];
428
283
  if (!reload) this.client.commands.delete(id);
429
284
  }
430
285
  async registerOnStart(guildIds, commands) {
@@ -448,13 +303,9 @@ var CommandsModule = class extends import_events2.default {
448
303
  }
449
304
  async _handleMessage(message) {
450
305
  if (!message.content?.length || message.author.bot) return;
451
- if (this.handler.MessageCommandInterceptor) {
452
- const shouldContinue = await this.handler.MessageCommandInterceptor(message);
453
- if (!shouldContinue) return;
454
- }
455
- const prefixRegex = new RegExp(`^(<@!?${message.client.user.id}>${this.client.prefix ? `|${this.client.prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}` : ""})\\s*`);
456
- if (!prefixRegex.test(message.content.toLowerCase())) return;
457
- const matchedPrefix = message.content.toLowerCase().match(prefixRegex)?.[1];
306
+ if (!this.prefixRegex) this.prefixRegex = createPrefixRegex(message.client.user.id, this.client.prefix);
307
+ if (!this.prefixRegex.test(message.content.toLowerCase())) return;
308
+ const matchedPrefix = message.content.toLowerCase().match(this.prefixRegex)?.[1];
458
309
  if (!matchedPrefix) return;
459
310
  const args = (message.content || "").slice(matchedPrefix.length).trim().split(/ +/);
460
311
  const commandName = args.shift()?.toLowerCase();
@@ -463,38 +314,48 @@ var CommandsModule = class extends import_events2.default {
463
314
  const command = this.client.commands.get(commandId) || this.client.commands.get(this.client.aliases.get(commandName) || "");
464
315
  if (!command || command.commandType !== "Message" || command.disabled || command.devOnly && !this.client.developers.includes(message.author.id)) return;
465
316
  if (!message.inGuild() && !command.contexts.includes("BotDM") || message.inGuild() && !command.contexts.includes("Guild")) return;
466
- if (message.inGuild() && command.memberPermissions) {
467
- const executor = await message.guild.members.fetch({ user: message.author.id, force: false });
468
- const memberPerms = executor.permissionsIn(message.channel) ?? executor.permissions;
469
- if (!memberPerms.has(command.memberPermissions)) {
470
- const missingPermsArray = memberPerms.missing(command.memberPermissions);
471
- if (typeof this.handler.onMemberPermissions === "function") return this.handler.onMemberPermissions(message, command, missingPermsArray);
472
- else return await message.reply({ content: "\u274C You don't have the required permission(s) to use this command." }).then((m) => {
473
- setTimeout(() => m.delete().catch((e) => null), 1e4);
474
- }).catch(() => null);
475
- }
317
+ if (this.middleware) {
318
+ const shouldContinue = await this.middleware(message, command);
319
+ if (!shouldContinue) return;
476
320
  }
477
- if (message.inGuild() && command.clientPermissions) {
478
- const clientMember = await message.guild.members.fetchMe({ force: false });
479
- const clientPerms = clientMember.permissionsIn(message.channel) ?? clientMember.permissions;
480
- if (!clientMember.permissions.has(command.clientPermissions)) {
481
- const missingPermsArray = clientPerms.missing(command.clientPermissions);
482
- if (typeof this.handler.onClientPermissions === "function") return this.handler.onClientPermissions(message, command, missingPermsArray);
483
- else return await message.reply({ content: `\u274C ${clientMember.displayName} requires ${missingPermsArray.map((p) => `\` ${p.replace(/([A-Z])/g, (_, l, i) => i === 0 ? l : ` ${l}`)} \``).join(" ")} permission(s) to run this command.` }).then((m) => {
484
- setTimeout(() => m.delete().catch((e) => null), 1e4);
485
- }).catch(() => null);
321
+ if (message.inGuild()) {
322
+ const [executer, clientMember] = await Promise.all([
323
+ command.memberPermissions ? message.guild.members.fetch({ user: message.author.id, force: false }) : null,
324
+ command.clientPermissions ? message.guild.members.fetchMe({ force: false }) : null
325
+ ]);
326
+ if (command.memberPermissions && !executer || command.clientPermissions && !clientMember) return;
327
+ if (command.memberPermissions) {
328
+ const memberPerms = resolvePermissions(executer, message.channel);
329
+ if (!memberPerms.has(command.memberPermissions)) {
330
+ const missing = memberPerms.missing(command.memberPermissions);
331
+ if (typeof this.handlers.onMemberPermissions === "function") return this.handlers.onMemberPermissions(message, command, missing);
332
+ return message.reply({ content: "You don't have the required permission(s) to use this command." }).then((m) => {
333
+ setTimeout(() => m.delete().catch((e) => null), 1e4);
334
+ }).catch(() => null);
335
+ }
336
+ }
337
+ if (command.clientPermissions) {
338
+ const clientPerms = resolvePermissions(clientMember, message.channel);
339
+ if (!clientPerms.has(command.clientPermissions)) {
340
+ const missing = clientPerms.missing(command.clientPermissions);
341
+ if (typeof this.handlers.onClientPermissions === "function") return this.handlers.onClientPermissions(message, command, missing);
342
+ return message.reply({ content: `${clientMember.displayName} requires ${formatPermissions(missing)} permission(s) to run this command.` }).then((m) => {
343
+ setTimeout(() => m.delete().catch((e) => null), 1e4);
344
+ }).catch(() => null);
345
+ }
486
346
  }
487
347
  }
488
348
  if (command.cooldown && command.cooldown > 1e3) {
489
- if (!this.client.cooldowns.has(commandId)) this.client.cooldowns.set(commandId, new import_discord4.Collection());
349
+ if (!this.client.cooldowns.has(commandId)) this.client.cooldowns.set(commandId, new Collection());
490
350
  const commandCooldowns = this.client.cooldowns.get(commandId);
491
351
  if (commandCooldowns) {
492
352
  if (commandCooldowns.has(message.author.id)) {
493
- const expirationDate = new Date((commandCooldowns.get(message.author.id) || 0) + command.cooldown);
494
- if (expirationDate.valueOf() - Date.now() > 1e3) {
495
- if (typeof this.handler.onCooldown === "function") return this.handler.onCooldown(message, command, expirationDate);
496
- else return await message.reply({ content: `\u274C Slow down and try the Command Again **${unixTimestamp(new Date(expirationDate), "R")}**.` }).then((m) => {
497
- setTimeout(() => m.delete().catch((e) => null), expirationDate.valueOf() - Date.now());
353
+ const expiresAt = new Date((commandCooldowns.get(message.author.id) || 0) + command.cooldown).valueOf();
354
+ const now = Date.now();
355
+ if (expiresAt - now > 1e3) {
356
+ if (typeof this.handlers.onCooldown === "function") return this.handlers.onCooldown(message, command, new Date(expiresAt));
357
+ return message.reply({ content: `Slow down and try the Command Again **${unixTimestamp(new Date(expiresAt), "R")}**.` }).then((m) => {
358
+ setTimeout(() => m.delete().catch((e) => null), expiresAt - Date.now());
498
359
  });
499
360
  }
500
361
  }
@@ -504,7 +365,11 @@ var CommandsModule = class extends import_events2.default {
504
365
  }
505
366
  try {
506
367
  this.emit("execute", { context: message, command });
507
- await command.execute(this.client, message, args);
368
+ if (message.inGuild() && command.contexts.includes("Guild")) {
369
+ await command.execute(this.client, message, args);
370
+ } else if (!message.inGuild() && command.contexts.includes("BotDM")) {
371
+ await command.execute(this.client, message, args);
372
+ }
508
373
  this.emit("success", { context: message, command });
509
374
  } catch (error) {
510
375
  this.emit("error", { context: message, command, error });
@@ -512,34 +377,35 @@ var CommandsModule = class extends import_events2.default {
512
377
  }
513
378
  async _handleInteraction(interaction) {
514
379
  if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand()) return;
515
- if (this.handler.InteractionCommandInterceptor) {
516
- const shouldContinue = await this.handler.InteractionCommandInterceptor(interaction);
517
- if (!shouldContinue) return;
518
- }
519
380
  const commandId = `${this._getCommandId(interaction)}:${interaction.commandName}`;
520
381
  const command = this.client.commands.get(commandId);
521
382
  if (!command || command.disabled || command.commandType === "Message") {
522
383
  this.emit("unknown", interaction);
523
384
  return;
524
385
  }
525
- if (interaction.guild && interaction.channel && !interaction.channel.isDMBased() && command.clientPermissions) {
386
+ if (this.middleware) {
387
+ const shouldContinue = await this.middleware(interaction, command);
388
+ if (!shouldContinue) return;
389
+ }
390
+ if (!interaction.inCachedGuild() && (command.commandContexts?.includes("Guild") || command.commandContexts?.includes(0))) return;
391
+ if (command.clientPermissions && interaction.inCachedGuild()) {
526
392
  const clientMember = await interaction.guild.members.fetchMe({ force: false });
527
- const clientPerms = interaction.channel.isSendable() ? clientMember.permissionsIn(interaction.channel) : clientMember.permissions;
393
+ const clientPerms = resolvePermissions(clientMember, interaction.channel);
528
394
  if (!clientPerms.has(command.clientPermissions)) {
529
- const missingPermsArray = clientPerms.missing(command.clientPermissions);
530
- if (typeof this.handler.onClientPermissions === "function") return this.handler.onClientPermissions(interaction, command, missingPermsArray);
531
- else return await interaction.reply({ content: `\u274C ${clientMember.displayName} requires ${missingPermsArray.map((p) => `\` ${p.replace(/([A-Z])/g, (_, l, i) => i === 0 ? l : ` ${l}`)} \``).join(" ")} permission(s) to run this command.`, flags: import_discord4.MessageFlags.Ephemeral });
395
+ const missing = clientPerms.missing(command.clientPermissions);
396
+ if (typeof this.handlers.onClientPermissions === "function") return this.handlers.onClientPermissions(interaction, command, missing);
397
+ return interaction.reply({ content: `${clientMember.displayName} requires ${formatPermissions(missing)} permission(s) to run this command.`, flags: MessageFlags.Ephemeral });
532
398
  }
533
399
  }
534
400
  if (command.cooldown && command.cooldown > 1e3) {
535
- if (!this.client.cooldowns.has(commandId)) this.client.cooldowns.set(commandId, new import_discord4.Collection());
401
+ if (!this.client.cooldowns.has(commandId)) this.client.cooldowns.set(commandId, new Collection());
536
402
  const commandCooldowns = this.client.cooldowns.get(commandId);
537
403
  if (commandCooldowns) {
538
404
  if (commandCooldowns.has(interaction.user.id)) {
539
- const expirationDate = new Date((commandCooldowns.get(interaction.user.id) || 0) + command.cooldown);
540
- if (expirationDate.valueOf() - Date.now() > 1e3) {
541
- if (typeof this.handler.onCooldown === "function") return this.handler.onCooldown(interaction, command, expirationDate);
542
- else return await interaction.reply({ content: `\u274C Slow down and try the Command Again **${unixTimestamp(new Date(expirationDate), "R")}**.`, flags: import_discord4.MessageFlags.Ephemeral });
405
+ const expiresAt = new Date((commandCooldowns.get(interaction.user.id) || 0) + command.cooldown).valueOf();
406
+ if (expiresAt - Date.now() > 1e3) {
407
+ if (typeof this.handlers.onCooldown === "function") return this.handlers.onCooldown(interaction, command, new Date(expiresAt));
408
+ return await interaction.reply({ content: `Slow down and try the Command Again **${unixTimestamp(new Date(expiresAt), "R")}**.`, flags: MessageFlags.Ephemeral });
543
409
  }
544
410
  }
545
411
  commandCooldowns.set(interaction.user.id, (/* @__PURE__ */ new Date()).valueOf());
@@ -561,62 +427,229 @@ var CommandsModule = class extends import_events2.default {
561
427
  return "unknown";
562
428
  }
563
429
  _getCommandData(command) {
564
- return {
430
+ const base = {
565
431
  name: command.name,
566
- description: command.description,
567
- type: resolveCommandType(command.commandType),
568
432
  defaultMemberPermissions: command.memberPermissions ?? null,
569
433
  contexts: resolveCommandContexts(command.commandContexts),
570
434
  integrationTypes: resolveIntegrationTypes(command.integrationTypes),
571
435
  nameLocalizations: command.nameLocalizations,
572
- descriptionLocalizations: command.descriptionLocalizations,
573
- ...command.commandType === "Slash" ? {
574
- options: command.options ? command.options.map((op) => typeof op.toJSON === "function" ? op.toJSON() : op) : []
575
- } : {}
436
+ descriptionLocalizations: command.descriptionLocalizations
437
+ };
438
+ if (command.commandType === "Slash") {
439
+ return {
440
+ ...base,
441
+ type: ApplicationCommandType.ChatInput,
442
+ description: command.description,
443
+ options: command.options
444
+ };
445
+ } else if (command.commandType === "ContextMessage") {
446
+ return {
447
+ ...base,
448
+ type: ApplicationCommandType.Message
449
+ };
450
+ }
451
+ return {
452
+ ...base,
453
+ type: ApplicationCommandType.User
576
454
  };
577
455
  }
578
456
  };
579
457
 
580
- // src/FrameworkClient.ts
581
- var import_fs2 = __toESM(require("fs"));
582
- var FrameworkClient = class extends import_discord5.Client {
583
- rootDir;
458
+ // src/core/FrameworkClient.ts
459
+ var FrameworkClient = class extends DiscordClient {
584
460
  prefix;
585
461
  developers;
462
+ rootDir;
463
+ commandsDir;
464
+ listenersDir;
465
+ autocompletersDir;
466
+ _inited = false;
467
+ autocompleters = new Collection2();
468
+ events = new Collection2();
469
+ aliases = new Collection2();
470
+ commands = new Collection2();
471
+ cooldowns = new Collection2();
472
+ commandsModule;
473
+ listenersModule;
474
+ autocompletersModule;
586
475
  constructor(frameworkOptions) {
587
476
  super(frameworkOptions.clientOptions);
588
477
  this.prefix = frameworkOptions.prefix ?? "!";
589
- this.rootDir = frameworkOptions.rootDir ?? (import_fs2.default.existsSync("./src") ? "./src" : "./");
590
- this.developers = frameworkOptions.developers || [];
591
- this.autocomplete = new import_discord5.Collection();
592
- this.events = new import_discord5.Collection();
593
- this.aliases = new import_discord5.Collection();
594
- this.commands = new import_discord5.Collection();
595
- this.cooldowns = new import_discord5.Collection();
596
- this.autocompleteModule = new AutocompleteModule(this);
597
- this.listenerModule = new ListenerModule(this);
478
+ this.developers = [...frameworkOptions.developers || []];
479
+ this.rootDir = frameworkOptions.rootDir ?? (dirExists("./src") ? "./src" : "./");
480
+ this.commandsDir = resolvePath(this.rootDir, frameworkOptions.commandsDir ?? "commands");
481
+ this.listenersDir = resolvePath(this.rootDir, frameworkOptions.listenersDir ?? "listeners");
482
+ this.autocompletersDir = resolvePath(this.rootDir, frameworkOptions.autocompletersDir ?? "autocompleters");
598
483
  this.commandsModule = new CommandsModule(this);
599
- this.on("interactionCreate", (interaction) => {
600
- if (interaction.isAnySelectMenu()) return this.emit("selectMenuInteraction", interaction);
601
- else if (interaction.isModalSubmit()) return this.emit("modalSubmitInteraction", interaction);
602
- else if (interaction.isButton()) return this.emit("buttonInteraction", interaction);
603
- });
484
+ this.listenersModule = new ListenerModule(this);
485
+ this.autocompletersModule = new AutocompletersModule(this);
486
+ this.routeInteractions();
604
487
  this.once("clientReady", async () => {
605
488
  if (frameworkOptions.registerOnStart && frameworkOptions.guildsToRegister?.length) {
606
489
  await this.commandsModule.registerOnStart(frameworkOptions.guildsToRegister);
607
490
  }
608
491
  });
609
492
  }
610
- async start(token) {
611
- await this.listenerModule.loadAll();
612
- await this.autocompleteModule.loadAll();
493
+ async init() {
494
+ this._inited = true;
495
+ await this.listenersModule.loadAll();
496
+ await this.autocompletersModule.loadAll();
613
497
  await this.commandsModule.loadAll();
498
+ }
499
+ async start(token) {
500
+ if (!this._inited) await this.init();
614
501
  await this.login(token);
615
502
  }
503
+ routeInteractions() {
504
+ this.on("interactionCreate", (interaction) => {
505
+ if (interaction.isAnySelectMenu()) return this.emit("selectMenuInteraction", interaction);
506
+ else if (interaction.isModalSubmit()) return this.emit("modalSubmitInteraction", interaction);
507
+ else if (interaction.isButton()) return this.emit("buttonInteraction", interaction);
508
+ });
509
+ }
616
510
  };
617
511
 
512
+ // src/builders/autocompleters/Autocompleter.ts
513
+ function Autocompleter(options) {
514
+ if (!options) throw new FrameworkError("NoOptions");
515
+ if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
516
+ if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
517
+ if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
518
+ if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
519
+ if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
520
+ if (options.commands && !Array.isArray(options.commands)) throw new FrameworkTypeError("InvalidType", "commands", "string[]", typeof options.commands);
521
+ if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
522
+ return {
523
+ id: options.name,
524
+ name: options.name,
525
+ disabled: options.disabled ?? false,
526
+ execute: options.execute
527
+ };
528
+ }
529
+
530
+ // src/types/commands.ts
531
+ var CommandTypes = ["Slash", "Message", "ContextMessage", "ContextUser"];
532
+ var CommandContexts = ["Guild", "BotDM", "PrivateChannel", 0, 1, 2];
533
+ var IntegrationTypes = ["GuildInstall", "UserInstall", 0, 1];
534
+ var CommandScopes = ["default", "guild", "global"];
535
+ var MessageCommandContexts = ["Guild", "BotDM"];
536
+
537
+ // src/builders/commands/ContextCommand.ts
538
+ import { ApplicationIntegrationType as ApplicationIntegrationType2, InteractionContextType as InteractionContextType2 } from "discord.js";
539
+
540
+ // src/builders/commands/BaseCommand.ts
541
+ function BaseCommand(options) {
542
+ if (!options) throw new FrameworkError("NoOptions");
543
+ if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
544
+ if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
545
+ if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
546
+ if (!options.description || !options.description?.length) throw new FrameworkError("InvalidOption", "description");
547
+ if (typeof options.description !== "string") throw new FrameworkTypeError("InvalidType", "description", "string", typeof options.description);
548
+ if (!options.commandType) throw new FrameworkError("InvalidOption", "commandType");
549
+ if (!CommandTypes.includes(options.commandType)) throw new FrameworkError("InvalidValue", "commandType", CommandTypes);
550
+ if (options.memberPermissions !== void 0 && !isPermissionResolvable(options.memberPermissions)) {
551
+ throw new FrameworkTypeError("InvalidType", "memberPermissions", "PermissionResolvable", typeof options.memberPermissions);
552
+ }
553
+ if (options.clientPermissions !== void 0 && !isPermissionResolvable(options.clientPermissions)) {
554
+ throw new FrameworkTypeError("InvalidType", "clientPermissions", "PermissionResolvable", typeof options.clientPermissions);
555
+ }
556
+ if (options.cooldown && typeof options.cooldown !== "number") throw new FrameworkTypeError("InvalidType", "cooldown", "number", typeof options.cooldown);
557
+ if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
558
+ return {
559
+ ...options,
560
+ id: `${options.commandType}:${options.name}`,
561
+ name: normalizeCommandName(options.name, options.commandType),
562
+ description: options.description,
563
+ commandType: options.commandType,
564
+ memberPermissions: options.memberPermissions ?? void 0,
565
+ clientPermissions: options.clientPermissions ?? void 0,
566
+ cooldown: options.cooldown ?? void 0,
567
+ disabled: options.disabled ?? false
568
+ };
569
+ }
570
+
571
+ // src/builders/commands/ContextCommand.ts
572
+ function ContextCommand(options) {
573
+ if (!options.commandType) throw new FrameworkError("InvalidOption", "commandType");
574
+ if (options.commandType !== CommandTypes[2] && options.commandType !== CommandTypes[3]) throw new FrameworkError("InvalidValue", "commandType", CommandTypes);
575
+ if (!options.commandScope) throw new FrameworkError("InvalidOption", "commandScope");
576
+ if (typeof options.commandScope !== "string" || !CommandScopes.includes(options.commandScope)) throw new FrameworkError("InvalidValue", "commandScope", CommandScopes);
577
+ if (options.commandContexts && !Array.isArray(options.commandContexts)) throw new FrameworkTypeError("InvalidType", "commandContexts", "Array", typeof options.commandContexts);
578
+ if (options.commandContexts && options.commandContexts.some((c) => !CommandContexts.includes(c))) throw new FrameworkError("InvalidValues", "commandContexts", CommandContexts);
579
+ if (options.integrationTypes && !Array.isArray(options.integrationTypes)) throw new FrameworkTypeError("InvalidType", "integrationTypes", "Array", typeof options.integrationTypes);
580
+ if (options.integrationTypes && options.integrationTypes.some((c) => !IntegrationTypes.includes(c))) throw new FrameworkError("InvalidValues", "integrationTypes", IntegrationTypes);
581
+ if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
582
+ if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
583
+ if (!options.commandContexts || !options.commandContexts.length) options.commandContexts = [InteractionContextType2.Guild];
584
+ if (!options.integrationTypes || !options.integrationTypes.length) options.integrationTypes = [ApplicationIntegrationType2.GuildInstall];
585
+ return BaseCommand({
586
+ ...options,
587
+ commandType: options.commandType,
588
+ description: options.description ?? "no description"
589
+ });
590
+ }
591
+
592
+ // src/builders/commands/MessageCommand.ts
593
+ function MessageCommand(options) {
594
+ if (options.aliases && !Array.isArray(options.aliases)) throw new FrameworkTypeError("InvalidType", "aliases", "array", typeof options.aliases);
595
+ if (options.usage && typeof options.usage !== "string") throw new FrameworkTypeError("InvalidType", "usage", "string", typeof options.usage);
596
+ if (options.contexts && !Array.isArray(options.contexts)) throw new FrameworkTypeError("InvalidType", "contexts", "array", typeof options.contexts);
597
+ if (options.contexts && options.contexts.some((c) => !MessageCommandContexts.includes(c))) throw new FrameworkError("InvalidValues", "contexts", MessageCommandContexts);
598
+ if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
599
+ if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
600
+ if (options.devOnly !== void 0 && typeof options.devOnly !== "boolean") throw new FrameworkTypeError("InvalidType", "devOnly", "boolean", typeof options.devOnly);
601
+ if (!options.contexts) options.contexts = ["Guild"];
602
+ if (options.devOnly === void 0) options.devOnly = false;
603
+ return BaseCommand({
604
+ ...options,
605
+ commandType: "Message"
606
+ });
607
+ }
608
+
609
+ // src/builders/commands/SlashCommand.ts
610
+ import { ApplicationIntegrationType as ApplicationIntegrationType3, InteractionContextType as InteractionContextType3 } from "discord.js";
611
+ function SlashCommand(options) {
612
+ if (!options.commandScope) throw new FrameworkError("InvalidOption", "commandScope");
613
+ if (typeof options.commandScope !== "string" || !CommandScopes.includes(options.commandScope)) throw new FrameworkError("InvalidValue", "commandScope", CommandScopes);
614
+ if (options.commandContexts && !Array.isArray(options.commandContexts)) throw new FrameworkTypeError("InvalidType", "commandContexts", "Array", typeof options.commandContexts);
615
+ if (options.commandContexts && options.commandContexts.some((c) => !CommandContexts.includes(c))) throw new FrameworkError("InvalidValues", "commandContexts", CommandContexts);
616
+ if (options.integrationTypes && !Array.isArray(options.integrationTypes)) throw new FrameworkTypeError("InvalidType", "integrationTypes", "Array", typeof options.integrationTypes);
617
+ if (options.integrationTypes && options.integrationTypes.some((c) => !IntegrationTypes.includes(c))) throw new FrameworkError("InvalidValues", "integrationTypes", IntegrationTypes);
618
+ if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
619
+ if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
620
+ options.options = normalizeOptions(options.options);
621
+ if (!options.commandContexts || !options.commandContexts.length) options.commandContexts = [InteractionContextType3.Guild];
622
+ if (!options.integrationTypes || !options.integrationTypes.length) options.integrationTypes = [ApplicationIntegrationType3.GuildInstall];
623
+ return BaseCommand({
624
+ ...options,
625
+ commandType: "Slash"
626
+ });
627
+ }
628
+
629
+ // src/builders/listeners/Listener.ts
630
+ function Listener(options) {
631
+ if (!options) throw new FrameworkError("NoOptions");
632
+ if (typeof options !== "object") throw new FrameworkTypeError("InvalidType", "options", "object", typeof options);
633
+ if (!options.name || !options.name?.length) throw new FrameworkError("InvalidOption", "name");
634
+ if (typeof options.name !== "string") throw new FrameworkTypeError("InvalidType", "name", "string", typeof options.name);
635
+ if (!options.execute) throw new FrameworkError("InvalidOption", "execute");
636
+ if (typeof options.execute !== "function") throw new FrameworkTypeError("InvalidType", "execute", "function", typeof options.execute);
637
+ if (options.once !== void 0 && typeof options.once !== "boolean") throw new FrameworkTypeError("InvalidType", "once", "boolean", typeof options.once);
638
+ if (options.disabled !== void 0 && typeof options.disabled !== "boolean") throw new FrameworkTypeError("InvalidType", "disabled", "boolean", typeof options.disabled);
639
+ return {
640
+ id: `Client:${options.name}`,
641
+ name: options.name,
642
+ once: options.once ?? false,
643
+ disabled: options.disabled ?? false,
644
+ execute: options.execute
645
+ };
646
+ }
647
+
648
+ // src/extensions/index.ts
649
+ import { Message as Message3 } from "discord.js";
650
+
618
651
  // src/extensions/Message.ts
619
- var import_discord6 = require("discord.js");
652
+ import { MessageCollector, InteractionCollector, InteractionType } from "discord.js";
620
653
  function prefix() {
621
654
  return this.client.prefix;
622
655
  }
@@ -628,7 +661,7 @@ function awaitMemberResponse(options = {}) {
628
661
  if (!this.channel) {
629
662
  return reject(new Error("Channel not available for this message."));
630
663
  }
631
- const collector = new import_discord6.MessageCollector(this.channel, {
664
+ const collector = new MessageCollector(this.channel, {
632
665
  time: 6e4,
633
666
  filter: (m) => m.author.id === this.author.id && (m.content || "").length > 0,
634
667
  ...options,
@@ -646,19 +679,19 @@ function awaitMemberResponse(options = {}) {
646
679
  });
647
680
  }
648
681
  function createModalSubmitCollector(options = {}) {
649
- return new import_discord6.InteractionCollector(this.client, {
682
+ return new InteractionCollector(this.client, {
650
683
  ...options,
651
- interactionType: import_discord6.InteractionType.ModalSubmit,
684
+ interactionType: InteractionType.ModalSubmit,
652
685
  message: this
653
686
  });
654
687
  }
655
688
  function awaitModalSubmitComponent(options = {}) {
656
689
  return new Promise((resolve, reject) => {
657
- const collector = new import_discord6.InteractionCollector(this.client, {
690
+ const collector = new InteractionCollector(this.client, {
658
691
  time: 6e4,
659
692
  filter: (i) => i.user.id === this.author.id,
660
693
  ...options,
661
- interactionType: import_discord6.InteractionType.ModalSubmit,
694
+ interactionType: InteractionType.ModalSubmit,
662
695
  message: this,
663
696
  max: 1
664
697
  });
@@ -669,7 +702,9 @@ function awaitModalSubmitComponent(options = {}) {
669
702
  });
670
703
  });
671
704
  }
672
- Object.defineProperties(import_discord6.Message.prototype, {
705
+
706
+ // src/extensions/index.ts
707
+ Object.defineProperties(Message3.prototype, {
673
708
  prefix: { get: prefix, configurable: true },
674
709
  isDeveloper: { value: isDeveloper, writable: true, configurable: true },
675
710
  awaitMemberResponse: { value: awaitMemberResponse, writable: true, configurable: true },
@@ -677,25 +712,37 @@ Object.defineProperties(import_discord6.Message.prototype, {
677
712
  awaitModalSubmitComponent: { value: awaitModalSubmitComponent, writable: true, configurable: true }
678
713
  });
679
714
 
680
- // src/Builders.ts
681
- var import_discord7 = require("discord.js");
682
- // Annotate the CommonJS export names for ESM import in node:
683
- 0 && (module.exports = {
684
- AttachmentOption,
715
+ // src/index.ts
716
+ import {
717
+ SlashCommandAttachmentOption,
718
+ SlashCommandBooleanOption,
719
+ SlashCommandChannelOption,
720
+ SlashCommandIntegerOption,
721
+ SlashCommandMentionableOption,
722
+ SlashCommandNumberOption,
723
+ SlashCommandRoleOption,
724
+ SlashCommandStringOption,
725
+ SlashCommandUserOption,
726
+ SlashCommandSubcommandBuilder,
727
+ SlashCommandSubcommandGroupBuilder
728
+ } from "discord.js";
729
+ export {
730
+ SlashCommandAttachmentOption as AttachmentOption,
685
731
  Autocompleter,
686
- BooleanOption,
687
- ChannelOption,
732
+ SlashCommandBooleanOption as BooleanOption,
733
+ SlashCommandChannelOption as ChannelOption,
688
734
  ContextCommand,
689
735
  FrameworkClient,
690
- IntegerOption,
736
+ SlashCommandIntegerOption as IntegerOption,
691
737
  Listener,
692
- MentionableOption,
738
+ SlashCommandMentionableOption as MentionableOption,
693
739
  MessageCommand,
694
- NumberOption,
695
- RoleOption,
740
+ SlashCommandNumberOption as NumberOption,
741
+ SlashCommandRoleOption as RoleOption,
696
742
  SlashCommand,
697
- StringOption,
698
- SubcommandBuilder,
699
- SubcommandGroupBuilder,
700
- UserOption
701
- });
743
+ SlashCommandStringOption as StringOption,
744
+ SlashCommandSubcommandBuilder as SubcommandBuilder,
745
+ SlashCommandSubcommandGroupBuilder as SubcommandGroupBuilder,
746
+ SlashCommandUserOption as UserOption
747
+ };
748
+ //# sourceMappingURL=index.js.map