@arox/framework 0.1.0-alpha.1 → 0.1.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.
@@ -0,0 +1,4 @@
1
+ import { Client } from "./structures/Client";
2
+ export declare let currentClient: Client | null;
3
+ export declare function setClient(client: Client): void;
4
+ export declare function clearClient(): void;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get clearClient () {
13
+ return clearClient;
14
+ },
15
+ get currentClient () {
16
+ return currentClient;
17
+ },
18
+ get setClient () {
19
+ return setClient;
20
+ }
21
+ });
22
+ let currentClient = null;
23
+ function setClient(client) {
24
+ currentClient = client;
25
+ }
26
+ function clearClient() {
27
+ currentClient = null;
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _discord = require("discord.js");
6
+ const _Event = require("../structures/Event");
7
+ const _Context = require("../structures/Context");
8
+ new _Event.EventBuilder(_discord.Events.InteractionCreate, false).onExecute(async function(context, interaction) {
9
+ if (!interaction.isChatInputCommand()) return;
10
+ const command = context.client.commands.get(interaction.commandName);
11
+ if (!command || !command.supportsSlash) {
12
+ await interaction.reply({
13
+ content: "Command not found or disabled.",
14
+ ephemeral: true
15
+ });
16
+ return;
17
+ }
18
+ try {
19
+ const ctx = new _Context.Context(context.client, {
20
+ interaction
21
+ });
22
+ if (command._onInteraction) await command._onInteraction(ctx.toJSON());
23
+ } catch (error) {
24
+ context.client.logger.error(`Error executing command ${command.name}:`, error);
25
+ if (interaction.replied || interaction.deferred) {
26
+ await interaction.followUp({
27
+ content: "There was an error while executing this command!",
28
+ ephemeral: true
29
+ });
30
+ } else {
31
+ await interaction.reply({
32
+ content: "There was an error while executing this command!",
33
+ ephemeral: true
34
+ });
35
+ }
36
+ }
37
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _discord = require("discord.js");
6
+ const _Event = require("../structures/Event");
7
+ const _Context = require("../structures/Context");
8
+ const _util = require("../utils/util");
9
+ new _Event.EventBuilder(_discord.Events.MessageCreate, false, async function(context, message) {
10
+ if (message.author.bot) return;
11
+ const prefix = context.client.prefix;
12
+ if (typeof prefix !== "string" || prefix.length === 0 || !message.content.startsWith(prefix)) return;
13
+ const args = message.content.slice(prefix.length).trim().split(/ +/);
14
+ const commandName = args.shift()?.toLowerCase();
15
+ if (!commandName) return;
16
+ const commandAlias = context.client.aliases.findKey((cmd)=>cmd.has(commandName));
17
+ let command = context.client.commands.get(commandAlias ?? commandName);
18
+ if (!command || !command.supportsPrefix) {
19
+ await message.reply({
20
+ content: "Command not found or disabled.",
21
+ allowedMentions: {
22
+ repliedUser: false
23
+ }
24
+ }).then(_util.deleteMessage);
25
+ return;
26
+ }
27
+ try {
28
+ const ctx = new _Context.Context(context.client, {
29
+ message,
30
+ args
31
+ });
32
+ context.logger.debug(`${ctx.author?.tag ?? "Unknown"} used ${command.name}(message)`);
33
+ if (command._onMessage) await command._onMessage(ctx.toJSON());
34
+ } catch (error) {
35
+ context.client.logger.error(`Error executing command ${command.name}:`, error);
36
+ }
37
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _discord = require("discord.js");
6
+ const _Event = require("../structures/Event");
7
+ new _Event.EventBuilder(_discord.Events.ClientReady).onExecute(async function(context) {
8
+ if (context.client.options.autoRegisterCommands) {
9
+ await context.client.registerCommands();
10
+ }
11
+ });
package/dist/index.d.ts CHANGED
@@ -1 +1,8 @@
1
+ export * from "./structures/Client";
2
+ export * from "./structures/Command";
3
+ export * from "./structures/Context";
4
+ export * from "./structures/Event";
5
+ export * from "./structures/Argument";
6
+ export * from "./utils/logger/Logger";
7
+ export * from "./context";
1
8
  export declare const version = "[VI]{{version}}[/VI]";
package/dist/index.js CHANGED
@@ -1 +1,19 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"version",{enumerable:true,get:function(){return version}});const version="v0.1.0-alpha.1";
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "version", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return version;
9
+ }
10
+ });
11
+ const _export_star = require("@swc/helpers/_/_export_star");
12
+ _export_star._(require("./structures/Client"), exports);
13
+ _export_star._(require("./structures/Command"), exports);
14
+ _export_star._(require("./structures/Context"), exports);
15
+ _export_star._(require("./structures/Event"), exports);
16
+ _export_star._(require("./structures/Argument"), exports);
17
+ _export_star._(require("./utils/logger/Logger"), exports);
18
+ _export_star._(require("./context"), exports);
19
+ const version = "v0.1.0";
@@ -0,0 +1,22 @@
1
+ import { ApplicationCommandOptionData, ApplicationCommandOptionType } from "discord.js";
2
+ export declare class Argument {
3
+ readonly name: string;
4
+ readonly description: string;
5
+ readonly type: ApplicationCommandOptionType;
6
+ readonly required: boolean;
7
+ readonly choices?: {
8
+ name: string;
9
+ value: string | number;
10
+ }[];
11
+ constructor(data: {
12
+ name: string;
13
+ description: string;
14
+ type: ApplicationCommandOptionType;
15
+ required?: boolean;
16
+ choices?: {
17
+ name: string;
18
+ value: string | number;
19
+ }[];
20
+ });
21
+ toJSON(): ApplicationCommandOptionData;
22
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "Argument", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return Argument;
9
+ }
10
+ });
11
+ class Argument {
12
+ name;
13
+ description;
14
+ type;
15
+ required;
16
+ choices;
17
+ constructor(data){
18
+ this.name = data.name;
19
+ this.description = data.description;
20
+ this.type = data.type;
21
+ this.required = data.required ?? false;
22
+ this.choices = data.choices;
23
+ }
24
+ toJSON() {
25
+ return {
26
+ name: this.name,
27
+ description: this.description,
28
+ type: this.type,
29
+ required: this.required,
30
+ choices: this.choices
31
+ };
32
+ }
33
+ }
@@ -0,0 +1,17 @@
1
+ import { Client as DiscordClient, Collection, IntentsBitField } from "discord.js";
2
+ import { CommandBuilder } from "./Command";
3
+ import { FrameworkOptions } from "#types/client.js";
4
+ import { Logger } from "../utils/logger/Logger";
5
+ export declare class Client<Ready extends boolean = boolean> extends DiscordClient<Ready> {
6
+ readonly logger: Logger;
7
+ commands: Collection<string, CommandBuilder>;
8
+ aliases: Collection<string, Set<string>>;
9
+ readonly prefix: string | false;
10
+ options: Omit<FrameworkOptions, "intents"> & {
11
+ intents: IntentsBitField;
12
+ };
13
+ constructor(opts: FrameworkOptions);
14
+ loadFiles(dir: string): Promise<void>;
15
+ loadFile(file: string): Promise<void>;
16
+ registerCommands(): Promise<void>;
17
+ }
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "Client", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return Client;
9
+ }
10
+ });
11
+ const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
12
+ const _discord = require("discord.js");
13
+ const _path = /*#__PURE__*/ _interop_require_default._(require("path"));
14
+ const _Files = require("../utils/Files");
15
+ const _lodash = require("lodash");
16
+ const _context = require("../context");
17
+ const _util = require("../utils/util");
18
+ const _Logger = require("../utils/logger/Logger");
19
+ const defaultOpts = {
20
+ paths: {
21
+ events: "events",
22
+ commands: "commands"
23
+ },
24
+ autoRegisterCommands: true
25
+ };
26
+ class Client extends _discord.Client {
27
+ logger;
28
+ commands;
29
+ aliases;
30
+ prefix;
31
+ constructor(opts){
32
+ super((0, _lodash.merge)({}, defaultOpts, opts));
33
+ this.logger = new _Logger.Logger(opts.logger);
34
+ this.commands = new _discord.Collection();
35
+ this.aliases = new _discord.Collection();
36
+ this.prefix = (0, _util.getPrefix)(this.options.prefix ?? {
37
+ enabled: false
38
+ });
39
+ if (this.options.paths?.events) {
40
+ this.loadFiles(_path.default.join((0, _Files.getProjectRoot)(), this.options.paths?.events)).catch((error)=>this.logger.error("Error loading events:", error));
41
+ }
42
+ (0, _context.setClient)(this);
43
+ try {
44
+ require("../events/ready");
45
+ require("../events/interaction");
46
+ if (this.prefix) require("../events/message");
47
+ } finally{
48
+ (0, _context.clearClient)();
49
+ }
50
+ }
51
+ async loadFiles(dir) {
52
+ if (!require("fs").existsSync(dir)) {
53
+ this.logger.warn(`Directory not found: ${dir}`);
54
+ return;
55
+ }
56
+ const files = (0, _Files.getFiles)(dir);
57
+ for (const file of files){
58
+ await this.loadFile(file);
59
+ }
60
+ }
61
+ async loadFile(file) {
62
+ try {
63
+ delete require.cache[require.resolve(file)];
64
+ (0, _context.setClient)(this);
65
+ require(file);
66
+ } catch (error) {
67
+ this.logger.error(`Error loading file ${file}:`, error);
68
+ } finally{
69
+ (0, _context.clearClient)();
70
+ }
71
+ }
72
+ async registerCommands() {
73
+ if (!this.token) {
74
+ this.logger.warn("registerCommands skipped: client token is not set.");
75
+ return;
76
+ }
77
+ if (!this.application) {
78
+ this.logger.warn("registerCommands skipped: client application is not ready.");
79
+ return;
80
+ }
81
+ const slashCommands = this.commands.filter((cmd)=>cmd.supportsSlash).map((cmd)=>({
82
+ name: cmd.name,
83
+ description: cmd.description,
84
+ options: cmd.options
85
+ }));
86
+ const rest = new _discord.REST({
87
+ version: "10"
88
+ }).setToken(this.token);
89
+ try {
90
+ this.logger.debug(`Started refreshing ${slashCommands.length} application (/) commands.`);
91
+ await rest.put(_discord.Routes.applicationCommands(this.application.id), {
92
+ body: slashCommands
93
+ });
94
+ this.logger.info(`Loaded ${slashCommands.length} application (/) commands.`);
95
+ } catch (error) {
96
+ this.logger.error("Failed to register commands:", error);
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,31 @@
1
+ import { ApplicationCommandOptionData, ChatInputCommandInteraction, Message } from "discord.js";
2
+ import { Context } from "./Context";
3
+ import { Client } from "./Client";
4
+ import { Argument } from "./Argument";
5
+ import { MaybePromise } from "#types/extra.js";
6
+ import { Logger } from "../utils/logger/Logger";
7
+ export interface CommandOptions {
8
+ name: string;
9
+ description: string;
10
+ aliases?: string[];
11
+ options?: (ApplicationCommandOptionData | Argument)[];
12
+ slash?: boolean;
13
+ prefix?: boolean;
14
+ }
15
+ export declare class CommandBuilder {
16
+ readonly client: Client;
17
+ readonly logger: Logger;
18
+ readonly name: string;
19
+ readonly description: string;
20
+ readonly aliases: string[];
21
+ readonly options: ApplicationCommandOptionData[];
22
+ private _supportsSlash;
23
+ private _supportsPrefix;
24
+ _onMessage?: (ctx: NonNullable<ReturnType<Context<Message>["toJSON"]>>) => MaybePromise<void>;
25
+ _onInteraction?: (ctx: NonNullable<ReturnType<Context<ChatInputCommandInteraction>["toJSON"]>>) => MaybePromise<void>;
26
+ get supportsSlash(): false | ((ctx: NonNullable<ReturnType<Context<ChatInputCommandInteraction>["toJSON"]>>) => MaybePromise<void>) | undefined;
27
+ get supportsPrefix(): false | ((ctx: NonNullable<ReturnType<Context<Message>["toJSON"]>>) => MaybePromise<void>) | undefined;
28
+ constructor(options: CommandOptions);
29
+ onMessage(func: (ctx: NonNullable<ReturnType<Context<Message>["toJSON"]>>) => MaybePromise<void>): this;
30
+ onInteraction(func: (ctx: NonNullable<ReturnType<Context<ChatInputCommandInteraction>["toJSON"]>>) => MaybePromise<void>): this;
31
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CommandBuilder", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CommandBuilder;
9
+ }
10
+ });
11
+ const _Argument = require("./Argument");
12
+ const _context = require("../context");
13
+ class CommandBuilder {
14
+ client;
15
+ logger;
16
+ name;
17
+ description;
18
+ aliases;
19
+ options;
20
+ _supportsSlash;
21
+ _supportsPrefix;
22
+ _onMessage;
23
+ _onInteraction;
24
+ get supportsSlash() {
25
+ return this._supportsSlash && this._onInteraction;
26
+ }
27
+ get supportsPrefix() {
28
+ return this._supportsPrefix && this._onMessage;
29
+ }
30
+ constructor(options){
31
+ const client = _context.currentClient;
32
+ if (!client) throw new Error("Client is not defined");
33
+ this.client = client;
34
+ this.logger = client.logger;
35
+ this.name = options.name;
36
+ this.description = options.description;
37
+ this.aliases = options.aliases ?? [];
38
+ this.options = (options.options ?? []).map((opt)=>{
39
+ return opt instanceof _Argument.Argument ? opt.toJSON() : opt;
40
+ });
41
+ this._supportsPrefix = options.prefix ?? false;
42
+ this._supportsSlash = options.slash ?? false;
43
+ if (!this._supportsPrefix && !this._supportsSlash) {
44
+ throw new Error(`Command ${this.name} must support either slash or prefix commands.`);
45
+ }
46
+ if (this.client.commands.has(this.name)) throw new Error(`Command name "${this.name}" is already registered.`);
47
+ const existingAliasOwner = this.client.aliases.findKey((aliases)=>aliases.has(this.name));
48
+ if (existingAliasOwner) {
49
+ throw new Error(`Command name "${this.name}" is already registered as an alias for command "${existingAliasOwner}".`);
50
+ }
51
+ for (const alias of this.aliases){
52
+ if (this.client.commands.has(alias)) {
53
+ throw new Error(`Alias "${alias}" is already registered as a command name.`);
54
+ }
55
+ const conflictingCommand = this.client.aliases.findKey((aliases)=>aliases.has(alias));
56
+ if (conflictingCommand) {
57
+ throw new Error(`Alias "${alias}" is already registered as an alias for command "${conflictingCommand}".`);
58
+ }
59
+ }
60
+ this.client.commands.set(this.name, this);
61
+ if (this.aliases.length > 0) {
62
+ this.client.aliases.set(this.name, new Set(this.aliases));
63
+ }
64
+ this.logger.debug(`Loaded Command ${this.name}`);
65
+ }
66
+ onMessage(func) {
67
+ this._onMessage = func;
68
+ return this;
69
+ }
70
+ onInteraction(func) {
71
+ this._onInteraction = func;
72
+ return this;
73
+ }
74
+ }
@@ -0,0 +1,32 @@
1
+ import { Message, User, ChatInputCommandInteraction } from "discord.js";
2
+ import { Client } from "../structures/Client";
3
+ type ContextPayload<T extends ChatInputCommandInteraction | Message> = T extends ChatInputCommandInteraction ? {
4
+ interaction: T;
5
+ args?: string[];
6
+ } : {
7
+ message: T;
8
+ args?: string[];
9
+ };
10
+ export declare class Context<T extends ChatInputCommandInteraction | Message> {
11
+ readonly client: Client;
12
+ readonly args: string[];
13
+ readonly data: T;
14
+ constructor(client: Client, payload: ContextPayload<T>);
15
+ isInteraction(): this is Context<ChatInputCommandInteraction>;
16
+ isMessage(): this is Context<Message>;
17
+ get author(): User | null;
18
+ toJSON(): {
19
+ kind: "interaction";
20
+ interaction: T;
21
+ author: User | null;
22
+ message?: undefined;
23
+ args?: undefined;
24
+ } | {
25
+ kind: "message";
26
+ message: Message;
27
+ args: string[];
28
+ author: User | null;
29
+ interaction?: undefined;
30
+ };
31
+ }
32
+ export {};
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "Context", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return Context;
9
+ }
10
+ });
11
+ const _discord = require("discord.js");
12
+ class Context {
13
+ client;
14
+ args;
15
+ data;
16
+ constructor(client, payload){
17
+ this.client = client;
18
+ this.args = payload.args ?? [];
19
+ if ("interaction" in payload) {
20
+ this.data = payload.interaction;
21
+ } else {
22
+ this.data = payload.message;
23
+ }
24
+ }
25
+ isInteraction() {
26
+ return this.data instanceof _discord.ChatInputCommandInteraction;
27
+ }
28
+ isMessage() {
29
+ return this.data instanceof _discord.Message;
30
+ }
31
+ get author() {
32
+ if (this.isInteraction()) {
33
+ return this.data.user;
34
+ }
35
+ if (this.isMessage()) {
36
+ return this.data.author;
37
+ }
38
+ return null;
39
+ }
40
+ toJSON() {
41
+ const { data, args, author } = this;
42
+ if (this.isInteraction()) {
43
+ return {
44
+ kind: "interaction",
45
+ interaction: data,
46
+ author: author
47
+ };
48
+ }
49
+ return {
50
+ kind: "message",
51
+ message: data,
52
+ args: args,
53
+ author: author
54
+ };
55
+ }
56
+ }
@@ -0,0 +1,19 @@
1
+ import { ClientEvents } from "discord.js";
2
+ import { MaybePromise } from "#types/extra.js";
3
+ import { Client } from "./Client";
4
+ import { Logger } from "../utils/logger/Logger";
5
+ type EventArgs<K extends keyof ClientEvents> = ClientEvents[K];
6
+ type EventHandler<K extends keyof ClientEvents> = (context: EventBuilder<K>, ...args: EventArgs<K>) => MaybePromise<void>;
7
+ export declare class EventBuilder<K extends keyof ClientEvents> {
8
+ readonly name: K;
9
+ readonly once: boolean;
10
+ readonly client: Client;
11
+ readonly logger: Logger;
12
+ private handler?;
13
+ private bound;
14
+ private readonly listener;
15
+ constructor(name: K, once?: boolean, _handler?: EventHandler<K>);
16
+ private register;
17
+ onExecute(func: EventHandler<K>): this;
18
+ }
19
+ export {};
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "EventBuilder", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return EventBuilder;
9
+ }
10
+ });
11
+ const _context = require("../context");
12
+ class EventBuilder {
13
+ name;
14
+ once;
15
+ client;
16
+ logger;
17
+ handler;
18
+ bound = false;
19
+ listener = async (...args)=>{
20
+ if (!this.handler) return;
21
+ try {
22
+ await this.handler(this, ...args);
23
+ } catch (error) {
24
+ this.client.logger.error(`Error executing event ${this.name} (${this.constructor.name}):`, error);
25
+ }
26
+ };
27
+ constructor(name, once = false, _handler){
28
+ this.name = name;
29
+ this.once = once;
30
+ if (!_context.currentClient) throw new Error("Client is not defined");
31
+ this.client = _context.currentClient;
32
+ this.logger = _context.currentClient.logger;
33
+ if (_handler) {
34
+ this.handler = _handler;
35
+ this.register();
36
+ }
37
+ this.logger.debug(`Loaded Event ${String(this.name)}`);
38
+ }
39
+ register() {
40
+ if (this.bound || !this.handler) return;
41
+ if (this.once) {
42
+ this.client.once(this.name, this.listener);
43
+ } else {
44
+ this.client.on(this.name, this.listener);
45
+ }
46
+ this.bound = true;
47
+ }
48
+ onExecute(func) {
49
+ this.handler = func;
50
+ this.register();
51
+ return this;
52
+ }
53
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getFiles(baseDir: string): string[];
2
+ export declare function getProjectRoot(): string;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get getFiles () {
13
+ return getFiles;
14
+ },
15
+ get getProjectRoot () {
16
+ return getProjectRoot;
17
+ }
18
+ });
19
+ const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
20
+ const _fastglob = /*#__PURE__*/ _interop_require_default._(require("fast-glob"));
21
+ const _path = /*#__PURE__*/ _interop_require_default._(require("path"));
22
+ function getFiles(baseDir) {
23
+ return _fastglob.default.sync([
24
+ "**/*.ts",
25
+ "**/*.js"
26
+ ], {
27
+ cwd: baseDir,
28
+ absolute: true,
29
+ ignore: [
30
+ "**/*.d.ts",
31
+ "node_modules/**",
32
+ ".git/**",
33
+ "dist/**",
34
+ "lib/**",
35
+ "out/**",
36
+ "build/**",
37
+ ".next/**",
38
+ "coverage/**"
39
+ ]
40
+ });
41
+ }
42
+ function getProjectRoot() {
43
+ if (!require.main?.filename) {
44
+ return process.cwd();
45
+ }
46
+ return _path.default.dirname(require.main.filename);
47
+ }