@carzo/enire 3.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.
Files changed (42) hide show
  1. package/README.md +57 -0
  2. package/lib/classes/Client.d.ts +37 -0
  3. package/lib/classes/Client.js +125 -0
  4. package/lib/classes/Context.d.ts +24 -0
  5. package/lib/classes/Context.js +87 -0
  6. package/lib/classes/Cooldowns.d.ts +22 -0
  7. package/lib/classes/Cooldowns.js +1 -0
  8. package/lib/classes/Errors.d.ts +135 -0
  9. package/lib/classes/Errors.js +1 -0
  10. package/lib/classes/HelpCommand.d.ts +15 -0
  11. package/lib/classes/HelpCommand.js +1 -0
  12. package/lib/classes/Loader.d.ts +85 -0
  13. package/lib/classes/Loader.js +302 -0
  14. package/lib/classes/Plugins.d.ts +52 -0
  15. package/lib/classes/Plugins.js +107 -0
  16. package/lib/classes/Utils.d.ts +25 -0
  17. package/lib/classes/Utils.js +563 -0
  18. package/lib/classes/builders/CommandBuilder.d.ts +44 -0
  19. package/lib/classes/builders/CommandBuilder.js +91 -0
  20. package/lib/classes/builders/EventBuilder.d.ts +19 -0
  21. package/lib/classes/builders/EventBuilder.js +1 -0
  22. package/lib/classes/builders/GroupBuilder.d.ts +40 -0
  23. package/lib/classes/builders/GroupBuilder.js +72 -0
  24. package/lib/classes/builders/InteractionBuilder.d.ts +32 -0
  25. package/lib/classes/builders/InteractionBuilder.js +1 -0
  26. package/lib/classes/builders/ParamsBuilder.d.ts +87 -0
  27. package/lib/classes/builders/ParamsBuilder.js +1 -0
  28. package/lib/classes/experiments/Confirmator.d.ts +58 -0
  29. package/lib/classes/experiments/Confirmator.js +1 -0
  30. package/lib/classes/experiments/Paginator.d.ts +65 -0
  31. package/lib/classes/experiments/Paginator.js +1 -0
  32. package/lib/events/interactionCreate.d.ts +4 -0
  33. package/lib/events/interactionCreate.js +17 -0
  34. package/lib/events/messageCreate.d.ts +4 -0
  35. package/lib/events/messageCreate.js +17 -0
  36. package/lib/events/messageUpdate.d.ts +4 -0
  37. package/lib/events/messageUpdate.js +17 -0
  38. package/lib/experiments.d.ts +2 -0
  39. package/lib/experiments.js +1 -0
  40. package/lib/main.d.ts +15 -0
  41. package/lib/main.js +22 -0
  42. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # enire
2
+ A modern discord.js-based framework for building hybrid Discord bots with a unified command pipeline.
3
+
4
+ ## Install
5
+ ```bash
6
+ npm install enire@latest
7
+ ```
8
+
9
+ ## Features
10
+ - Unified hybrid pipeline (prefix + slash) for a single execution path
11
+ - Modular command / interaction / event loaders
12
+ - Global and per-command plugins (guards/conditions)
13
+ - Built-in cooldown tracking with buckets
14
+ - Centralized framework error channel (`frameworkError` + `error`)
15
+ - Debug mode hooks (`debug` event)
16
+ - Optional help command
17
+ - Built-in arguments parser
18
+
19
+ ## Example setup
20
+ ```js
21
+ const { Enire, GatewayIntentBits, Partials } = require("enire");
22
+
23
+ const client = new Enire({
24
+ intents: [
25
+ GatewayIntentBits.Guilds,
26
+ GatewayIntentBits.GuildMessages,
27
+ GatewayIntentBits.MessageContent
28
+ ],
29
+ partials: [Partials.Channel],
30
+ prefix: "!",
31
+ debug: true
32
+ });
33
+
34
+ client.load("./files");
35
+
36
+ client.on("frameworkError", (error, ctx) => {
37
+ console.error("Framework error:", error, "Context:", ctx?.command?.data?.name ?? null);
38
+ });
39
+
40
+ client.login("TOKEN");
41
+ ```
42
+
43
+ ## Breaking changes in v3
44
+ - Framework is now branded as **enire** (package name changed from `erine` to `enire`).
45
+ - Runtime execution is unified for prefix and slash commands.
46
+ - Core listeners are internally managed by `Enire` with centralized error forwarding.
47
+ - `Erine` is kept as a compatibility alias of `Enire`, but `Enire` is now the canonical class name.
48
+ - Command/Group builders now support `guards` metadata, and commands support builder-level cooldown metadata.
49
+ - Message-update handling is now routed through the shared message pipeline.
50
+
51
+ ## Migration notes
52
+ - Replace imports from `Erine` with `Enire` when possible.
53
+ - If you had custom error handling on process events, prefer listening to `frameworkError`.
54
+ - If you rely on command plugins only, you can now also define command/group guards directly in builders.
55
+
56
+ ## Disclaimer
57
+ enire is not affiliated with Discord or discord.js.
@@ -0,0 +1,37 @@
1
+ import { Client, ClientOptions, CommandInteraction, Message, Snowflake } from "discord.js";
2
+ import { Context } from "./Context.js";
3
+ import { Loader, Plugin } from "./Loader.js";
4
+ import { HelpCommand } from "./HelpCommand.js";
5
+ import { Cooldowns } from "./Cooldowns.js";
6
+
7
+ export interface EnireRestrictions {
8
+ userIDs: Set<Snowflake>;
9
+ guildIDs: Set<Snowflake>;
10
+ }
11
+
12
+ export interface EnireOptions extends ClientOptions {
13
+ autoSync?: boolean;
14
+ context?: typeof Context;
15
+ guildOnly?: boolean;
16
+ owners?: Snowflake[];
17
+ prefix: string | string[] | ((ctx: Context) => Promise<string> | string);
18
+ replyOnEdit?: boolean;
19
+ helpCommand?: typeof HelpCommand;
20
+ restrictions?: EnireRestrictions;
21
+ debug?: boolean;
22
+ }
23
+
24
+ export declare class Enire extends Client {
25
+ cooldowns: Cooldowns;
26
+ loader: Loader;
27
+ ops: EnireOptions;
28
+ constructor(options: EnireOptions);
29
+ addGlobalPlugins(plugins: Plugin[]): this;
30
+ getContext(data: CommandInteraction | Message): Context;
31
+ load(dir: string, reload?: boolean): Promise<import("./Loader.js").ModuleData<import("./builders/InteractionBuilder.js").InteractionBuilder | import("./builders/CommandBuilder.js").CommandBuilder | import("./builders/EventBuilder.js").EventBuilder | import("./builders/GroupBuilder.js").GroupBuilder, any[]>[]>;
32
+ sync(guildIDs?: string[]): Promise<void>;
33
+ handleFrameworkError(error: unknown, ctx?: Context | null): void;
34
+ login(token: string): Promise<string>;
35
+ }
36
+
37
+ export { Enire as Erine };
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Erine = exports.Enire = void 0;
4
+
5
+ const discord_js_1 = require("discord.js");
6
+ const Context_js_1 = require("./Context.js");
7
+ const Loader_js_1 = require("./Loader.js");
8
+ const Cooldowns_js_1 = require("./Cooldowns.js");
9
+ const Utils_js_1 = require("./Utils.js");
10
+
11
+ let processHandlersBound = false;
12
+
13
+ class Enire extends discord_js_1.Client {
14
+ cooldowns = new Cooldowns_js_1.Cooldowns(this);
15
+ loader = new Loader_js_1.Loader({ client: this });
16
+ ops;
17
+ #coreListenersBound = false;
18
+
19
+ constructor(options) {
20
+ super(options);
21
+ this.ops = options;
22
+
23
+ if (this.ops.guildOnly === undefined) this.ops.guildOnly = true;
24
+ if (typeof this.ops.debug !== "boolean") this.ops.debug = false;
25
+ }
26
+
27
+ addGlobalPlugins(plugins) {
28
+ this.loader.globalPlugins.push(...plugins);
29
+ return this;
30
+ }
31
+
32
+ getContext(data) {
33
+ return new (this.ops.context || Context_js_1.Context)(this, data);
34
+ }
35
+
36
+ async load(dir, reload = false) {
37
+ if (!dir) throw new SyntaxError("Missing module path in Enire#load!");
38
+ return this.loader.load(dir, reload);
39
+ }
40
+
41
+ async sync(guildIDs) {
42
+ await this.loader.sync(guildIDs);
43
+ }
44
+
45
+ handleFrameworkError(error, ctx = null) {
46
+ if (this.ops.debug) {
47
+ const summary = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
48
+ this.emit("debug", `[enire] ${summary}`);
49
+ }
50
+
51
+ this.emit("frameworkError", error, ctx);
52
+ this.emit("error", error);
53
+ }
54
+
55
+ #bindCoreListeners() {
56
+ if (this.#coreListenersBound) return;
57
+
58
+ this.on("messageCreate", async (message) => {
59
+ try {
60
+ await Utils_js_1.Utils.handleMessage(this, message, false);
61
+ } catch (error) {
62
+ this.handleFrameworkError(error, error?.ctx ?? null);
63
+ }
64
+ });
65
+
66
+ if (this.ops.replyOnEdit) {
67
+ this.on("messageUpdate", async (_oldMessage, newMessage) => {
68
+ try {
69
+ await Utils_js_1.Utils.handleMessage(this, newMessage, true);
70
+ } catch (error) {
71
+ this.handleFrameworkError(error, error?.ctx ?? null);
72
+ }
73
+ });
74
+ }
75
+
76
+ this.on("interactionCreate", async (interaction) => {
77
+ try {
78
+ await Utils_js_1.Utils.handleInteraction(this, interaction);
79
+ } catch (error) {
80
+ this.handleFrameworkError(error, error?.ctx ?? null);
81
+ }
82
+ });
83
+
84
+ this.#coreListenersBound = true;
85
+ }
86
+
87
+ #bindProcessHandlers() {
88
+ if (processHandlersBound) return;
89
+
90
+ process.on("uncaughtException", (error) => this.handleFrameworkError(error));
91
+ process.on("unhandledRejection", (error) => this.handleFrameworkError(error));
92
+
93
+ processHandlersBound = true;
94
+ }
95
+
96
+ #registerHelpCommand() {
97
+ if (!this.ops.helpCommand) return;
98
+
99
+ const help = new this.ops.helpCommand();
100
+ if (!this.loader.commands.normal) this.loader.commands.normal = new discord_js_1.Collection();
101
+
102
+ this.loader.commands.normal.set("help", {
103
+ data: help.data,
104
+ params: help.params,
105
+ plugins: help.plugins,
106
+ code: help.code.bind(help),
107
+ });
108
+ }
109
+
110
+ async login(token) {
111
+ this.#bindProcessHandlers();
112
+ this.#bindCoreListeners();
113
+ this.#registerHelpCommand();
114
+
115
+ if (this.ops.debug) {
116
+ this.rest.on("rateLimited", (details) => {
117
+ this.emit("debug", `[enire] Rate limited: ${JSON.stringify(details)}`);
118
+ });
119
+ }
120
+
121
+ return super.login(token);
122
+ }
123
+ }
124
+ exports.Enire = Enire;
125
+ exports.Erine = Enire;
@@ -0,0 +1,24 @@
1
+ import { Command, Types } from "../classes/Loader.js";
2
+ import * as P from "./builders/ParamsBuilder.js";
3
+ import { Enire } from "./Client.js";
4
+ import * as DJS from "discord.js";
5
+
6
+ export declare class Context {
7
+ bot: Enire;
8
+ args: string[] | null;
9
+ data: DJS.Message | DJS.CommandInteraction;
10
+ prefix: string;
11
+ command: Command<Types.Normal> | null;
12
+ parent: Command<Types.Group> | null;
13
+ params: P.BaseParam[] | null;
14
+ constructor(bot: Enire, data: DJS.Message | DJS.CommandInteraction);
15
+ get message(): DJS.Message | null;
16
+ get interaction(): DJS.CommandInteraction | null;
17
+ get author(): DJS.User;
18
+ get channel(): DJS.TextBasedChannel | null;
19
+ get member(): DJS.GuildMember | DJS.APIInteractionGuildMember | null;
20
+ get guild(): DJS.Guild | null;
21
+ send(payload: string | DJS.MessagePayload | DJS.MessageCreateOptions | DJS.InteractionReplyOptions | DJS.InteractionEditReplyOptions): Promise<DJS.Message<boolean>>;
22
+ react(...emojis: string[]): Promise<DJS.MessageReaction | undefined>;
23
+ get<T>(param: string): T | null;
24
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Context = void 0;
4
+
5
+ const tslib_1 = require("tslib");
6
+ const DJS = tslib_1.__importStar(require("discord.js"));
7
+
8
+ class Context {
9
+ bot;
10
+ args;
11
+ data;
12
+ prefix = "";
13
+ command;
14
+ parent = null;
15
+ params;
16
+
17
+ constructor(bot, data) {
18
+ this.bot = bot;
19
+ this.data = data;
20
+ this.command = null;
21
+ this.params = this.data instanceof DJS.Message ? [] : [];
22
+ this.args = this.data instanceof DJS.Message ? [] : null;
23
+ }
24
+
25
+ get message() {
26
+ return this.data instanceof DJS.Message ? this.data : null;
27
+ }
28
+
29
+ get interaction() {
30
+ return this.data instanceof DJS.Message ? null : this.data;
31
+ }
32
+
33
+ get author() {
34
+ return this.data instanceof DJS.Message ? this.data.author : this.data.user;
35
+ }
36
+
37
+ get channel() {
38
+ return this.data.channel || null;
39
+ }
40
+
41
+ get member() {
42
+ return this.data.member || null;
43
+ }
44
+
45
+ get guild() {
46
+ return this.data.guild || null;
47
+ }
48
+
49
+ async send(payload) {
50
+ if (this.data instanceof DJS.Message) {
51
+ return this.data.channel.send(payload);
52
+ }
53
+
54
+ if (this.data.replied || this.data.deferred) {
55
+ return this.data.editReply(payload);
56
+ }
57
+
58
+ return this.data.reply(payload);
59
+ }
60
+
61
+ async react(...emojis) {
62
+ if (!(this.data instanceof DJS.Message)) return undefined;
63
+
64
+ let lastReaction;
65
+ for (const emoji of emojis) {
66
+ lastReaction = await this.data.react(emoji);
67
+ }
68
+
69
+ return lastReaction;
70
+ }
71
+
72
+ get(param) {
73
+ const lowered = param.toLowerCase();
74
+
75
+ if (this.params?.length) {
76
+ return this.params.find((entry) => entry.name.toLowerCase() === lowered)?.value ?? null;
77
+ }
78
+
79
+ if (this.data instanceof DJS.Message) return null;
80
+
81
+ const option = this.data.options?.data?.find((entry) => entry.name.toLowerCase() === lowered);
82
+ if (!option) return null;
83
+
84
+ return option.attachment ?? option.member ?? option.channel ?? option.role ?? option.user ?? option.value ?? null;
85
+ }
86
+ }
87
+ exports.Context = Context;
@@ -0,0 +1,22 @@
1
+ import { Erine } from "./Client";
2
+ import { Collection } from "discord.js";
3
+ export declare enum Bucket {
4
+ Member = "MEMBER",
5
+ User = "USER",
6
+ Guild = "GUILD",
7
+ Channel = "CHANNEL"
8
+ }
9
+ export declare class Cooldowns {
10
+ bot: Erine;
11
+ track: Collection<string, number>;
12
+ constructor(bot: Erine);
13
+ getCooldownSource(command: string, id: string, bucket: Bucket): Promise<number | undefined>;
14
+ setCooldownSource(command: string, id: string, bucket: Bucket, time: number): Promise<void>;
15
+ check(command: string, id: string, cooldown: number, bucket: Bucket): Promise<{
16
+ command: string;
17
+ id: string;
18
+ time: number;
19
+ bucket: Bucket;
20
+ left: number;
21
+ } | null>;
22
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Cooldowns=exports.Bucket=void 0;const discord_js_1=require("discord.js");var Bucket;!function(e){e.Member="MEMBER",e.User="USER",e.Guild="GUILD",e.Channel="CHANNEL"}(Bucket||(exports.Bucket=Bucket={}));class Cooldowns{bot;track=new discord_js_1.Collection;constructor(e){this.bot=e}async getCooldownSource(e,o,t){return this.track.get(e+`#${t}#`+o)}async setCooldownSource(e,o,t,s){this.track.set(e+`#${t}#`+o,Date.now()),setTimeout(()=>this.track.delete(e+`#${t}#`+o),s)}async check(e,o,t,s){var c=await this.getCooldownSource(e,o,s);return c&&Date.now()-c<t?{command:e,id:o,time:t,bucket:s,left:t-(Date.now()-c)}:null}}exports.Cooldowns=Cooldowns;
@@ -0,0 +1,135 @@
1
+ import { Channel, ChannelType, Guild, PermissionResolvable, User } from "discord.js";
2
+ import { BaseParam, ChannelParam } from "./builders/ParamsBuilder.js";
3
+ import { Context } from "./Context.js";
4
+ declare class GuildOnly extends Error {
5
+ ctx: Context;
6
+ constructor(context: Context, message?: string);
7
+ get user(): User;
8
+ }
9
+ declare class NotOwner extends Error {
10
+ ctx: Context;
11
+ constructor(context: Context, message?: string);
12
+ get user(): User;
13
+ }
14
+ declare class CommandNotFound extends Error {
15
+ ctx: Context;
16
+ provided: string;
17
+ constructor(context: Context, provided: string, message?: string);
18
+ }
19
+ declare class UnknownCommandError extends Error {
20
+ ctx: Context;
21
+ error: any;
22
+ constructor(context: Context, error: any, message?: string);
23
+ }
24
+ declare class MissingRequiredParam extends Error {
25
+ ctx: Context;
26
+ param: BaseParam;
27
+ constructor(context: Context, param: BaseParam, message?: string);
28
+ }
29
+ declare class InvalidParam extends Error {
30
+ ctx: Context;
31
+ metadata: Record<string, any>;
32
+ constructor(context: Context, message?: string, metadata?: Record<string, any>);
33
+ }
34
+ declare class InvalidParamNumber extends Error {
35
+ ctx: Context;
36
+ param: BaseParam;
37
+ constructor(context: Context, param: BaseParam, message?: string);
38
+ }
39
+ declare class InvalidParamBoolean extends Error {
40
+ ctx: Context;
41
+ param: BaseParam;
42
+ constructor(context: Context, param: BaseParam, message?: string);
43
+ }
44
+ declare class InvalidParamChoice extends Error {
45
+ ctx: Context;
46
+ param: BaseParam;
47
+ choices: {
48
+ name: string;
49
+ value: any;
50
+ }[];
51
+ constructor(context: Context, param: BaseParam, choices: {
52
+ name: string;
53
+ value: any;
54
+ }[], message?: string);
55
+ }
56
+ declare class InvalidParamMember extends Error {
57
+ ctx: Context;
58
+ param: BaseParam;
59
+ constructor(context: Context, param: BaseParam, message?: string);
60
+ }
61
+ declare class InvalidParamChannel extends Error {
62
+ ctx: Context;
63
+ param: BaseParam;
64
+ constructor(context: Context, param: BaseParam, message?: string);
65
+ }
66
+ declare class InvalidParamRole extends Error {
67
+ ctx: Context;
68
+ param: BaseParam;
69
+ constructor(context: Context, param: BaseParam, message?: string);
70
+ }
71
+ declare class InvalidChannelType extends Error {
72
+ ctx: Context;
73
+ param: ChannelParam;
74
+ provided: ChannelType;
75
+ expected: ChannelType[];
76
+ constructor(context: Context, param: ChannelParam, provided: ChannelType, expected: ChannelType[], message?: string);
77
+ }
78
+ declare class InvalidParamAttachment extends Error {
79
+ ctx: Context;
80
+ param: BaseParam;
81
+ constructor(context: Context, param: BaseParam, message?: string);
82
+ }
83
+ declare class MissingPermission extends Error {
84
+ ctx: Context;
85
+ permissions: PermissionResolvable[];
86
+ constructor(context: Context, perms: PermissionResolvable[], message?: string);
87
+ }
88
+ declare class MissingChannelPermission extends Error {
89
+ ctx: Context;
90
+ permissions: PermissionResolvable[];
91
+ channel: Channel;
92
+ constructor(context: Context, perms: PermissionResolvable[], channel: Channel, message?: string);
93
+ }
94
+ declare class MissingBotPermission extends Error {
95
+ ctx: Context;
96
+ permissions: PermissionResolvable[];
97
+ constructor(context: Context, perms: PermissionResolvable[], message?: string);
98
+ }
99
+ declare class MissingBotChannelPermission extends Error {
100
+ ctx: Context;
101
+ permissions: PermissionResolvable[];
102
+ channel: Channel;
103
+ constructor(context: Context, perms: PermissionResolvable[], channel: Channel, message?: string);
104
+ }
105
+ declare class NotNSFW extends Error {
106
+ ctx: Context;
107
+ constructor(context: Context, message?: string);
108
+ }
109
+ declare class NotInChannelType extends Error {
110
+ ctx: Context;
111
+ types: ChannelType[];
112
+ channel: Channel;
113
+ constructor(ctx: Context, types: ChannelType[], channel: Channel, message?: string);
114
+ }
115
+ declare class OnlyForIDs extends Error {
116
+ ctx: Context;
117
+ snowflakes: string[];
118
+ constructor(context: Context, snowflakes: string[], message?: string);
119
+ }
120
+ declare class CommandInCooldown extends Error {
121
+ ctx: Context;
122
+ timeLeft: number;
123
+ constructor(context: Context, timeLeft: number, message?: string);
124
+ }
125
+ declare class RestrictedUser extends Error {
126
+ ctx: Context;
127
+ user: User;
128
+ constructor(ctx: Context, user: User, message?: string);
129
+ }
130
+ declare class RestrictedGuild extends Error {
131
+ ctx: Context;
132
+ guild: Guild;
133
+ constructor(ctx: Context, guild: Guild, message?: string);
134
+ }
135
+ export { InvalidParam, GuildOnly, NotOwner, CommandNotFound, UnknownCommandError, MissingRequiredParam, InvalidParamNumber, InvalidParamChoice, MissingPermission, MissingChannelPermission, MissingBotPermission, MissingBotChannelPermission, InvalidParamBoolean, InvalidParamMember, InvalidParamChannel, InvalidParamRole, InvalidChannelType, InvalidParamAttachment, NotNSFW, NotInChannelType, OnlyForIDs, CommandInCooldown, RestrictedUser, RestrictedGuild };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RestrictedGuild=exports.RestrictedUser=exports.CommandInCooldown=exports.OnlyForIDs=exports.NotInChannelType=exports.NotNSFW=exports.InvalidParamAttachment=exports.InvalidChannelType=exports.InvalidParamRole=exports.InvalidParamChannel=exports.InvalidParamMember=exports.InvalidParamBoolean=exports.MissingBotChannelPermission=exports.MissingBotPermission=exports.MissingChannelPermission=exports.MissingPermission=exports.InvalidParamChoice=exports.InvalidParamNumber=exports.MissingRequiredParam=exports.UnknownCommandError=exports.CommandNotFound=exports.NotOwner=exports.GuildOnly=exports.InvalidParam=void 0;class GuildOnly extends Error{ctx;constructor(s,e="This command is only available in guilds."){super(e),this.ctx=s}get user(){return this.ctx.author}}exports.GuildOnly=GuildOnly;class NotOwner extends Error{ctx;constructor(s,e="Someone that is not register as owner tried to use this command."){super(e),this.ctx=s}get user(){return this.ctx.author}}exports.NotOwner=NotOwner;class CommandNotFound extends Error{ctx;provided;constructor(s,e,r="That command doesn't exist."){super(r),this.ctx=s,this.provided=e}}exports.CommandNotFound=CommandNotFound;class UnknownCommandError extends Error{ctx;error;constructor(s,e,r="An unknown error"){super(r),this.ctx=s,this.error=e}}exports.UnknownCommandError=UnknownCommandError;class MissingRequiredParam extends Error{ctx;param;constructor(s,e,r="You have to provide all required parameters."){super(r),this.ctx=s,this.param=e}}exports.MissingRequiredParam=MissingRequiredParam;class InvalidParam extends Error{ctx;metadata;constructor(s,e="Some parameter is invalid in arguments provided.",r={}){super(e),this.ctx=s,this.metadata=r}}exports.InvalidParam=InvalidParam;class InvalidParamNumber extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't a valid number."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamNumber=InvalidParamNumber;class InvalidParamBoolean extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't boolean."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamBoolean=InvalidParamBoolean;class InvalidParamChoice extends Error{ctx;param;choices;constructor(s,e,r,t="Some parameter in that command isn't a valid choice."){super(t),this.ctx=s,this.param=e,this.choices=r}}exports.InvalidParamChoice=InvalidParamChoice;class InvalidParamMember extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't a valid member."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamMember=InvalidParamMember;class InvalidParamChannel extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't a valid channel."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamChannel=InvalidParamChannel;class InvalidParamRole extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't a valid role."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamRole=InvalidParamRole;class InvalidChannelType extends Error{ctx;param;provided;expected;constructor(s,e,r,t,n="Some parameter in that command isn't a valid channel type allowed."){super(n),this.ctx=s,this.param=e,this.provided=r,this.expected=t}}exports.InvalidChannelType=InvalidChannelType;class InvalidParamAttachment extends Error{ctx;param;constructor(s,e,r="Some parameter in that command isn't a valid attachment."){super(r),this.ctx=s,this.param=e}}exports.InvalidParamAttachment=InvalidParamAttachment;class MissingPermission extends Error{ctx;permissions;constructor(s,e,r="The command author doesn't have permissions enough to execute this command."){super(r),this.ctx=s,this.permissions=e}}exports.MissingPermission=MissingPermission;class MissingChannelPermission extends Error{ctx;permissions;channel;constructor(s,e,r,t="The command author doesn't have permissions enough in a channel to execute this command."){super(t),this.ctx=s,this.permissions=e,this.channel=r}}exports.MissingChannelPermission=MissingChannelPermission;class MissingBotPermission extends Error{ctx;permissions;constructor(s,e,r="I don't have permissions enough to execute this command."){super(r),this.ctx=s,this.permissions=e}}exports.MissingBotPermission=MissingBotPermission;class MissingBotChannelPermission extends Error{ctx;permissions;channel;constructor(s,e,r,t="I don't have permissions enough in that channel to execute this command."){super(t),this.ctx=s,this.permissions=e,this.channel=r}}exports.MissingBotChannelPermission=MissingBotChannelPermission;class NotNSFW extends Error{ctx;constructor(s,e="This command can only be executed in a NSFW channel."){super(e),this.ctx=s}}exports.NotNSFW=NotNSFW;class NotInChannelType extends Error{ctx;types;channel;constructor(s,e,r,t="This command can only be executed in certain channel types."){super(t),this.ctx=s,this.types=e,this.channel=r}}exports.NotInChannelType=NotInChannelType;class OnlyForIDs extends Error{ctx;snowflakes;constructor(s,e,r="This command can only be used by specified users."){super(r),this.ctx=s,this.snowflakes=e}}exports.OnlyForIDs=OnlyForIDs;class CommandInCooldown extends Error{ctx;timeLeft;constructor(s,e,r="This command is in cooldown."){super(r),this.ctx=s,this.timeLeft=e}}exports.CommandInCooldown=CommandInCooldown;class RestrictedUser extends Error{ctx;user;constructor(s,e,r="Looks like this user is restricted from bot."){super(r),this.ctx=s,this.user=e}}exports.RestrictedUser=RestrictedUser;class RestrictedGuild extends Error{ctx;guild;constructor(s,e,r="Looks like this guild is restricted from bot."){super(r),this.ctx=s,this.guild=e}}exports.RestrictedGuild=RestrictedGuild;
@@ -0,0 +1,15 @@
1
+ import { type Plugin, CommandBuilder, Context, CommandHelpingObject, GroupHelpingObject, ParamsBuilder } from "../main.js";
2
+ export declare class HelpCommand {
3
+ data: CommandBuilder;
4
+ plugins: Plugin[];
5
+ params: ParamsBuilder;
6
+ code(ctx: Context): Promise<void>;
7
+ sendEmpty(ctx: Context): Promise<void>;
8
+ sendNotFound(ctx: Context): Promise<void>;
9
+ sendCommand(ctx: Context, command: CommandHelpingObject): Promise<void>;
10
+ sendGroup(ctx: Context, group: GroupHelpingObject): Promise<void>;
11
+ getCommand(ctx: Context, q: string): CommandHelpingObject | null;
12
+ getGroup(ctx: Context, q: string): GroupHelpingObject | null;
13
+ private doEmbed;
14
+ private c;
15
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.HelpCommand=void 0;const main_js_1=require("../main.js");class HelpCommand{data=new main_js_1.CommandBuilder({name:"help",aliases:["h"],description:"Shows this command"});plugins=[];params=(new main_js_1.ParamsBuilder).addString({name:"query",description:"An optional command/group/subcommand name",required:!1,ellipsis:!0});async code(a){var e;return a.get("query")?(e=this.getCommand(a,a.get("query")))?this.sendCommand(a,e):(e=this.getGroup(a,a.get("query")))?this.sendGroup(a,e):this.sendNotFound(a):this.sendEmpty(a)}async sendEmpty(a){await a.send({embeds:[this.doEmbed(a).setDescription("Welcome to my help")]})}async sendNotFound(a){await a.send("I was unable to find something related to that!")}async sendCommand(a,e){var t=e.data.aliases.length?`[${[e.data.name].concat(e.data.aliases).join("|")}]`:e.data.name,n=e.group?e.group.data.aliases?.length?`[${[e.group.data.name].concat(e.group.data.aliases).join("|")}] `:e.group.data.name+" ":"",s=e.params?.params.length?e.params.params.map(a=>`**${a.name}**${a.required?"*":"?"} :: `+a.description).join("\n"):null,d=e.params?.params.length?e.params.params.map(a=>""+a.name+(a.required?"*":"?")).join(" "):"";await a.send({embeds:[this.doEmbed(a).setTitle(e.data.name).setDescription(e.data.description).addFields({name:"Usage",value:a.prefix+n+t+" "+d}).addFields({name:"Arguments",value:s||"Without arguments."})]})}async sendGroup(a,e){var t=e.data.aliases?.length?`[${[e.data.name].concat(e.data.aliases).join("|")}] `:e.data.name,n=e.subcommands.map(a=>`\`${e.data.name} ${a.data.name}\` :: `+a.data.description);await a.send({embeds:[this.doEmbed(a).setTitle(t).setDescription(e.data.description).addFields({name:"Subcommands",value:n.length?n.join("\n"):"Without sub commands."})]})}getCommand(a,e){let t=a.bot.loader.walkCommands();return e=this.c(e),(a=t.find(a=>!a.group&&this.c(a.data.name)==e||a.data.aliases.map(this.c).includes(e)))||(t=t.filter(a=>a.group).map(a=>({...a,regexp:new RegExp(`^(${(a.group.data.aliases||[]).concat(a.group.data.name).join("|")})( +)(${(a.data.aliases||[]).concat(a.data.name).join("|")})$`,"gi"),full:a.group.data.name+" "+a.data.name}))).find(a=>a.regexp.test(e))||null}getGroup(a,e){e=this.c(e);let t=a.bot.loader.walkCommands().filter(a=>a.group).map(a=>a.group).find(a=>this.c(a.data.name)==e||a.data.aliases?.map(this.c).includes(e));return t?(a=a.bot.loader.walkCommands().filter(a=>a.group&&a.group.data.name==t.data.name).map(a=>({...a,regexp:new RegExp(`^(${(a.group.data.aliases||[]).concat(a.group.data.name).join("|")})( +)(${(a.data.aliases||[]).concat(a.data.name).join("|")})$`,"gi"),full:a.group.data.name+" "+a.data.name})),{...t,subcommands:a}):null}doEmbed(a){return(new main_js_1.EmbedBuilder).setAuthor({name:a.author.username,iconURL:a.author.displayAvatarURL()}).setTimestamp().setColor("Blurple").setFooter({text:a.bot.user?.username+"'s Help",iconURL:a.bot.user.displayAvatarURL()})}c(a){return a.toLowerCase().trim()}}exports.HelpCommand=HelpCommand;
@@ -0,0 +1,85 @@
1
+ import { InteractionBuilder } from "./builders/InteractionBuilder.js";
2
+ import { Collection, REST } from "discord.js";
3
+ import { CommandBuilder } from "./builders/CommandBuilder.js";
4
+ import { ParamsBuilder } from "./builders/ParamsBuilder.js";
5
+ import { EventBuilder } from "./builders/EventBuilder.js";
6
+ import { GroupBuilder } from "./builders/GroupBuilder.js";
7
+ import { Plugins as EnirePlugins } from "../main.js";
8
+ import { Context } from "./Context.js";
9
+ import { Enire } from "./Client.js";
10
+
11
+ export interface ModuleData<T extends unknown = unknown, K extends any[] = any[]> {
12
+ data: CommandBuilder | GroupBuilder | InteractionBuilder | EventBuilder;
13
+ plugins?: T extends CommandBuilder ? (typeof EnirePlugins[] | Plugin[]) : never;
14
+ params?: T extends CommandBuilder ? ParamsBuilder : never;
15
+ code?: T extends CommandBuilder
16
+ ? (ctx: Context) => Promise<void>
17
+ : T extends InteractionBuilder
18
+ ? (interaction: any) => Promise<void>
19
+ : T extends EventBuilder
20
+ ? (bot: Enire, ...args: K) => Promise<void>
21
+ : undefined;
22
+ }
23
+
24
+ export type AsyncFunction<S, T> = (args: S) => Promise<T>;
25
+ export type SyncFunction<S, T> = (args: S) => T;
26
+ export type Plugin = AsyncFunction<Context, boolean> | SyncFunction<Context, boolean> | Promise<(ctx: Context) => Promise<boolean>>;
27
+
28
+ export interface CommandStructures {
29
+ normal: {
30
+ data: CommandBuilder;
31
+ params?: ParamsBuilder;
32
+ plugins?: Plugin[];
33
+ code: (ctx: Context) => Promise<void>;
34
+ };
35
+ group: {
36
+ data: GroupBuilder;
37
+ };
38
+ }
39
+
40
+ export declare enum Types {
41
+ Normal = "normal",
42
+ Group = "group"
43
+ }
44
+
45
+ export type Command<K extends keyof CommandStructures = "normal"> = CommandStructures[K];
46
+
47
+ interface EnireCollected {
48
+ normal: Collection<string, Command<"normal">> | null;
49
+ group: Collection<string, Command<"group">> | null;
50
+ }
51
+
52
+ interface LoaderOptions {
53
+ client: Enire;
54
+ }
55
+
56
+ export interface CommandHelpingObject extends Command<Types.Normal> {
57
+ group: Command<Types.Group> | null;
58
+ }
59
+
60
+ type ErineInteractionTypes =
61
+ | "autocomplete"
62
+ | "button"
63
+ | "chatInput"
64
+ | "messageContextMenu"
65
+ | "modalSubmit"
66
+ | "userContextMenu"
67
+ | "channelSelectMenu"
68
+ | "roleSelectMenu"
69
+ | "stringSelectMenu"
70
+ | "userSelectMenu"
71
+ | "mentionableSelectMenu"
72
+ | "anyInteraction";
73
+
74
+ export declare class Loader {
75
+ client: Enire;
76
+ commands: EnireCollected;
77
+ interactions: Record<ErineInteractionTypes, Collection<string, ModuleData<InteractionBuilder>>>;
78
+ globalPlugins: Plugin[];
79
+ listeners: Collection<string, ModuleData<InteractionBuilder>> | null;
80
+ rest: REST;
81
+ constructor(options: LoaderOptions);
82
+ load(dir: string, reload?: boolean): Promise<ModuleData<InteractionBuilder | CommandBuilder | EventBuilder | GroupBuilder, any[]>[]>;
83
+ walkCommands(callable?: (command: Command<Types>) => number): CommandHelpingObject[];
84
+ sync(guildIDs?: string[]): Promise<void>;
85
+ }