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,33 @@
1
+ import path from 'path';
2
+ import { Logger } from '../../common/logger.js';
3
+ import '../../common/theme.js';
4
+ import { validateAndFormatName, buildTemplate, createDirectoryIfNotExists, generateFile } from '../../util/generator-cli.util.js';
5
+
6
+ class ServiceGeneratorHelper {
7
+ /**
8
+ * Generates a service file based on the provided service name.
9
+ * Validates and formats the service name, creates the necessary directories,
10
+ * and generates the service file using a predefined template.
11
+ *
12
+ * @param serviceName - The name of the service to generate.
13
+ * It can include slashes for nested paths.
14
+ * @throws Exits the process if the service name is not provided or invalid.
15
+ */ generateService(serviceName) {
16
+ if (!serviceName) {
17
+ this.logger.error('Service name is required.');
18
+ process.exit(1);
19
+ }
20
+ const { parts, kebabCaseName, className } = validateAndFormatName(serviceName);
21
+ const serviceDir = path.join(process.cwd(), 'src', 'services', ...parts);
22
+ const serviceFile = path.join(serviceDir, `${kebabCaseName}.service.ts`);
23
+ const serviceTemplate = buildTemplate(className, 'service.template');
24
+ createDirectoryIfNotExists(serviceDir);
25
+ generateFile(serviceFile, serviceTemplate);
26
+ }
27
+ constructor(appName){
28
+ this.appName = appName;
29
+ this.logger = new Logger(this.appName);
30
+ }
31
+ }
32
+
33
+ export { ServiceGeneratorHelper };
@@ -0,0 +1,333 @@
1
+ #!/usr/bin/env node
2
+ import path from 'path';
3
+ import webpack from 'webpack';
4
+ import { Logger } from '../common/logger.js';
5
+ import '../common/theme.js';
6
+ import { spawn } from 'node:child_process';
7
+ import { capitalize } from 'lodash-es';
8
+ import wait from '../util/wait.util.js';
9
+ import { GeneratorCLI } from './generator.js';
10
+ import * as fs from 'node:fs';
11
+ import { setEnvironment, compileAndValidateConfig } from '../util/common.util.js';
12
+ import { Command } from 'commander';
13
+ import { simpleGit } from 'simple-git';
14
+ import chalk from 'chalk';
15
+ import { execSync } from 'child_process';
16
+ import { ensureReady, configureCommandHelp } from '../util/meocord-cli.util.js';
17
+ import packageJson from '../package.json.js';
18
+ import { fileURLToPath } from 'url';
19
+
20
+ const __filename$1 = fileURLToPath(import.meta.url);
21
+ const __dirname$1 = path.dirname(__filename$1);
22
+ /**
23
+ * A Command Line Interface (CLI) for managing the MeoCord application.
24
+ */ class MeoCordCLI {
25
+ /**
26
+ * Configures and runs the MeoCord CLI.
27
+ */ async run() {
28
+ let program = new Command();
29
+ program.name(this.appName.toLowerCase()).description(`CLI for managing the ${this.appName} application`).version(this.version);
30
+ program.command('show').description('Display information').option('-w, --warranty', 'Display warranty disclaimer').option('-c, --license', 'Display licensing conditions and usage rights').action((options)=>{
31
+ if (!options.warranty && !options.license) {
32
+ program.commands.find((cmd)=>cmd.name() === 'show')?.outputHelp();
33
+ process.exit(1);
34
+ }
35
+ if (options.warranty) {
36
+ console.log(`
37
+ This program is distributed in the hope that it will be useful,
38
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
39
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
40
+
41
+ The authors of this software are not responsible for damages caused
42
+ by the usage, misuse, or inability to use the software.
43
+
44
+ See the GNU General Public License for full details:
45
+ <https://www.gnu.org/licenses/>.
46
+ `);
47
+ }
48
+ if (options.license) {
49
+ console.log(`
50
+ This program is free software: you can redistribute it and/or
51
+ modify it under the terms of the GNU General Public License as
52
+ published by the Free Software Foundation, either version 3 of
53
+ the License, or (at your option) any later version.
54
+
55
+ Key conditions of the GNU GPL v3:
56
+ - You can use this software for personal, academic, or commercial purposes.
57
+ - If you distribute modified versions, you must share the source code under the same GPL v3 license.
58
+ - The original copyright must be retained.
59
+
60
+ For full license details, refer to:
61
+ <https://www.gnu.org/licenses/gpl-3.0.txt>
62
+ `);
63
+ }
64
+ });
65
+ program.command('create <app-name>').description('Create a new MeoCord application').action(async (appName)=>await this.createApp(appName));
66
+ program.command('build').description('Build the application').option('-d, --dev', 'Build in development mode').option('-p, --prod', 'Build in production mode').action(async (options)=>{
67
+ await ensureReady();
68
+ const mode = options.prod ? 'production' : 'development';
69
+ setEnvironment(mode);
70
+ await compileAndValidateConfig();
71
+ await this.build(mode);
72
+ });
73
+ program.command('start').description('Start the application').option('-b, --build', 'Pre-build before starting').option('-d, --dev', 'Start in development mode').option('-p, --prod', 'Start in production mode').action(async (options)=>{
74
+ await ensureReady();
75
+ const mode = options.prod ? 'production' : 'development';
76
+ setEnvironment(mode);
77
+ if (options.build || options.dev) {
78
+ await compileAndValidateConfig();
79
+ }
80
+ if (options.build) {
81
+ await this.build(mode);
82
+ }
83
+ options.prod ? await this.startProd() : await this.startDev();
84
+ });
85
+ program = this.generatorCLI.register(program);
86
+ configureCommandHelp(program);
87
+ program.showHelpAfterError().parse(process.argv);
88
+ }
89
+ async createApp(appName) {
90
+ const kebabCaseAppName = appName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
91
+ const appPath = path.resolve(process.cwd(), kebabCaseAppName);
92
+ const gitRepo = 'https://github.com/l7aromeo/meocord-template.git';
93
+ console.info(chalk.blueBright(`🚀 Creating a new MeoCord app: ${chalk.bold(kebabCaseAppName)}`));
94
+ try {
95
+ // Validate if directory already exists
96
+ if (fs.existsSync(appPath)) {
97
+ console.error(chalk.red(`❌ Directory "${chalk.bold(kebabCaseAppName)}" already exists.`));
98
+ await wait(100);
99
+ process.exit(1);
100
+ }
101
+ // Check Node.js version
102
+ const MINIMUM_NODE_VERSION = '22.14.0';
103
+ const [major, minor, patch] = process.version.slice(1).split('.').map(Number);
104
+ const [minMajor, minMinor, minPatch] = MINIMUM_NODE_VERSION.split('.').map(Number);
105
+ if (major < minMajor || major === minMajor && minor < minMinor || major === minMajor && minor === minMinor && patch < minPatch) {
106
+ console.error(chalk.red(`❌ Node.js v${MINIMUM_NODE_VERSION} or higher is required. Current version: v${process.version}.`));
107
+ await wait(100);
108
+ process.exit(1);
109
+ }
110
+ // Clone the template repository
111
+ console.info(chalk.blueBright('📦 Fetching template...'));
112
+ await simpleGit().clone(gitRepo, appPath);
113
+ console.log(chalk.green(`✔ App successfully created at: ${chalk.bold(appPath)}`));
114
+ // Remove .git history from template
115
+ fs.rmSync(path.join(appPath, '.git'), {
116
+ recursive: true,
117
+ force: true
118
+ });
119
+ // Initialize a new Git repository
120
+ console.info(chalk.blueBright('🔧 Initializing Git repository...'));
121
+ const git = simpleGit(appPath);
122
+ await git.init();
123
+ await git.add('./*');
124
+ await git.commit('Initial commit');
125
+ console.log(chalk.green('✔ Git repository initialized.'));
126
+ // Install dependencies
127
+ console.info(chalk.blueBright('📦 Installing dependencies...'));
128
+ execSync(`cd ${kebabCaseAppName} && corepack enable && yarn install`, {
129
+ stdio: 'inherit'
130
+ });
131
+ console.log(chalk.green('✔ Dependencies installed successfully.'));
132
+ console.log(chalk.greenBright(`🎉 MeoCord app "${chalk.bold(kebabCaseAppName)}" is ready!`));
133
+ } catch (error) {
134
+ console.error(chalk.red(`❌ Failed to create app: ${error instanceof Error ? error.message : String(error)}`));
135
+ await wait(100);
136
+ process.exit(1);
137
+ }
138
+ }
139
+ /**
140
+ * Builds the MeoCord application in the specified mode.
141
+ *
142
+ * @param mode - The build mode ('production' or 'development').
143
+ */ async build(mode) {
144
+ try {
145
+ this.clearConsole();
146
+ this.logger.info(`Building ${mode} version...`);
147
+ const webpackConfig = (await import(this.webpackConfigPath)).default;
148
+ const compiler = webpack({
149
+ ...webpackConfig,
150
+ mode
151
+ });
152
+ if (!compiler) {
153
+ this.logger.error('Failed to create webpack compiler instance.');
154
+ throw new Error('Failed to create webpack compiler instance.');
155
+ }
156
+ // Workaround for Bun: Keep the event loop alive while webpack runs
157
+ // Bun sometimes exits before async callbacks fire
158
+ let keepAliveTimer = null;
159
+ await new Promise((resolve, reject)=>{
160
+ keepAliveTimer = setInterval(()=>{
161
+ // Keeps event loop active
162
+ }, 100);
163
+ compiler.run((err, stats)=>{
164
+ if (keepAliveTimer) {
165
+ clearInterval(keepAliveTimer);
166
+ keepAliveTimer = null;
167
+ }
168
+ if (err) {
169
+ this.logger.error(`Build encountered an error: ${err.message}`);
170
+ return reject(`Build encountered an error: ${err.message}`);
171
+ }
172
+ if (stats?.hasErrors()) {
173
+ this.logger.error('Build failed due to errors in the compilation process:', stats.compilation.errors);
174
+ } else {
175
+ this.logger.info(`${capitalize(mode)} build completed successfully.`);
176
+ }
177
+ compiler.close((closeErr)=>{
178
+ if (closeErr) {
179
+ this.logger.error(`Error occurred while closing the compiler: ${closeErr.message}`);
180
+ return reject(`Error occurred while closing the compiler: ${closeErr.message}`);
181
+ }
182
+ resolve();
183
+ });
184
+ });
185
+ });
186
+ } catch (error) {
187
+ this.logger.error(`Build process failed: ${error.message}`);
188
+ await wait(100);
189
+ process.exit(1);
190
+ }
191
+ }
192
+ /**
193
+ * Starts the MeoCord application in development mode with live updates.
194
+ */ async startDev() {
195
+ try {
196
+ this.clearConsole();
197
+ this.logger.log('Starting watch mode...');
198
+ const webpackConfig = (await import(this.webpackConfigPath)).default;
199
+ const compiler = webpack({
200
+ ...webpackConfig,
201
+ mode: 'development'
202
+ });
203
+ if (!compiler) {
204
+ this.logger.error('Failed to create webpack compiler instance.');
205
+ await wait(100);
206
+ process.exit(1);
207
+ }
208
+ let nodemonProcess = null;
209
+ let isRunning = false;
210
+ const watch = ()=>compiler.watch({}, (err, stats)=>{
211
+ if (err) {
212
+ this.logger.error(`Webpack Error: ${err.message}`);
213
+ return;
214
+ }
215
+ if (stats?.hasErrors()) {
216
+ this.logger.error('Build failed due to errors in the compilation process:', stats.compilation.errors);
217
+ } else {
218
+ if (nodemonProcess) {
219
+ nodemonProcess.kill();
220
+ nodemonProcess = null;
221
+ }
222
+ nodemonProcess = spawn('npx -y nodemon', [
223
+ '-q',
224
+ this.mainJSPath
225
+ ], {
226
+ shell: true,
227
+ cwd: this.projectRoot,
228
+ stdio: 'inherit'
229
+ });
230
+ isRunning = true;
231
+ }
232
+ });
233
+ watch();
234
+ let debounceWatcher;
235
+ const fsWatcher = fs.watch(path.resolve(process.cwd(), 'meocord.config.ts'), ()=>{
236
+ clearTimeout(debounceWatcher);
237
+ debounceWatcher = setTimeout(async ()=>{
238
+ if (isRunning && nodemonProcess) {
239
+ isRunning = false;
240
+ this.logger.log('MeoCord config change detected, reloading config...');
241
+ if (nodemonProcess && !nodemonProcess.killed) {
242
+ nodemonProcess.kill();
243
+ nodemonProcess = null;
244
+ }
245
+ await new Promise((resolve)=>compiler.close(resolve));
246
+ watch();
247
+ }
248
+ }, 300);
249
+ });
250
+ let sigintReceived = false;
251
+ process.on('SIGINT', async ()=>{
252
+ if (sigintReceived) {
253
+ // Second Ctrl+C — force kill and exit immediately
254
+ if (nodemonProcess && !nodemonProcess.killed) nodemonProcess.kill('SIGKILL');
255
+ process.exit(1);
256
+ }
257
+ sigintReceived = true;
258
+ // Nodemon and the bot already received SIGINT from the process group.
259
+ // Clean up parent-owned resources and wait for nodemon to exit.
260
+ fsWatcher.close();
261
+ if (nodemonProcess && !nodemonProcess.killed) {
262
+ nodemonProcess.on('exit', async ()=>{
263
+ await new Promise((resolve)=>compiler.close(resolve));
264
+ process.exit(0);
265
+ });
266
+ } else {
267
+ await new Promise((resolve)=>compiler.close(resolve));
268
+ process.exit(0);
269
+ }
270
+ });
271
+ } catch (error) {
272
+ this.logger.error(`Failed to start: ${error.message}`);
273
+ }
274
+ }
275
+ /**
276
+ * Starts the MeoCord application in production mode.
277
+ */ async startProd() {
278
+ try {
279
+ // Check if mainJS exists before proceeding
280
+ if (!fs.existsSync(this.mainJSPath)) {
281
+ this.logger.error(`Main entry file (main.js) not found! You might need to build before running in production mode.`);
282
+ await wait(100);
283
+ process.exit(1);
284
+ }
285
+ this.clearConsole();
286
+ this.logger.log('Starting...');
287
+ const start = spawn(`node ${this.mainJSPath}`, {
288
+ shell: true,
289
+ cwd: this.projectRoot,
290
+ stdio: 'inherit'
291
+ }).on('spawn', this.clearConsole);
292
+ start.on('exit', (code)=>{
293
+ process.exit(code ?? 0);
294
+ });
295
+ let sigintReceived = false;
296
+ process.on('SIGINT', ()=>{
297
+ if (sigintReceived) {
298
+ // Second Ctrl+C — force kill child and exit immediately
299
+ if (!start.killed) start.kill('SIGKILL');
300
+ process.exit(1);
301
+ }
302
+ sigintReceived = true;
303
+ // Child process receives SIGINT from the process group directly.
304
+ // Wait for it to exit via the 'exit' handler above.
305
+ });
306
+ } catch (error) {
307
+ this.logger.error('Failed to start:', error instanceof Error ? error.message : String(error));
308
+ await wait(100);
309
+ process.exit(1);
310
+ }
311
+ }
312
+ /**
313
+ * Clears the console on all platforms.
314
+ */ clearConsole() {
315
+ process.stdout.write('\u001b[3J\u001b[2J\u001b[H');
316
+ }
317
+ constructor(){
318
+ this.appName = 'MeoCord';
319
+ this.logger = new Logger(this.appName);
320
+ this.projectRoot = process.cwd();
321
+ this.mainJSPath = path.join(this.projectRoot, 'dist', 'main.js');
322
+ this.webpackConfigPath = path.resolve(__dirname$1, '..', '..', '..', 'webpack.config.js');
323
+ this.generatorCLI = new GeneratorCLI(this.appName);
324
+ this.version = packageJson.version;
325
+ }
326
+ }
327
+ // Create an instance of the CLI and run it
328
+ const cli = new MeoCordCLI();
329
+ cli.run().catch(async (error)=>{
330
+ cli.logger.error('Failed to initialize CLI:', error?.message || error);
331
+ await wait(100);
332
+ process.exit(1);
333
+ });
@@ -0,0 +1,2 @@
1
+ export { Logger } from './logger.js';
2
+ export { Theme } from './theme.js';
@@ -0,0 +1,72 @@
1
+ import { inspect } from 'node:util';
2
+ import dayjs from 'dayjs';
3
+ import utc from 'dayjs/plugin/utc.js';
4
+ import timezone from 'dayjs/plugin/timezone.js';
5
+ import { loadMeoCordConfig } from '../util/meocord-config-loader.util.js';
6
+ import chalk from 'chalk';
7
+
8
+ dayjs.extend(utc);
9
+ dayjs.extend(timezone);
10
+ class Logger {
11
+ log(...args) {
12
+ this.logWithContext('log', args);
13
+ }
14
+ info(...args) {
15
+ this.logWithContext('log', args);
16
+ }
17
+ warn(...args) {
18
+ this.logWithContext('warn', args);
19
+ }
20
+ error(...args) {
21
+ this.logWithContext('error', args);
22
+ }
23
+ debug(...args) {
24
+ this.logWithContext('debug', args);
25
+ }
26
+ verbose(...args) {
27
+ this.logWithContext('log', args);
28
+ }
29
+ formatMessage(message, logType) {
30
+ if (typeof message === 'object' && message !== null) {
31
+ return inspect(message, {
32
+ showHidden: true,
33
+ depth: null,
34
+ colors: true,
35
+ compact: false,
36
+ showProxy: true
37
+ });
38
+ }
39
+ return (this.colorMap[logType] || ((msg)=>msg))(message);
40
+ }
41
+ logWithContext(logLevel, messages) {
42
+ if (messages.length === 0) return;
43
+ const config = loadMeoCordConfig();
44
+ const logType = logLevel.toUpperCase();
45
+ const applyColor = this.colorMap[logType] || ((msg)=>msg);
46
+ const formattedMessages = messages.map((message)=>this.formatMessage(message, logType));
47
+ const coloredAppName = config?.appName ? applyColor(chalk.bold(`[${config.appName}]`)) : undefined;
48
+ const timestamp = chalk.bold(dayjs().format('dddd, MMMM D, YYYY HH:mm:ss [UTC]Z'));
49
+ const coloredLogLevel = applyColor(chalk.bold(`[${logType}]`));
50
+ const coloredContext = this.context ? chalk.yellow.bold(`[${this.context}]`) : '';
51
+ const logTexts = [
52
+ coloredAppName,
53
+ timestamp,
54
+ coloredLogLevel,
55
+ coloredContext,
56
+ ...formattedMessages
57
+ ].filter((log)=>!!log);
58
+ console[logLevel](...logTexts);
59
+ }
60
+ constructor(context){
61
+ this.context = context;
62
+ this.colorMap = {
63
+ LOG: chalk.green,
64
+ INFO: chalk.cyan,
65
+ WARN: chalk.yellow,
66
+ ERROR: chalk.red,
67
+ DEBUG: chalk.magenta
68
+ };
69
+ }
70
+ }
71
+
72
+ export { Logger };
@@ -14,5 +14,11 @@
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
- */
18
- export { MeoCordFactory } from '../core/meocord-factory.js';
17
+ */ class Theme {
18
+ }
19
+ Theme.successColor = '#28A745';
20
+ Theme.infoColor = '#17A2B8';
21
+ Theme.errorColor = '#DC3545';
22
+ Theme.warningColor = '#FFC107';
23
+
24
+ export { Theme };
@@ -0,0 +1 @@
1
+ export { MeoCordFactory } from './meocord-factory.js';
@@ -0,0 +1,28 @@
1
+ import 'reflect-metadata';
2
+ import { Logger } from '../common/logger.js';
3
+ import '../common/theme.js';
4
+ import { MeoCordApp } from './meocord.app.js';
5
+ import { mainContainer } from '../decorator/container.js';
6
+ import 'inversify';
7
+ import 'discord.js';
8
+ import 'path';
9
+ import 'fs';
10
+ import 'jiti';
11
+
12
+ class MeoCordFactory {
13
+ static create(target) {
14
+ const container = Reflect.getMetadata('inversify:container', target);
15
+ if (!container) {
16
+ if (typeof target === 'function') {
17
+ this.logger.error(`No container found for class: ${target.name}`);
18
+ } else {
19
+ this.logger.error('No container found for the provided target.');
20
+ }
21
+ throw new Error('No container found on the target class.');
22
+ }
23
+ return mainContainer.get(MeoCordApp);
24
+ }
25
+ }
26
+ MeoCordFactory.logger = new Logger();
27
+
28
+ export { MeoCordFactory };