meocord 1.2.1 → 1.2.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 (113) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +152 -140
  3. package/dist/cjs/_shared/meocord.app-CHjdCAA_.cjs +496 -0
  4. package/dist/cjs/_shared/theme-BdtbtMZX.cjs +176 -0
  5. package/dist/cjs/common/index.cjs +16 -0
  6. package/dist/cjs/core/index.cjs +35 -0
  7. package/dist/cjs/decorator/index.cjs +360 -0
  8. package/dist/cjs/enum/index.cjs +20 -0
  9. package/dist/cjs/interface/index.cjs +2 -0
  10. package/dist/esm/bin/generator.js +92 -0
  11. package/dist/esm/bin/helper/controller-generator.helper.js +105 -0
  12. package/dist/esm/bin/helper/guard-generator.helper.js +33 -0
  13. package/dist/esm/bin/helper/service-generator.helper.js +33 -0
  14. package/dist/esm/bin/meocord.js +333 -0
  15. package/dist/esm/common/index.js +2 -0
  16. package/dist/esm/common/logger.js +72 -0
  17. package/dist/{core/index.d.ts → esm/common/theme.js} +8 -2
  18. package/dist/esm/core/index.js +1 -0
  19. package/dist/esm/core/meocord-factory.js +28 -0
  20. package/dist/esm/core/meocord.app.js +267 -0
  21. package/dist/esm/decorator/app.decorator.js +99 -0
  22. package/dist/esm/decorator/command-builder.decorator.js +32 -0
  23. package/dist/esm/decorator/container.js +6 -0
  24. package/dist/esm/decorator/controller.decorator.js +218 -0
  25. package/dist/esm/decorator/guard.decorator.js +165 -0
  26. package/dist/esm/decorator/index.js +6 -0
  27. package/dist/esm/decorator/service.decorator.js +58 -0
  28. package/dist/esm/enum/controller.enum.js +43 -0
  29. package/dist/esm/enum/index.js +1 -0
  30. package/dist/esm/interface/index.js +1 -0
  31. package/dist/esm/package.json.js +5 -0
  32. package/dist/esm/util/common.util.js +68 -0
  33. package/dist/esm/util/embed.util.js +13 -0
  34. package/dist/esm/util/generator-cli.util.js +107 -0
  35. package/dist/{util → esm/util}/json.util.js +10 -6
  36. package/dist/esm/util/meocord-cli.util.js +172 -0
  37. package/dist/esm/util/meocord-config-loader.util.js +48 -0
  38. package/dist/esm/util/tsconfig.util.js +83 -0
  39. package/dist/{util → esm/util}/wait.util.js +5 -1
  40. package/dist/{common/logger.d.ts → types/common/index.d.ts} +30 -1
  41. package/dist/{core/meocord.app.d.ts → types/core/index.d.ts} +30 -2
  42. package/dist/types/decorator/index.d.ts +425 -0
  43. package/dist/types/enum/index.d.ts +18 -0
  44. package/dist/{interface → types/interface}/index.d.ts +11 -7
  45. package/package.json +64 -48
  46. package/webpack.config.js +2 -2
  47. package/dist/bin/generator.d.ts +0 -29
  48. package/dist/bin/generator.js +0 -17
  49. package/dist/bin/helper/controller-generator.helper.d.ts +0 -67
  50. package/dist/bin/helper/controller-generator.helper.js +0 -50
  51. package/dist/bin/helper/guard-generator.helper.d.ts +0 -32
  52. package/dist/bin/helper/guard-generator.helper.js +0 -25
  53. package/dist/bin/helper/service-generator.helper.d.ts +0 -32
  54. package/dist/bin/helper/service-generator.helper.js +0 -25
  55. package/dist/bin/meocord.d.ts +0 -19
  56. package/dist/bin/meocord.js +0 -34
  57. package/dist/common/index.d.ts +0 -19
  58. package/dist/common/index.js +0 -17
  59. package/dist/common/logger.js +0 -17
  60. package/dist/common/theme.d.ts +0 -24
  61. package/dist/common/theme.js +0 -17
  62. package/dist/core/index.js +0 -17
  63. package/dist/core/meocord-factory.d.ts +0 -24
  64. package/dist/core/meocord-factory.js +0 -17
  65. package/dist/core/meocord.app.js +0 -17
  66. package/dist/decorator/app.decorator.d.ts +0 -59
  67. package/dist/decorator/app.decorator.js +0 -61
  68. package/dist/decorator/command-builder.decorator.d.ts +0 -39
  69. package/dist/decorator/command-builder.decorator.js +0 -35
  70. package/dist/decorator/container.d.ts +0 -20
  71. package/dist/decorator/container.js +0 -17
  72. package/dist/decorator/controller.decorator.d.ts +0 -125
  73. package/dist/decorator/controller.decorator.js +0 -113
  74. package/dist/decorator/guard.decorator.d.ts +0 -101
  75. package/dist/decorator/guard.decorator.js +0 -94
  76. package/dist/decorator/index.d.ts +0 -23
  77. package/dist/decorator/index.js +0 -17
  78. package/dist/decorator/service.decorator.d.ts +0 -36
  79. package/dist/decorator/service.decorator.js +0 -36
  80. package/dist/enum/controller.enum.d.ts +0 -42
  81. package/dist/enum/controller.enum.js +0 -19
  82. package/dist/enum/index.d.ts +0 -18
  83. package/dist/enum/index.js +0 -17
  84. package/dist/interface/command-decorator.interface.d.ts +0 -43
  85. package/dist/interface/command-decorator.interface.js +0 -1
  86. package/dist/interface/index.js +0 -1
  87. package/dist/util/common.util.d.ts +0 -40
  88. package/dist/util/common.util.js +0 -38
  89. package/dist/util/embed.util.d.ts +0 -19
  90. package/dist/util/embed.util.js +0 -17
  91. package/dist/util/generator-cli.util.d.ts +0 -65
  92. package/dist/util/generator-cli.util.js +0 -49
  93. package/dist/util/index.d.ts +0 -18
  94. package/dist/util/index.js +0 -17
  95. package/dist/util/json.util.d.ts +0 -27
  96. package/dist/util/meocord-cli.util.d.ts +0 -62
  97. package/dist/util/meocord-cli.util.js +0 -50
  98. package/dist/util/meocord-config-loader.util.d.ts +0 -32
  99. package/dist/util/meocord-config-loader.util.js +0 -34
  100. package/dist/util/tsconfig.util.d.ts +0 -29
  101. package/dist/util/tsconfig.util.js +0 -32
  102. package/dist/util/wait.util.d.ts +0 -18
  103. /package/dist/{bin → esm/bin}/builder-template/builder/context-menu.builder.template +0 -0
  104. /package/dist/{bin → esm/bin}/builder-template/builder/slash.builder.template +0 -0
  105. /package/dist/{bin → esm/bin}/builder-template/controller/button.controller.template +0 -0
  106. /package/dist/{bin → esm/bin}/builder-template/controller/context-menu.controller.template +0 -0
  107. /package/dist/{bin → esm/bin}/builder-template/controller/message.controller.template +0 -0
  108. /package/dist/{bin → esm/bin}/builder-template/controller/modal-submit.controller.template +0 -0
  109. /package/dist/{bin → esm/bin}/builder-template/controller/reaction.controller.template +0 -0
  110. /package/dist/{bin → esm/bin}/builder-template/controller/select-menu.controller.template +0 -0
  111. /package/dist/{bin → esm/bin}/builder-template/controller/slash.controller.template +0 -0
  112. /package/dist/{bin → esm/bin}/builder-template/guard.template +0 -0
  113. /package/dist/{bin → esm/bin}/builder-template/service.template +0 -0
@@ -0,0 +1,48 @@
1
+ import path from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { createJiti } from 'jiti';
4
+ import { fixJSON } from './json.util.js';
5
+
6
+ /**
7
+ * Loads the MeoCord configuration file (meocord.config.ts) directly at runtime
8
+ * using jiti, without a separate compilation step.
9
+ *
10
+ * @returns {MeoCordConfig | undefined} The loaded configuration object, or undefined if loading fails.
11
+ */ function loadMeoCordConfig() {
12
+ const configPath = path.resolve(process.cwd(), 'meocord.config.ts');
13
+ if (!existsSync(configPath)) {
14
+ return undefined;
15
+ }
16
+ try {
17
+ // Read user's tsconfig.json to extract path aliases for jiti
18
+ const tsConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
19
+ const aliases = {};
20
+ if (existsSync(tsConfigPath)) {
21
+ const tsConfig = JSON.parse(fixJSON(readFileSync(tsConfigPath, 'utf-8')));
22
+ const paths = tsConfig?.compilerOptions?.paths;
23
+ if (paths) {
24
+ for (const [key, values] of Object.entries(paths)){
25
+ // Convert TS path alias format "@src/*" -> ["./src/*"] to jiti alias format
26
+ const aliasKey = key.replace('/*', '');
27
+ const aliasValue = path.resolve(process.cwd(), values[0].replace('/*', ''));
28
+ aliases[aliasKey] = aliasValue;
29
+ }
30
+ }
31
+ }
32
+ const jiti = createJiti(import.meta.url, {
33
+ interopDefault: true,
34
+ alias: aliases,
35
+ moduleCache: false
36
+ });
37
+ return jiti(configPath);
38
+ } catch (error) {
39
+ if (error instanceof Error) {
40
+ console.error(`[MeoCord] Failed to load config: ${error.message}`);
41
+ } else {
42
+ console.error(`[MeoCord] Failed to load config: Unknown error`);
43
+ }
44
+ return undefined;
45
+ }
46
+ }
47
+
48
+ export { loadMeoCordConfig };
@@ -0,0 +1,83 @@
1
+ import path from 'path';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import { Logger } from '../common/logger.js';
4
+ import '../common/theme.js';
5
+ import { tmpdir } from 'os';
6
+ import { fixJSON } from './json.util.js';
7
+
8
+ const logger = new Logger();
9
+ /**
10
+ * Prepares and modifies the project's `tsconfig.json` file for usage with tools like Webpack.
11
+ * - Verifies the existence of `tsconfig.json`.
12
+ * - Fixes invalid JSON if necessary by correcting formatting issues like comments or trailing commas.
13
+ * - Updates paths in `compilerOptions` and other sections to absolute paths.
14
+ * - Removes the `noEmit` option if present in `compilerOptions`.
15
+ * - Writes the modified `tsconfig.json` to a temporary location.
16
+ *
17
+ * @returns {string} The absolute path to the generated temporary `tsconfig.json`.
18
+ * @throws {Error} When `tsconfig.json` is missing or cannot be fixed/parsing fails.
19
+ */ function prepareModifiedTsConfig() {
20
+ const tsConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
21
+ // Ensure tsconfig.json exists
22
+ if (!existsSync(tsConfigPath)) {
23
+ throw new Error(`tsconfig.json not found in: ${process.cwd()}`);
24
+ }
25
+ const tsConfigContent = readFileSync(tsConfigPath, 'utf-8');
26
+ let parsedConfig;
27
+ try {
28
+ parsedConfig = JSON.parse(tsConfigContent);
29
+ } catch (error) {
30
+ logger.warn('Invalid JSON detected in tsconfig.json!', error);
31
+ logger.log('Attempting to fix JSON...');
32
+ try {
33
+ const fixedContent = fixJSON(tsConfigContent);
34
+ parsedConfig = JSON.parse(fixedContent);
35
+ writeFileSync(tsConfigPath, fixedContent, 'utf-8');
36
+ logger.info('Fixed and updated tsconfig.json successfully.');
37
+ } catch (fixError) {
38
+ throw new Error(`Failed to parse tsconfig.json, even after attempting to fix: ${fixError instanceof Error ? fixError.message : fixError}`);
39
+ }
40
+ }
41
+ // Process compilerOptions
42
+ if (parsedConfig?.compilerOptions) {
43
+ const pathOptions = [
44
+ 'outDir',
45
+ 'rootDir',
46
+ 'baseUrl',
47
+ 'tsBuildInfoFile'
48
+ ];
49
+ // Convert relative paths to absolute paths in `compilerOptions`
50
+ pathOptions.forEach((option)=>{
51
+ if (parsedConfig.compilerOptions[option]) {
52
+ parsedConfig.compilerOptions[option] = path.resolve(process.cwd(), parsedConfig.compilerOptions[option]);
53
+ }
54
+ });
55
+ const additionalKeys = [
56
+ 'include',
57
+ 'exclude',
58
+ 'typeRoots'
59
+ ];
60
+ // Convert relative paths to absolute paths in additional keys
61
+ additionalKeys.forEach((key)=>{
62
+ if (parsedConfig[key]) {
63
+ parsedConfig[key] = parsedConfig[key].map((p)=>path.resolve(process.cwd(), p));
64
+ }
65
+ });
66
+ // Resolve path mappings in `paths` if present
67
+ if (parsedConfig.compilerOptions.paths) {
68
+ Object.keys(parsedConfig.compilerOptions.paths).forEach((alias)=>{
69
+ parsedConfig.compilerOptions.paths[alias] = parsedConfig.compilerOptions.paths[alias].map((p)=>path.resolve(process.cwd(), p));
70
+ });
71
+ }
72
+ // Remove `noEmit` option if it exists
73
+ if ('noEmit' in parsedConfig.compilerOptions) {
74
+ delete parsedConfig.compilerOptions.noEmit;
75
+ }
76
+ }
77
+ // Write the modified configuration to a temporary location for usage
78
+ const tempTsConfigPath = path.resolve(path.join(tmpdir(), 'modified-tsconfig.json'));
79
+ writeFileSync(tempTsConfigPath, JSON.stringify(parsedConfig, null, 2));
80
+ return tempTsConfigPath;
81
+ }
82
+
83
+ export { prepareModifiedTsConfig };
@@ -14,4 +14,8 @@
14
14
  *
15
15
  * You should have received a copy of the GNU General Public License
16
16
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */export default function wait(a){return new Promise(function(b){return setTimeout(b,a)})}
17
+ */ function wait(ms) {
18
+ return new Promise((resolve)=>setTimeout(resolve, ms));
19
+ }
20
+
21
+ export { wait as default };
@@ -1,3 +1,5 @@
1
+ import { ColorResolvable } from 'discord.js';
2
+
1
3
  /**
2
4
  * MeoCord Framework
3
5
  * Copyright (C) 2025 Ukasyah Rahmatullah Zada
@@ -15,7 +17,7 @@
15
17
  * You should have received a copy of the GNU General Public License
16
18
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
19
  */
18
- export declare class Logger {
20
+ declare class Logger {
19
21
  private context?;
20
22
  private readonly colorMap;
21
23
  constructor(context?: string | undefined);
@@ -28,3 +30,30 @@ export declare class Logger {
28
30
  private formatMessage;
29
31
  private logWithContext;
30
32
  }
33
+
34
+ /**
35
+ * MeoCord Framework
36
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
37
+ *
38
+ * This program is free software: you can redistribute it and/or modify
39
+ * it under the terms of the GNU General Public License as published by
40
+ * the Free Software Foundation, either version 3 of the License, or
41
+ * (at your option) any later version.
42
+ *
43
+ * This program is distributed in the hope that it will be useful,
44
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
+ * GNU General Public License for more details.
47
+ *
48
+ * You should have received a copy of the GNU General Public License
49
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
50
+ */
51
+
52
+ declare class Theme {
53
+ static successColor: ColorResolvable;
54
+ static infoColor: ColorResolvable;
55
+ static errorColor: ColorResolvable;
56
+ static warningColor: ColorResolvable;
57
+ }
58
+
59
+ export { Logger, Theme };
@@ -1,3 +1,6 @@
1
+ import { ServiceIdentifier } from 'inversify';
2
+ import { Client, ActivityOptions } from 'discord.js';
3
+
1
4
  /**
2
5
  * MeoCord Framework
3
6
  * Copyright (C) 2025 Ukasyah Rahmatullah Zada
@@ -15,8 +18,8 @@
15
18
  * You should have received a copy of the GNU General Public License
16
19
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
20
  */
18
- import { type ActivityOptions, Client } from 'discord.js';
19
- export declare class MeoCordApp {
21
+
22
+ declare class MeoCordApp {
20
23
  private readonly controllers;
21
24
  private readonly discordClient;
22
25
  private discordToken;
@@ -34,3 +37,28 @@ export declare class MeoCordApp {
34
37
  private handleReaction;
35
38
  private gracefulShutdown;
36
39
  }
40
+
41
+ /**
42
+ * MeoCord Framework
43
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
44
+ *
45
+ * This program is free software: you can redistribute it and/or modify
46
+ * it under the terms of the GNU General Public License as published by
47
+ * the Free Software Foundation, either version 3 of the License, or
48
+ * (at your option) any later version.
49
+ *
50
+ * This program is distributed in the hope that it will be useful,
51
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53
+ * GNU General Public License for more details.
54
+ *
55
+ * You should have received a copy of the GNU General Public License
56
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
57
+ */
58
+
59
+ declare class MeoCordFactory {
60
+ private static logger;
61
+ static create(target: ServiceIdentifier): MeoCordApp;
62
+ }
63
+
64
+ export { MeoCordFactory };
@@ -0,0 +1,425 @@
1
+ import { CommandType } from '../enum/index.js';
2
+ import { SlashCommandBuilder, SlashCommandSubcommandsOnlyBuilder, ContextMenuCommandBuilder, ButtonInteraction, StringSelectMenuInteraction, ChatInputCommandInteraction, UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, ModalSubmitInteraction, OmitPartialGroupDMChannel, Message, MessageReaction, PartialMessageReaction, ClientOptions, ActivityOptions } from 'discord.js';
3
+ import { ReactionHandlerOptions, GuardInterface } from '../interface/index.js';
4
+ import { ServiceIdentifier, Container } from 'inversify';
5
+ import 'webpack';
6
+
7
+ /**
8
+ * MeoCord Framework
9
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
10
+ *
11
+ * This program is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+ */
24
+
25
+ /**
26
+ * `@Service()` decorator to mark a class as a service that can be injected into controllers or used as standalone services.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * @Service()
31
+ * class MyService {
32
+ * constructor(private anotherService: AnotherService) {}
33
+ *
34
+ * doSomething() {
35
+ * this.anotherService.alsoDoSomething()
36
+ * console.log('Hello, World!')
37
+ * }
38
+ * }
39
+ * ```
40
+ * @returns A decorator function to apply to the class.
41
+ */
42
+ declare function Service<T>(): (target: new (...args: any[]) => T) => void;
43
+
44
+ /**
45
+ * MeoCord Framework
46
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
47
+ *
48
+ * This program is free software: you can redistribute it and/or modify
49
+ * it under the terms of the GNU General Public License as published by
50
+ * the Free Software Foundation, either version 3 of the License, or
51
+ * (at your option) any later version.
52
+ *
53
+ * This program is distributed in the hope that it will be useful,
54
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56
+ * GNU General Public License for more details.
57
+ *
58
+ * You should have received a copy of the GNU General Public License
59
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
60
+ */
61
+
62
+ /**
63
+ * Base interface for a command builder.
64
+ */
65
+ interface CommandBuilderBase<T extends CommandType.SLASH | CommandType.CONTEXT_MENU = CommandType.SLASH | CommandType.CONTEXT_MENU> {
66
+ /**
67
+ * Builds the command structure using the specified command name.
68
+ *
69
+ * @param commandName - The name of the command.
70
+ * @returns A SlashCommandBuilder or ContextMenuCommandBuilder instance.
71
+ */
72
+ build: (commandName: string) => T extends CommandType.SLASH ? SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder : T extends CommandType.CONTEXT_MENU ? ContextMenuCommandBuilder : never;
73
+ }
74
+ type CommandBuilderConstructor<T extends CommandType.SLASH | CommandType.CONTEXT_MENU> = new () => CommandBuilderBase<T>;
75
+ /**
76
+ * Command metadata describing a registered command method.
77
+ */
78
+ interface CommandMetadata<T extends string = string> {
79
+ methodName: string;
80
+ builder: ReturnType<CommandBuilderBase['build']> | undefined;
81
+ type: CommandType;
82
+ regex?: RegExp;
83
+ dynamicParams?: T[];
84
+ }
85
+ type CommandInteractionType<CBC extends CommandType.SLASH | CommandType.CONTEXT_MENU, T extends CommandBuilderConstructor<CBC> | CommandType> = T extends CommandType.BUTTON ? ButtonInteraction : T extends CommandType.SELECT_MENU ? StringSelectMenuInteraction : T extends CommandBuilderConstructor<CommandType.SLASH> ? ChatInputCommandInteraction : T extends CommandBuilderConstructor<CommandType.CONTEXT_MENU> ? UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction : T extends CommandType.MODAL_SUBMIT ? ModalSubmitInteraction : never;
86
+
87
+ /**
88
+ * MeoCord Framework
89
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
90
+ *
91
+ * This program is free software: you can redistribute it and/or modify
92
+ * it under the terms of the GNU General Public License as published by
93
+ * the Free Software Foundation, either version 3 of the License, or
94
+ * (at your option) any later version.
95
+ *
96
+ * This program is distributed in the hope that it will be useful,
97
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
98
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99
+ * GNU General Public License for more details.
100
+ *
101
+ * You should have received a copy of the GNU General Public License
102
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
103
+ */
104
+
105
+ /**
106
+ * This decorator is used to mark a class as a Discord command builder that later can be registered on the `@Command` decorator.
107
+ * It defines the command type using metadata and dynamically makes the class injectable if it isn't already.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * @CommandBuilder(CommandType.SLASH)
112
+ * export class MySlashCommand implements CommandBuilderBase {
113
+ * build(commandName: string): SlashCommandBuilder {
114
+ * return new SlashCommandBuilder().setName(commandName).setDescription('A sample slash command')
115
+ * }
116
+ * }
117
+ *```
118
+ *
119
+ * @param commandType - The type of the command, specified from the `CommandType` enum.
120
+ * @returns A decorator function that makes the target class injectable
121
+ * and assigns the `commandType` metadata.
122
+ */
123
+ declare function CommandBuilder<T extends CommandType.SLASH | CommandType.CONTEXT_MENU>(commandType: T): (target: new () => CommandBuilderBase<T>) => void;
124
+
125
+ /**
126
+ * MeoCord Framework
127
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
128
+ *
129
+ * This program is free software: you can redistribute it and/or modify
130
+ * it under the terms of the GNU General Public License as published by
131
+ * the Free Software Foundation, either version 3 of the License, or
132
+ * (at your option) any later version.
133
+ *
134
+ * This program is distributed in the hope that it will be useful,
135
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
136
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
137
+ * GNU General Public License for more details.
138
+ *
139
+ * You should have received a copy of the GNU General Public License
140
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
141
+ */
142
+
143
+ /**
144
+ * Decorator to register message handlers in the controller.
145
+ *
146
+ * @param keyword - An optional keyword to filter messages this handler should respond to.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * @MessageHandler('hello')
151
+ * async handleHelloMessage(message: Message) {
152
+ * await message.reply('Hello! How can I help you?');
153
+ * }
154
+ *
155
+ * @MessageHandler()
156
+ * async handleAnyMessage(message: Message) {
157
+ * console.log(`Received a message: ${message.content}`);
158
+ * }
159
+ * ```
160
+ */
161
+ declare function MessageHandler<T extends OmitPartialGroupDMChannel<Message<boolean>>, R extends void | Promise<void>>(keyword?: string): (target: object, propertyKey: string, _descriptor: TypedPropertyDescriptor<(message: T) => R>) => void;
162
+ /**
163
+ * Decorator to register reaction handlers in the controller.
164
+ *
165
+ * @param emoji - Optional emoji name to filter reactions this handler should respond to.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * @ReactionHandler('👍')
170
+ * async handleThumbsUpReaction(reaction: MessageReaction, { user }: ReactionHandlerOptions) {
171
+ * console.log(`User ${user.username} reacted with 👍`);
172
+ * }
173
+ *
174
+ * @ReactionHandler()
175
+ * async handleAnyReaction(reaction: MessageReaction, { user }: ReactionHandlerOptions) {
176
+ * console.log(`User ${user.username} reacted with ${reaction.emoji.name}`);
177
+ * }
178
+ * ```
179
+ */
180
+ declare function ReactionHandler<T extends MessageReaction | PartialMessageReaction, R extends void | Promise<void>>(emoji?: string): (target: object, propertyKey: string, _descriptor: TypedPropertyDescriptor<(reaction: T, options: ReactionHandlerOptions) => R> | TypedPropertyDescriptor<(reaction: T) => R>) => void;
181
+ /**
182
+ * Retrieves reaction handlers metadata from a given controller.
183
+ *
184
+ * @param controller - The controller class instance.
185
+ * @returns An array of reaction handler metadata objects.
186
+ */
187
+ declare function getReactionHandlers(controller: any): {
188
+ emoji: string | undefined;
189
+ method: string;
190
+ }[];
191
+ /**
192
+ * Retrieves message handlers metadata from a given controller.
193
+ *
194
+ * @param controller - The controller class instance.
195
+ * @returns An array of message handler method names.
196
+ */
197
+ declare function getMessageHandlers(controller: any): {
198
+ keyword: string | undefined;
199
+ method: string;
200
+ }[];
201
+ /**
202
+ * Decorator to register command methods in a controller.
203
+ *
204
+ * @param commandName - The name or pattern of the command.
205
+ * @param builderOrType - A command builder class or a command type from `CommandType`.
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * @Command('help', CommandType.SLASH)
210
+ * public async handleHelp(interaction: ChatInputCommandInteraction) {
211
+ * await interaction.reply('This is the help command!')
212
+ * }
213
+ *
214
+ * @Command('stats-{id}', CommandType.BUTTON)
215
+ * public async handleStats(message: ButtonInteraction, { id }) {
216
+ * await message.reply(`Fetching stats for ID: ${id}`);
217
+ * }
218
+ * ```
219
+ */
220
+ declare function Command<CBC extends CommandType.SLASH | CommandType.CONTEXT_MENU, T extends CommandBuilderConstructor<CBC> | CommandType>(commandName: string, builderOrType: T): <P extends Record<string, any>, R extends Promise<void> | void>(target: object, propertyKey: string, _descriptor: TypedPropertyDescriptor<(interaction: CommandInteractionType<CBC, T>, params: P) => R> | TypedPropertyDescriptor<(interaction: CommandInteractionType<CBC, T>) => R>) => void;
221
+ /**
222
+ * Retrieves the command map for a given controller.
223
+ *
224
+ * @param controller - The controller class instance.
225
+ * @returns A record containing command metadata indexed by command names.
226
+ */
227
+ declare function getCommandMap<T extends string>(controller: any): Record<string, CommandMetadata<T>[]>;
228
+ /**
229
+ * Decorator to mark a class as a controller that can later be registered to the App class `(app.ts)` using the `@MeoCord` decorator.
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * @Controller()
234
+ * export class PingSlashController {
235
+ * constructor(private pingService: PingService) {}
236
+ *
237
+ * @Command('ping', PingCommandBuilder)
238
+ * async ping(interaction: ChatInputCommandInteraction) {
239
+ * const response = await this.pingService.handlePing()
240
+ * await interaction.reply(response)
241
+ * }
242
+ * }
243
+ * ```
244
+ */
245
+ declare function Controller(): (target: any) => void;
246
+
247
+ /**
248
+ * MeoCord Framework
249
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
250
+ *
251
+ * This program is free software: you can redistribute it and/or modify
252
+ * it under the terms of the GNU General Public License as published by
253
+ * the Free Software Foundation, either version 3 of the License, or
254
+ * (at your option) any later version.
255
+ *
256
+ * This program is distributed in the hope that it will be useful,
257
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
258
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
259
+ * GNU General Public License for more details.
260
+ *
261
+ * You should have received a copy of the GNU General Public License
262
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
263
+ */
264
+
265
+ /**
266
+ * `@Guard()` decorator to mark a class as a Guard that later can be added on `@UseGuard` decorator.
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * @Guard()
271
+ export class ButtonInteractionGuard implements GuardInterface {
272
+ private readonly logger = new Logger(ButtonInteractionGuard.name)
273
+
274
+ async canActivate(context: ButtonInteraction, { ownerId }: { ownerId: string }): Promise<boolean> {
275
+ if (context.user.id !== ownerId) {
276
+ this.logger.error(
277
+ `User with id ${context.user.id} is not allowed to use this command that initiated by user with id ${ownerId}.`,
278
+ )
279
+ const embed = generateErrorEmbed(
280
+ `Hi <@${context.user.id}>, this command can only be used by the person who initiated it: <@${ownerId}>.`,
281
+ )
282
+ await context.reply({
283
+ embeds: [embed],
284
+ flags: MessageFlagsBitField.Flags.Ephemeral,
285
+ })
286
+ return false
287
+ }
288
+ return true
289
+ }
290
+ }
291
+ * ```
292
+ */
293
+ declare function Guard(): (target: any) => void;
294
+ /**
295
+ * Type for a guard with parameters.
296
+ * This type defines a guard that requires additional parameters (other than the default constructor).
297
+ */
298
+ interface GuardWithParams {
299
+ /**
300
+ * The guard class that needs to be instantiated.
301
+ */
302
+ provide: new (...args: any[]) => GuardInterface;
303
+ /**
304
+ * Parameters to be passed to the guard during instantiation.
305
+ */
306
+ params: Record<string, any>;
307
+ }
308
+ /**
309
+ * `@UseGuard()` decorator to apply one or more guards to methods.
310
+ * Guards are used to handle permission checks before executing a method.
311
+ * Each guard must use `@Guard` decorator and implement the `canActivate` method, which determines
312
+ * whether the method should be allowed to execute based on the provided context (Interaction, Message, or Reaction) and arguments.
313
+ * This decorator ensures that all guards pass validation before calling the original method.
314
+ * Supports guards that are parameterized (accepting additional parameters).
315
+ *
316
+ * @param guards - One or more guard classes to apply. These can be regular guards or guards with additional parameters.
317
+ * - If providing a guard with parameters, it should be an object with:
318
+ * - `provide`: The guard class to instantiate. Must implement `GuardInterface`.
319
+ * - `params`: A record of key-value pairs to be passed as additional properties to the guard instance.
320
+ * @returns A method decorator function that applies the guards to the method.
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * // Method-level usage
325
+ * @Command('profile-{id}', CommandType.BUTTON)
326
+ * @UseGuard(
327
+ * { provide: RateLimiterGuard, params: { limit: 2, window: 3000 } },
328
+ * ButtonInteractionGuard
329
+ * )
330
+ * async showProfileById(interaction: ButtonInteraction, { id }: { id: string }) {
331
+ * await interaction.reply(`Profile ID: ${id}`)
332
+ * }
333
+ *
334
+ * // Class-level usage
335
+ * @Controller()
336
+ * @UseGuard(GlobalGuard)
337
+ * class MyController {
338
+ * @Command('ping', CommandType.SLASH)
339
+ * async ping(interaction: ChatInputCommandInteraction) {
340
+ * await interaction.reply('Pong!')
341
+ * }
342
+ * }
343
+ * ```
344
+ */
345
+ declare function UseGuard(...guards: ((new (...args: any[]) => GuardInterface) | GuardWithParams)[]): any;
346
+
347
+ /**
348
+ * MeoCord Framework
349
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
350
+ *
351
+ * This program is free software: you can redistribute it and/or modify
352
+ * it under the terms of the GNU General Public License as published by
353
+ * the Free Software Foundation, either version 3 of the License, or
354
+ * (at your option) any later version.
355
+ *
356
+ * This program is distributed in the hope that it will be useful,
357
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
358
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
359
+ * GNU General Public License for more details.
360
+ *
361
+ * You should have received a copy of the GNU General Public License
362
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
363
+ */
364
+
365
+ /**
366
+ * `@MeoCord()` decorator for initializing and setting up the MeoCord application.
367
+ *
368
+ * @param {Object} options - The decorator options.
369
+ * @param {ServiceIdentifier[]} options.controllers - The list of controllers to be registered.
370
+ * @param {ClientOptions} options.clientOptions - The Discord client options for initializing the bot.
371
+ * @param {ActivityOptions[]} [options.activities] - Optional activities for the bot.
372
+ * @param {ServiceIdentifier[]} [options.services] - Optional services to be registered.
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * @MeoCord({
377
+ * controllers: [PingSlashController],
378
+ * clientOptions: {
379
+ * intents: [
380
+ * GatewayIntentBits.Guilds,
381
+ * GatewayIntentBits.GuildMembers,
382
+ * GatewayIntentBits.GuildMessages,
383
+ * GatewayIntentBits.GuildMessageReactions,
384
+ * GatewayIntentBits.MessageContent,
385
+ * ],
386
+ * partials: [Partials.Message, Partials.Channel, Partials.Reaction],
387
+ * },
388
+ * activities: [{
389
+ * name: `${sample(['Genshin', 'ZZZ'])} with Romeo`,
390
+ * type: ActivityType.Playing,
391
+ * url: 'https://enka.network/u/824957678/',
392
+ * }],
393
+ * services: [MyStandaloneService],
394
+ * })
395
+ * class MyApp {}
396
+ * ```
397
+ **/
398
+ declare function MeoCord(options: {
399
+ controllers: ServiceIdentifier[];
400
+ clientOptions: ClientOptions;
401
+ activities?: ActivityOptions[];
402
+ services?: ServiceIdentifier[];
403
+ }): (target: any) => void;
404
+
405
+ /**
406
+ * MeoCord Framework
407
+ * Copyright (C) 2025 Ukasyah Rahmatullah Zada
408
+ *
409
+ * This program is free software: you can redistribute it and/or modify
410
+ * it under the terms of the GNU General Public License as published by
411
+ * the Free Software Foundation, either version 3 of the License, or
412
+ * (at your option) any later version.
413
+ *
414
+ * This program is distributed in the hope that it will be useful,
415
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
416
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
417
+ * GNU General Public License for more details.
418
+ *
419
+ * You should have received a copy of the GNU General Public License
420
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
421
+ */
422
+
423
+ declare const mainContainer: Container;
424
+
425
+ export { Command, CommandBuilder, Controller, Guard, MeoCord, MessageHandler, ReactionHandler, Service, UseGuard, getCommandMap, getMessageHandlers, getReactionHandlers, mainContainer };
@@ -0,0 +1,18 @@
1
+ declare enum CommandType {
2
+ SLASH = "SLASH",
3
+ BUTTON = "BUTTON",
4
+ CONTEXT_MENU = "CONTEXT_MENU",
5
+ SELECT_MENU = "SELECT_MENU",
6
+ MODAL_SUBMIT = "MODAL_SUBMIT"
7
+ }
8
+ /**
9
+ * Enum representing actions that can be performed on a message reaction.
10
+ */
11
+ declare enum ReactionHandlerAction {
12
+ /** Reaction added to a message. */
13
+ ADD = "ADD",
14
+ /** Reaction removed from a message. */
15
+ REMOVE = "REMOVE"
16
+ }
17
+
18
+ export { CommandType, ReactionHandlerAction };