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