command-ts 0.0.1 → 0.0.2

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 (50) hide show
  1. package/README.md +102 -0
  2. package/out/function/CTSError.d.ts +3 -0
  3. package/out/function/CTSError.js +10 -0
  4. package/out/function/debug.d.ts +25 -0
  5. package/out/function/debug.js +73 -0
  6. package/out/function/index.d.ts +4 -0
  7. package/out/function/index.js +20 -0
  8. package/out/function/read-dir.d.ts +2 -0
  9. package/out/function/read-dir.js +38 -0
  10. package/out/function/visual.d.ts +1 -0
  11. package/out/function/visual.js +60 -0
  12. package/out/handler/button/index.d.ts +3 -0
  13. package/out/handler/button/index.js +7 -0
  14. package/out/handler/command/autocomplete.d.ts +3 -0
  15. package/out/handler/command/autocomplete.js +4 -0
  16. package/out/handler/command/execute.d.ts +3 -0
  17. package/out/handler/command/execute.js +45 -0
  18. package/out/handler/command/fetch-command.d.ts +2 -0
  19. package/out/handler/command/fetch-command.js +23 -0
  20. package/out/handler/command/index.d.ts +3 -0
  21. package/out/handler/command/index.js +22 -0
  22. package/out/handler/command/register.d.ts +3 -0
  23. package/out/handler/command/register.js +15 -0
  24. package/out/handler/event/fetch-event.d.ts +2 -0
  25. package/out/handler/event/fetch-event.js +27 -0
  26. package/out/handler/event/index.d.ts +3 -0
  27. package/out/handler/event/index.js +11 -0
  28. package/out/handler/event/on-event.d.ts +2 -0
  29. package/out/handler/event/on-event.js +23 -0
  30. package/out/handler/index.d.ts +3 -0
  31. package/out/handler/index.js +36 -0
  32. package/out/handler/modal/index.d.ts +3 -0
  33. package/out/handler/modal/index.js +7 -0
  34. package/out/handler/selectmenu/channel.d.ts +3 -0
  35. package/out/handler/selectmenu/channel.js +7 -0
  36. package/out/handler/selectmenu/index.d.ts +3 -0
  37. package/out/handler/selectmenu/index.js +7 -0
  38. package/out/handler/selectmenu/mentionable.d.ts +3 -0
  39. package/out/handler/selectmenu/mentionable.js +7 -0
  40. package/out/handler/selectmenu/role.d.ts +3 -0
  41. package/out/handler/selectmenu/role.js +7 -0
  42. package/out/handler/selectmenu/string.d.ts +3 -0
  43. package/out/handler/selectmenu/string.js +7 -0
  44. package/out/handler/selectmenu/user.d.ts +3 -0
  45. package/out/handler/selectmenu/user.js +7 -0
  46. package/out/index.d.ts +4 -1
  47. package/out/index.js +20 -1
  48. package/out/type.d.ts +26 -0
  49. package/out/type.js +28 -0
  50. package/package.json +9 -3
package/README.md CHANGED
@@ -30,3 +30,105 @@ pnpm add command-ts
30
30
  ```sh
31
31
  yarn add command-ts
32
32
  ```
33
+
34
+ ## Usage
35
+
36
+ ```typescript
37
+ import { handler } from "command-ts"
38
+ import { Client, GatewayIntentBits } from "discord.js"
39
+
40
+ const client = new Client({
41
+ intents: [GatewayIntentBits.Guilds]
42
+ })
43
+
44
+ handler({
45
+ client,
46
+ debug: true, // Enable debug logging
47
+ command: "./commands", // Path to commands folder
48
+ event: "./events", // Path to events folder
49
+ button: "./buttons", // Path to button handlers
50
+ modal: "./modals", // Path to modal handlers
51
+ selectmenu: "./selectmenus" // Path to select menu handlers
52
+ })
53
+
54
+ client.login("YOUR_TOKEN")
55
+ ```
56
+
57
+ ### Command Structure
58
+
59
+ Create a command file in your commands folder:
60
+
61
+ ```typescript
62
+ import { Command } from "command-ts"
63
+
64
+ export const command: Command = {
65
+ data: {
66
+ name: "ping",
67
+ description: "Replies with pong!"
68
+ },
69
+ run: async (interaction) => {
70
+ await interaction.reply("Pong!")
71
+ }
72
+ }
73
+ ```
74
+
75
+ ## API Documentation
76
+
77
+ ### Handler Options
78
+
79
+ The `handler` function accepts an options object with the following properties:
80
+
81
+ ```typescript
82
+ type Options = {
83
+ client: Client // Discord.js client instance (required)
84
+ debug?: boolean // Enable debug logging
85
+ event?: string | EventMap // Path to events folder or event map
86
+ command?: string | CommandMap // Path to commands folder or command map
87
+ button?: string | ButtonMap // Path to button handlers or button map
88
+ modal?: string | ModalMap // Path to modal handlers or modal map
89
+ selectmenu?: SelectMenu | string // Path to select menu handlers or select menu config
90
+ middleware?: Middleware | Middleware[] // Command middleware functions
91
+ }
92
+ ```
93
+
94
+ ### Command Types
95
+
96
+ Commands must implement the `Command` Types:
97
+
98
+ ```typescript
99
+ type Command = {
100
+ data: RESTPostAPIApplicationCommandsJSONBody // Command registration data
101
+ autocomplete?: (interaction: AutocompleteInteraction) => any // Optional autocomplete handler
102
+ run: (interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) => any
103
+ }
104
+ ```
105
+
106
+ ### SelectMenu Types
107
+
108
+ The SelectMenu configuration supports different menu types:
109
+
110
+ ```typescript
111
+ type SelectMenu = {
112
+ StringSelectMenu?: string | ((interaction: StringSelectMenuInteraction) => any)
113
+ UserSelectMenu?: string | ((interaction: UserSelectMenuInteraction) => any)
114
+ RoleSelectMenu?: string | ((interaction: RoleSelectMenuInteraction) => any)
115
+ MentionableSelectMenu?: string | ((interaction: MentionableSelectMenuInteraction) => any)
116
+ ChannelSelectMenu?: string | ((interaction: ChannelSelectMenuInteraction) => any)
117
+ }
118
+ ```
119
+
120
+ ### Middleware
121
+
122
+ Middleware functions can be used to add custom logic before command execution:
123
+
124
+ ```typescript
125
+ type Middleware = (command: Command, interaction: CommandInteraction, stop: (reason?: string) => void) => any
126
+ ```
127
+
128
+ ## Contributing
129
+
130
+ Contributions are welcome! Please feel free to submit a Pull Request.
131
+
132
+ ## License
133
+
134
+ This project is licensed under the Apache-2.0 License. See the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,3 @@
1
+ export declare class CTSError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CTSError = void 0;
4
+ class CTSError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "CTSError";
8
+ }
9
+ }
10
+ exports.CTSError = CTSError;
@@ -0,0 +1,25 @@
1
+ export declare const enum LogLevel {
2
+ DEBUG = 0,
3
+ INFO = 1,
4
+ WARN = 2,
5
+ ERROR = 3
6
+ }
7
+ type LoggerConfig = {
8
+ minLevel: LogLevel;
9
+ includeTimestamp: boolean;
10
+ dateFormat: Intl.DateTimeFormatOptions;
11
+ timeFormat: Intl.DateTimeFormatOptions;
12
+ };
13
+ declare const createLogger: (customConfig?: Partial<LoggerConfig>) => {
14
+ debug: (message: unknown, ...args: unknown[]) => void;
15
+ info: (message: unknown, ...args: unknown[]) => void;
16
+ warn: (message: unknown, ...args: unknown[]) => void;
17
+ error: (message: unknown, ...args: unknown[]) => void;
18
+ };
19
+ export declare const debug: {
20
+ debug: (message: unknown, ...args: unknown[]) => void;
21
+ info: (message: unknown, ...args: unknown[]) => void;
22
+ warn: (message: unknown, ...args: unknown[]) => void;
23
+ error: (message: unknown, ...args: unknown[]) => void;
24
+ };
25
+ export { createLogger };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLogger = exports.debug = void 0;
4
+ const colorette_1 = require("colorette");
5
+ const handler_1 = require("../handler");
6
+ const node_util_1 = require("node:util");
7
+ const defaultConfig = {
8
+ minLevel: 0 /* LogLevel.DEBUG */,
9
+ includeTimestamp: true,
10
+ dateFormat: {
11
+ year: "numeric",
12
+ month: "2-digit",
13
+ day: "2-digit"
14
+ },
15
+ timeFormat: {
16
+ hour: "2-digit",
17
+ minute: "2-digit",
18
+ second: "2-digit",
19
+ hour12: false
20
+ }
21
+ };
22
+ const getTimestamp = (config) => {
23
+ if (!config.includeTimestamp)
24
+ return "";
25
+ const date = new Date();
26
+ const dateStr = date.toLocaleDateString(undefined, config.dateFormat);
27
+ const timeStr = date.toLocaleTimeString(undefined, config.timeFormat);
28
+ return `[${dateStr} ${timeStr}]`;
29
+ };
30
+ const shouldLog = (level, config) => {
31
+ const levelMap = {
32
+ DEBUG: 0 /* LogLevel.DEBUG */,
33
+ INFO: 1 /* LogLevel.INFO */,
34
+ WARN: 2 /* LogLevel.WARN */,
35
+ ERROR: 3 /* LogLevel.ERROR */
36
+ };
37
+ return levelMap[level] >= config.minLevel;
38
+ };
39
+ const formatArgs = (args) => {
40
+ if (args.length === 0)
41
+ return "";
42
+ let str = "";
43
+ for (const obj of args) {
44
+ str += (0, node_util_1.inspect)(obj, { colors: true, depth: Infinity });
45
+ str += " ";
46
+ }
47
+ return str;
48
+ };
49
+ const createLog = (config) => {
50
+ return (level, color, message, ...args) => {
51
+ if (shouldLog(level, config)) {
52
+ const timestamp = getTimestamp(config);
53
+ const levelStr = color(`[${level}]`);
54
+ const formattedArgs = formatArgs(args);
55
+ if (handler_1.IsDebugEnabled)
56
+ console.log(`${(0, colorette_1.blue)(timestamp)} ${levelStr} ${message} ${formattedArgs}`);
57
+ if (level === "WARN")
58
+ process.emitWarning(`${message}`);
59
+ }
60
+ };
61
+ };
62
+ const createLogger = (customConfig = {}) => {
63
+ const config = { ...defaultConfig, ...customConfig };
64
+ const log = createLog(config);
65
+ return {
66
+ debug: (message, ...args) => log("DEBUG", colorette_1.gray, message, ...args),
67
+ info: (message, ...args) => log("INFO", colorette_1.green, message, ...args),
68
+ warn: (message, ...args) => log("WARN", colorette_1.yellow, message, ...args),
69
+ error: (message, ...args) => log("ERROR", colorette_1.red, message, ...args)
70
+ };
71
+ };
72
+ exports.createLogger = createLogger;
73
+ exports.debug = createLogger();
@@ -0,0 +1,4 @@
1
+ export * from "./CTSError";
2
+ export * from "./debug";
3
+ export * from "./read-dir";
4
+ export * from "./visual";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./CTSError"), exports);
18
+ __exportStar(require("./debug"), exports);
19
+ __exportStar(require("./read-dir"), exports);
20
+ __exportStar(require("./visual"), exports);
@@ -0,0 +1,2 @@
1
+ export declare function GetFilePaths(directory: string, nesting?: boolean): string[];
2
+ export declare function GetFolderPaths(directory: string, nesting?: boolean): string[];
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetFilePaths = GetFilePaths;
4
+ exports.GetFolderPaths = GetFolderPaths;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ function GetFilePaths(directory, nesting) {
8
+ let file_paths = [];
9
+ if (!directory)
10
+ return file_paths;
11
+ const files = (0, node_fs_1.readdirSync)(directory, { withFileTypes: true });
12
+ for (const file of files) {
13
+ const file_path = (0, node_path_1.join)(directory, file.name);
14
+ if (file.isFile()) {
15
+ file_paths.push(file_path);
16
+ }
17
+ if (nesting && file.isDirectory()) {
18
+ file_paths = [...file_paths, ...GetFilePaths(file_path, true)];
19
+ }
20
+ }
21
+ return file_paths;
22
+ }
23
+ function GetFolderPaths(directory, nesting) {
24
+ let folder_paths = [];
25
+ if (!directory)
26
+ return folder_paths;
27
+ const folders = (0, node_fs_1.readdirSync)(directory, { withFileTypes: true });
28
+ for (const folder of folders) {
29
+ const folder_path = (0, node_path_1.join)(directory, folder.name);
30
+ if (folder.isDirectory()) {
31
+ folder_paths.push(folder_path);
32
+ if (nesting) {
33
+ folder_paths = [...folder_paths, ...GetFolderPaths(folder_path, true)];
34
+ }
35
+ }
36
+ }
37
+ return folder_paths;
38
+ }
@@ -0,0 +1 @@
1
+ export declare function GenerateList(type: string, filePaths: string[], srcDir: string): string;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GenerateList = GenerateList;
7
+ const colorette_1 = require("colorette");
8
+ const path_1 = __importDefault(require("path"));
9
+ function GenerateList(type, filePaths, srcDir) {
10
+ const x = [];
11
+ const commandCount = filePaths.length;
12
+ // Create directory structure from file paths
13
+ const directoryStructure = {};
14
+ for (const filePath of filePaths) {
15
+ // Skip files not in src directory
16
+ if (!filePath.startsWith(srcDir))
17
+ continue;
18
+ // Get relative path from src
19
+ const relativePath = filePath.substring(srcDir.length + 1);
20
+ const pathParts = relativePath.split(path_1.default.sep);
21
+ // File name without extension
22
+ const fileName = path_1.default.basename(pathParts[pathParts.length - 1], ".ts");
23
+ // Build directory structure
24
+ let currentLevel = directoryStructure;
25
+ // Process each directory in the path
26
+ for (let i = 0; i < pathParts.length - 1; i++) {
27
+ const part = pathParts[i];
28
+ if (!currentLevel[part]) {
29
+ currentLevel[part] = { __files: [] };
30
+ }
31
+ currentLevel = currentLevel[part];
32
+ }
33
+ // Add file to the current directory
34
+ currentLevel.__files.push(fileName);
35
+ }
36
+ // Generate formatted command list from directory structure
37
+ function processStructure(structure, level = 0) {
38
+ // Process directories first
39
+ for (const dir in structure) {
40
+ if (dir === "__files")
41
+ continue;
42
+ const indent = " ".repeat(level);
43
+ x.push(`${indent}├─ ${(0, colorette_1.cyan)(dir)}`);
44
+ // Process subdirectories and files
45
+ processStructure(structure[dir], level + 1);
46
+ }
47
+ // Process files
48
+ if (structure.__files) {
49
+ const indent = " ".repeat(level);
50
+ for (const file of structure.__files) {
51
+ x.push(`${indent}├─ ${(0, colorette_1.cyan)(file)}`);
52
+ }
53
+ }
54
+ }
55
+ // Generate command list
56
+ processStructure(directoryStructure);
57
+ // Add summary at the beginning
58
+ x.unshift(`Loaded ${(0, colorette_1.magenta)(commandCount.toString())} ${type}:`);
59
+ return x.join("\n");
60
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../../type";
2
+ import { Client } from "discord.js";
3
+ export declare function button_handler(data: Options["button"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.button_handler = button_handler;
4
+ const function_1 = require("../../function");
5
+ function button_handler(data, client) {
6
+ function_1.debug.warn("Button handler is not implemented yet");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Interaction } from "discord.js";
2
+ import { Command } from "../../type";
3
+ export declare function autocomplete(commands: Map<string, Command>, interaction: Interaction): Promise<void>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.autocomplete = autocomplete;
4
+ async function autocomplete(commands, interaction) { }
@@ -0,0 +1,3 @@
1
+ import { Command, Middleware } from "../../type";
2
+ import { Interaction } from "discord.js";
3
+ export declare function execute(commands: Map<string, Command>, interaction: Interaction, middleware: Array<Middleware>): Promise<void>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.execute = execute;
4
+ const function_1 = require("../../function");
5
+ async function execute(commands, interaction, middleware) {
6
+ if (!interaction.isCommand())
7
+ return;
8
+ const command = commands.get(interaction.commandName);
9
+ if (!command)
10
+ return;
11
+ const { run } = command;
12
+ if (!run || typeof run !== "function") {
13
+ return function_1.debug.warn(`Command ${interaction.commandName} does not have a run function`, { command });
14
+ }
15
+ if (middleware && middleware.length) {
16
+ let ShouldStop = false;
17
+ let reason;
18
+ const stop = (text) => {
19
+ ShouldStop = true;
20
+ if (text) {
21
+ reason = text;
22
+ }
23
+ else {
24
+ reason = "No reason provided";
25
+ }
26
+ };
27
+ let index = 0;
28
+ for (; index < middleware.length; index++) {
29
+ const fn = middleware[index];
30
+ await fn(command, interaction, stop);
31
+ if (ShouldStop)
32
+ break;
33
+ }
34
+ if (ShouldStop) {
35
+ return function_1.debug.info(`A middleware stopped execution`, { index, reason });
36
+ }
37
+ }
38
+ try {
39
+ await run(interaction);
40
+ }
41
+ catch (error) {
42
+ function_1.debug.error(`Error in command ${interaction.commandName} (${interaction.id})`, { error });
43
+ throw error;
44
+ }
45
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "../../type";
2
+ export declare function ftc_command(data: string): Map<string, Command>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ftc_command = ftc_command;
4
+ const function_1 = require("../../function");
5
+ function ftc_command(data) {
6
+ const files = (0, function_1.GetFilePaths)(data, true).filter((path) => path.endsWith(".js") || path.endsWith(".ts"));
7
+ const commands = new Map();
8
+ for (const file of files) {
9
+ const command = require(file);
10
+ if (!("data" in command)) {
11
+ function_1.debug.warn(`Ignoring: Command ${file} does not export "data".`, { command });
12
+ continue;
13
+ }
14
+ if (!("run" in command)) {
15
+ function_1.debug.warn(`Ignoring: Command ${file} does not export "run".`, { command });
16
+ continue;
17
+ }
18
+ commands.set(command.data.name, command);
19
+ }
20
+ function_1.debug.debug(`${(0, function_1.GenerateList)("commands", files, data)}`);
21
+ function_1.debug.debug(`Found ${commands.size} commands`, { commands });
22
+ return commands;
23
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../../type";
2
+ import { Client } from "discord.js";
3
+ export declare function command_handler(data: NonNullable<Options["command"]>, client: Client, middleware: Options["middleware"]): void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command_handler = command_handler;
4
+ const autocomplete_1 = require("./autocomplete");
5
+ const fetch_command_1 = require("./fetch-command");
6
+ const function_1 = require("../../function");
7
+ const register_1 = require("./register");
8
+ const execute_1 = require("./execute");
9
+ const discord_js_1 = require("discord.js");
10
+ const lodash_1 = require("lodash");
11
+ function command_handler(data, client, middleware) {
12
+ if (middleware)
13
+ middleware = typeof middleware === "function" ? [middleware] : middleware;
14
+ const commands = (0, lodash_1.isMap)(data) ? data : (0, fetch_command_1.ftc_command)(data);
15
+ client.on("ready", async (client) => await (0, register_1.register)(commands, client));
16
+ client.on("interactionCreate", async (interaction) => {
17
+ function_1.debug.info(`Command handler triggered`, { id: interaction.id, type: discord_js_1.InteractionType[interaction.type] });
18
+ await (0, execute_1.execute)(commands, interaction, middleware ?? []);
19
+ await (0, autocomplete_1.autocomplete)(commands, interaction);
20
+ });
21
+ function_1.debug.info("Command handler loaded");
22
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { Command } from "../../type";
3
+ export declare function register(commands: Map<string, Command>, client: Client<true>): Promise<void>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.register = register;
4
+ const function_1 = require("../../function");
5
+ async function register(commands, client) {
6
+ const cmd = Array.from(commands.values()).map((c) => c.data);
7
+ try {
8
+ await client.application.commands.set(cmd);
9
+ function_1.debug.info(`Successfully reloaded ${cmd.length} application (/) commands.`);
10
+ }
11
+ catch (error) {
12
+ function_1.debug.error(`Error reloading application (/) commands`);
13
+ throw error;
14
+ }
15
+ }
@@ -0,0 +1,2 @@
1
+ import { ClientEvents } from "discord.js";
2
+ export declare function ftc_event(data: string): Map<keyof ClientEvents, ((...arg: any) => any)[]>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ftc_event = ftc_event;
4
+ const function_1 = require("../../function");
5
+ function ftc_event(data) {
6
+ const EventFolderPaths = (0, function_1.GetFolderPaths)(data);
7
+ const FilePaths = [];
8
+ const event = new Map();
9
+ for (const EventFolderPath of EventFolderPaths) {
10
+ const eventName = EventFolderPath.replace(/\\/g, "/").split("/").pop();
11
+ const EventFilePaths = (0, function_1.GetFilePaths)(EventFolderPath, true).filter((path) => path.endsWith(".js") || path.endsWith(".ts"));
12
+ const fun = [];
13
+ for (const EventFilePath of EventFilePaths) {
14
+ const obj = require(EventFilePath);
15
+ const fn = typeof obj === "function" ? obj : obj.default;
16
+ if (typeof fn !== "function") {
17
+ function_1.debug.warn(`Ignoring: Event ${EventFilePath} does not export a function.`, { obj });
18
+ continue;
19
+ }
20
+ FilePaths.push(EventFilePath);
21
+ fun.push(fn);
22
+ }
23
+ event.set(eventName, fun);
24
+ }
25
+ function_1.debug.debug(`${(0, function_1.GenerateList)("events", FilePaths, data)}`);
26
+ return event;
27
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../../type";
2
+ import { Client } from "discord.js";
3
+ export declare function event_handler(data: NonNullable<Options["event"]>, client: Client): void;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.event_handler = event_handler;
4
+ const fetch_event_1 = require("./fetch-event");
5
+ const function_1 = require("../../function");
6
+ const on_event_1 = require("./on-event");
7
+ const lodash_1 = require("lodash");
8
+ function event_handler(data, client) {
9
+ (0, on_event_1.OnEvent)(client, (0, lodash_1.isMap)(data) ? data : (0, fetch_event_1.ftc_event)(data));
10
+ function_1.debug.info("Event handler loaded");
11
+ }
@@ -0,0 +1,2 @@
1
+ import { Client, ClientEvents } from "discord.js";
2
+ export declare function OnEvent(client: Client, map: Map<keyof ClientEvents, ((...arg: any) => any) | Array<(...arg: any) => any>>): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OnEvent = OnEvent;
4
+ const function_1 = require("../../function");
5
+ const lodash_1 = require("lodash");
6
+ function OnEvent(client, map) {
7
+ if (!(0, lodash_1.isMap)(map)) {
8
+ function_1.debug.error("Event handler must be a Map", { received: map });
9
+ throw new function_1.CTSError("Event handler must be a Map");
10
+ }
11
+ for (const [name, fn] of map) {
12
+ const func = typeof fn === "function" ? [fn] : fn;
13
+ for (const fn of func) {
14
+ if (typeof fn === "function") {
15
+ client.on(name, (...arg) => fn(...arg, client));
16
+ }
17
+ else {
18
+ function_1.debug.error("Event handler must be a function", `name: ${name}`, `function: ${fn}`);
19
+ throw new function_1.CTSError("Event handler must be a function");
20
+ }
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../type";
2
+ export declare let IsDebugEnabled: boolean;
3
+ export declare function handler({ debug: dbg, client, event, command, button, modal, selectmenu, middleware }: Options): void;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IsDebugEnabled = void 0;
4
+ exports.handler = handler;
5
+ const selectmenu_1 = require("./selectmenu");
6
+ const function_1 = require("../function");
7
+ const command_1 = require("./command");
8
+ const button_1 = require("./button");
9
+ const event_1 = require("./event");
10
+ const modal_1 = require("./modal");
11
+ const discord_js_1 = require("discord.js");
12
+ exports.IsDebugEnabled = false;
13
+ function handler({ debug: dbg, client, event, command, button, modal, selectmenu, middleware }) {
14
+ const djs = Number(discord_js_1.version.split(".").reduce((x, y, i) => (i === 2 ? x : `${x}.${y}`)));
15
+ exports.IsDebugEnabled = typeof dbg === "boolean" ? dbg : false;
16
+ if (djs < 14 || djs > 15) {
17
+ function_1.debug.warn("Your discord.js version might not be fully supported by command-ts handler");
18
+ }
19
+ if (!client) {
20
+ function_1.debug.error("Client is required", { received: client });
21
+ throw new function_1.CTSError("Client is required");
22
+ }
23
+ if (event)
24
+ (0, event_1.event_handler)(event, client);
25
+ if (button)
26
+ (0, button_1.button_handler)(button, client);
27
+ if (modal)
28
+ (0, modal_1.modal_handler)(modal, client);
29
+ if (selectmenu)
30
+ (0, selectmenu_1.selectmenu_handler)(selectmenu, client);
31
+ if (command)
32
+ (0, command_1.command_handler)(command, client, middleware);
33
+ function_1.debug.info("All Handler loaded");
34
+ // if (interaction_validator) interaction_validator_handler(interaction_validator, client)
35
+ // if (message_validator) message_validator_handler(message_validator, client)
36
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../../type";
2
+ import { Client } from "discord.js";
3
+ export declare function modal_handler(data: Options["modal"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.modal_handler = modal_handler;
4
+ const function_1 = require("../../function");
5
+ function modal_handler(data, client) {
6
+ function_1.debug.warn("Modal handler is not implemented yet");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { SelectMenu } from "../../type";
3
+ export declare function channel_handler(data: SelectMenu["ChannelSelectMenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.channel_handler = channel_handler;
4
+ const function_1 = require("../../function");
5
+ function channel_handler(data, client) {
6
+ function_1.debug.info("Channel select menu handler loaded");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "../../type";
2
+ import { Client } from "discord.js";
3
+ export declare function selectmenu_handler(data: Options["selectmenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectmenu_handler = selectmenu_handler;
4
+ const function_1 = require("../../function");
5
+ function selectmenu_handler(data, client) {
6
+ function_1.debug.warn("Select menu handler is not implemented yet");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { SelectMenu } from "../../type";
3
+ export declare function mentionable_handler(data: SelectMenu["MentionableSelectMenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mentionable_handler = mentionable_handler;
4
+ const function_1 = require("../../function");
5
+ function mentionable_handler(data, client) {
6
+ function_1.debug.info("Mentionable select menu handler loaded");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { SelectMenu } from "../../type";
3
+ export declare function role_handler(data: SelectMenu["RoleSelectMenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.role_handler = role_handler;
4
+ const function_1 = require("../../function");
5
+ function role_handler(data, client) {
6
+ function_1.debug.info("Role select menu handler loaded");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { SelectMenu } from "../../type";
3
+ export declare function string_handler(data: SelectMenu["StringSelectMenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.string_handler = string_handler;
4
+ const function_1 = require("../../function");
5
+ function string_handler(data, client) {
6
+ function_1.debug.info("String select menu handler loaded");
7
+ }
@@ -0,0 +1,3 @@
1
+ import { Client } from "discord.js";
2
+ import { SelectMenu } from "../../type";
3
+ export declare function user_handler(data: SelectMenu["UserSelectMenu"], client: Client): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.user_handler = user_handler;
4
+ const function_1 = require("../../function");
5
+ function user_handler(data, client) {
6
+ function_1.debug.info("User select menu handler loaded");
7
+ }
package/out/index.d.ts CHANGED
@@ -1 +1,4 @@
1
- export {};
1
+ export { version } from "../package.json";
2
+ export * from "./function";
3
+ export * from "./handler";
4
+ export * from "./type";
package/out/index.js CHANGED
@@ -1,3 +1,22 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- console.log("Hello, world!");
17
+ exports.version = void 0;
18
+ var package_json_1 = require("../package.json");
19
+ Object.defineProperty(exports, "version", { enumerable: true, get: function () { return package_json_1.version; } });
20
+ __exportStar(require("./function"), exports);
21
+ __exportStar(require("./handler"), exports);
22
+ __exportStar(require("./type"), exports);
package/out/type.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { AutocompleteInteraction, ChannelSelectMenuInteraction, ChatInputCommandInteraction, Client, ClientEvents, ContextMenuCommandInteraction, MentionableSelectMenuInteraction, RESTPostAPIApplicationCommandsJSONBody, RoleSelectMenuInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, ModalSubmitInteraction, ButtonInteraction, CommandInteraction } from "discord.js";
2
+ export type Options = {
3
+ client: Client;
4
+ debug?: boolean;
5
+ event?: PathOR<keyof ClientEvents, ((...arg: any) => any) | Array<(...arg: any) => any>>;
6
+ command?: PathOR<string, Command>;
7
+ button?: PathOR<string, (interaction: ButtonInteraction) => any>;
8
+ modal?: PathOR<string, (interaction: ModalSubmitInteraction) => any>;
9
+ selectmenu?: SelectMenu | string;
10
+ middleware?: Array<Middleware> | Middleware;
11
+ };
12
+ export type SelectMenu = {
13
+ StringSelectMenu?: PathOR<string, (interaction: StringSelectMenuInteraction) => any>;
14
+ UserSelectMenu?: PathOR<string, (interaction: UserSelectMenuInteraction) => any>;
15
+ RoleSelectMenu?: PathOR<string, (interaction: RoleSelectMenuInteraction) => any>;
16
+ MentionableSelectMenu?: PathOR<string, (interaction: MentionableSelectMenuInteraction) => any>;
17
+ ChannelSelectMenu?: PathOR<string, (interaction: ChannelSelectMenuInteraction) => any>;
18
+ };
19
+ export type PathOR<key extends string, value extends any> = Map<key, value> | string;
20
+ export type StopFunction = (reason?: string) => void;
21
+ export type Command = {
22
+ data: RESTPostAPIApplicationCommandsJSONBody;
23
+ autocomplete?: (interaction: AutocompleteInteraction) => any;
24
+ run: (interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) => any;
25
+ };
26
+ export type Middleware = (command: Command, interaction: CommandInteraction, stop: StopFunction) => any;
package/out/type.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /*
4
+ export type Handler = {
5
+ events?: string
6
+ commands?: string | CommandHandler
7
+ components?: string | ComponentHandler
8
+ }
9
+
10
+ export type CommandHandler = {
11
+ ChatInput?: string
12
+ Context?: string
13
+ }
14
+
15
+ export type ComponentHandler = {
16
+ Button?: string
17
+ Modal?: string
18
+ SelectMenu?: string | SelectMenuComponentHandler
19
+ }
20
+
21
+ export type SelectMenuComponentHandler = {
22
+ StringSelectMenu?: string
23
+ UserSelectMenu?: string
24
+ RoleSelectMenu?: string
25
+ MentionableSelectMenu?: string
26
+ ChannelSelectMenu?: string
27
+ }
28
+ */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "command-ts",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "A package for handling discord.js commands with TypeScript.",
5
5
  "author": "softwarexplus",
6
6
  "homepage": "https://github.com/softwarexplus/command-ts#readme",
@@ -21,14 +21,20 @@
21
21
  },
22
22
  "funding": {
23
23
  "type": "patreon",
24
- "url": "https://www.patreon.com/SoftwareXPlus"
24
+ "url": "https://www.patreon.com/xcfio"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public",
28
28
  "tag": "latest"
29
29
  },
30
+ "dependencies": {
31
+ "colorette": "^2.0.20",
32
+ "lodash": "^4.17.21"
33
+ },
30
34
  "devDependencies": {
31
- "@types/node": "^22.5.4"
35
+ "@types/lodash": "^4.17.14",
36
+ "@types/node": "^22.10.5",
37
+ "discord.js": "^14.17.2"
32
38
  },
33
39
  "scripts": {
34
40
  "fmt": "prettier --config=.prettierrc --write src/",