meocord 3.2.2 → 4.0.0-beta.1

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 (55) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +161 -29
  3. package/THIRD_PARTY_NOTICES.md +40 -0
  4. package/dist/cjs/_shared/{controller.decorator-eT0oHb8D.cjs → controller.decorator-9nIxOp9y.cjs} +1 -1
  5. package/dist/cjs/_shared/{metadata-key.enum-DITxfZlw.cjs → metadata-key.enum-aABGdodb.cjs} +0 -4
  6. package/dist/cjs/_shared/theme-Dqwlnz0m.cjs +124 -0
  7. package/dist/cjs/common/index.cjs +2 -6
  8. package/dist/cjs/core/index.cjs +69 -7
  9. package/dist/cjs/decorator/index.cjs +2 -2
  10. package/dist/cjs/enum/index.cjs +1 -1
  11. package/dist/cjs/testing/index.cjs +2 -6
  12. package/dist/esm/bin/app-template/meocord.config.ts.template +8 -13
  13. package/dist/esm/bin/app-template/package.json.template +12 -12
  14. package/dist/esm/bin/app-template/vitest.config.ts.template +6 -2
  15. package/dist/esm/bin/builder-template/builder/context-menu.builder.template +2 -2
  16. package/dist/esm/bin/builder-template/builder/primary-entry-point.builder.template +2 -2
  17. package/dist/esm/bin/builder-template/builder/slash.builder.template +2 -2
  18. package/dist/esm/bin/builder-template/controller/autocomplete.controller.template +4 -3
  19. package/dist/esm/bin/builder-template/controller/context-menu.controller.template +2 -2
  20. package/dist/esm/bin/builder-template/controller/primary-entry-point.controller.template +2 -2
  21. package/dist/esm/bin/builder-template/controller/slash.controller.template +2 -2
  22. package/dist/esm/bin/helper/controller-generator.helper.js +43 -26
  23. package/dist/esm/bin/helper/guard-generator.helper.js +8 -2
  24. package/dist/esm/bin/helper/service-generator.helper.js +8 -2
  25. package/dist/esm/bin/meocord.js +165 -142
  26. package/dist/esm/build/native-addons.js +274 -0
  27. package/dist/esm/build/rsbuild-config.js +176 -0
  28. package/dist/esm/common/decorator.js +0 -4
  29. package/dist/esm/common/theme.js +1 -5
  30. package/dist/esm/core/meocord-factory.js +5 -1
  31. package/dist/esm/enum/controller.enum.js +1 -5
  32. package/dist/esm/enum/metadata-key.enum.js +0 -4
  33. package/dist/esm/package.json.js +1 -1
  34. package/dist/esm/testing/mock-fn.js +1 -5
  35. package/dist/esm/util/common.util.js +3 -3
  36. package/dist/esm/util/generator-cli.util.js +54 -10
  37. package/dist/esm/util/json.util.js +0 -4
  38. package/dist/esm/util/meocord-config-loader.util.js +19 -51
  39. package/dist/esm/util/meocord-source-config.util.js +55 -0
  40. package/dist/esm/util/platform.util.js +66 -0
  41. package/dist/esm/util/runtime.util.js +20 -7
  42. package/dist/esm/util/tsconfig.util.js +1 -1
  43. package/dist/esm/util/wait.util.js +1 -5
  44. package/dist/types/common/index.d.ts +0 -16
  45. package/dist/types/core/index.d.ts +0 -12
  46. package/dist/types/decorator/index.d.ts +1 -31
  47. package/dist/types/enum/index.d.ts +0 -5
  48. package/dist/types/interface/index.d.ts +46 -57
  49. package/dist/types/testing/index.d.ts +4 -19
  50. package/meocord.eslint.cjs +0 -6
  51. package/meocord.eslint.d.ts +0 -6
  52. package/meocord.eslint.mjs +0 -6
  53. package/package.json +20 -24
  54. package/dist/cjs/_shared/theme-EmG1ZEwV.cjs +0 -179
  55. package/webpack.config.js +0 -147
@@ -1,73 +1,41 @@
1
1
  import path from 'path';
2
- import { existsSync, readFileSync } from 'fs';
3
- import { createJiti } from 'jiti';
4
- import { fixJSON } from './json.util.js';
2
+ import { existsSync } from 'fs';
3
+ import { createRequire } from 'module';
5
4
 
6
5
  let cachedConfig;
7
6
  let configLoaded = false;
8
7
  /**
9
- * Loads the MeoCord configuration, checking compiled output first then falling back to source.
8
+ * Loads the configuration a built application runs with: `dist/meocord.config.mjs`, which
9
+ * `meocord build` compiles from `meocord.config.ts`.
10
10
  *
11
- * Resolution order:
12
- * 1. `dist/meocord.config.mjs` — pre-compiled by `meocord build`, no tsconfig or source files needed
13
- * 2. `meocord.config.ts` — loaded via jiti with tsconfig path aliases (dev mode)
11
+ * Reads only the compiled file, which is plain JavaScript and needs no transpiler, tsconfig or
12
+ * source. Reading `meocord.config.ts` is {@link loadMeoCordSourceConfig}'s job, and it lives in its
13
+ * own module because it needs jiti: this one is imported by the logger and the factory, so a
14
+ * bot built with `bundleDependencies` bundles whatever it imports.
14
15
  *
15
- * The result is cached after the first successful load.
16
+ * The result is cached after the first load.
16
17
  *
17
- * @returns {MeoCordConfig | undefined} The loaded configuration object, or undefined if loading fails.
18
+ * @returns The configuration, or undefined when there is no compiled config or it fails to load.
18
19
  */ function loadMeoCordConfig() {
19
20
  if (configLoaded) return cachedConfig;
20
21
  configLoaded = true;
21
- cachedConfig = loadCompiledConfig() ?? loadSourceConfig();
22
+ cachedConfig = loadCompiledConfig();
22
23
  return cachedConfig;
23
24
  }
24
25
  /**
25
- * Loads the pre-compiled config from dist/meocord.config.mjs.
26
- * This file is generated by `meocord build` and requires no tsconfig or source files.
26
+ * `require` of an ES module, which Node supports cleanly from 22.13 and bun always has.
27
+ * Synchronous, like the logger and the factory that call it.
27
28
  */ function loadCompiledConfig() {
28
29
  const compiledPath = path.resolve(process.cwd(), 'dist', 'meocord.config.mjs');
29
30
  if (!existsSync(compiledPath)) return undefined;
30
31
  try {
31
- const jiti = createJiti(import.meta.url, {
32
- interopDefault: true
33
- });
34
- return jiti(compiledPath);
35
- } catch {
36
- // Fall through to source config
37
- return undefined;
38
- }
39
- }
40
- /**
41
- * Loads the source config from meocord.config.ts via jiti with tsconfig path alias resolution.
42
- * Used in development mode where source files and tsconfig.json are available.
43
- */ function loadSourceConfig() {
44
- const configPath = path.resolve(process.cwd(), 'meocord.config.ts');
45
- if (!existsSync(configPath)) return undefined;
46
- try {
47
- const tsConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
48
- const aliases = {};
49
- if (existsSync(tsConfigPath)) {
50
- const tsConfig = JSON.parse(fixJSON(readFileSync(tsConfigPath, 'utf-8')));
51
- const paths = tsConfig?.compilerOptions?.paths;
52
- if (paths) {
53
- for (const [key, values] of Object.entries(paths)){
54
- const aliasKey = key.replace('/*', '');
55
- aliases[aliasKey] = path.resolve(process.cwd(), values[0].replace('/*', ''));
56
- }
57
- }
58
- }
59
- const jiti = createJiti(import.meta.url, {
60
- interopDefault: true,
61
- alias: aliases,
62
- moduleCache: false
63
- });
64
- return jiti(configPath);
32
+ // Called through a variable so a bundler does not try to resolve the path while building the
33
+ // application; the file is only there once the build is done.
34
+ const load = createRequire(import.meta.url);
35
+ const loaded = load(compiledPath);
36
+ return loaded.default ?? loaded;
65
37
  } catch (error) {
66
- if (error instanceof Error) {
67
- console.error(`[MeoCord] Failed to load config: ${error.message}`);
68
- } else {
69
- console.error(`[MeoCord] Failed to load config: Unknown error`);
70
- }
38
+ console.error(`[MeoCord] Failed to load dist/meocord.config.mjs: ${error instanceof Error ? error.message : error}`);
71
39
  return undefined;
72
40
  }
73
41
  }
@@ -0,0 +1,55 @@
1
+ import path from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { createJiti } from 'jiti';
4
+ import { fixJSON } from './json.util.js';
5
+ import { loadMeoCordConfig } from './meocord-config-loader.util.js';
6
+
7
+ /**
8
+ * Loads meocord.config.ts from source, every time, for configuring a build.
9
+ *
10
+ * {@link loadMeoCordConfig} reads the compiled `dist/meocord.config.mjs` and caches the result,
11
+ * which is right at runtime -- production has no source -- and wrong while building. The compiled
12
+ * file is the previous build's output, so a build that read it would run on the config as it was
13
+ * last time, and the watcher's reload on a config change would reload nothing. Build time always
14
+ * has the source, so it reads the source.
15
+ *
16
+ * Only the CLI imports this module. It needs jiti to run TypeScript, and a bot has no use for jiti.
17
+ */ function loadMeoCordSourceConfig() {
18
+ const configPath = path.resolve(process.cwd(), 'meocord.config.ts');
19
+ if (!existsSync(configPath)) return undefined;
20
+ try {
21
+ const tsConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
22
+ const aliases = {};
23
+ if (existsSync(tsConfigPath)) {
24
+ const tsConfig = JSON.parse(fixJSON(readFileSync(tsConfigPath, 'utf-8')));
25
+ const paths = tsConfig?.compilerOptions?.paths;
26
+ if (paths) {
27
+ for (const [key, values] of Object.entries(paths)){
28
+ const aliasKey = key.replace('/*', '');
29
+ aliases[aliasKey] = path.resolve(process.cwd(), values[0].replace('/*', ''));
30
+ }
31
+ }
32
+ }
33
+ const jiti = createJiti(import.meta.url, {
34
+ interopDefault: true,
35
+ alias: aliases,
36
+ moduleCache: false
37
+ });
38
+ return jiti(configPath);
39
+ } catch (error) {
40
+ if (error instanceof Error) {
41
+ console.error(`[MeoCord] Failed to load config: ${error.message}`);
42
+ } else {
43
+ console.error(`[MeoCord] Failed to load config: Unknown error`);
44
+ }
45
+ return undefined;
46
+ }
47
+ }
48
+ /**
49
+ * The configuration as the CLI sees it: the compiled config when a build has produced one, and the
50
+ * source otherwise -- `meocord start` checks the token before anything has been built.
51
+ */ function loadMeoCordCliConfig() {
52
+ return loadMeoCordConfig() ?? loadMeoCordSourceConfig();
53
+ }
54
+
55
+ export { loadMeoCordCliConfig, loadMeoCordSourceConfig };
@@ -0,0 +1,66 @@
1
+ import { writeFileSync, existsSync, readFileSync } from 'fs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * File written beside a bundle that carries native addons, naming the platform it was built for.
6
+ */ const PLATFORM_MANIFEST = 'meocord.platform.json';
7
+ /** The C library this process runs against, when the runtime can say. */ function detectLibc() {
8
+ if (process.platform !== 'linux') return undefined;
9
+ try {
10
+ const report = process.report?.getReport?.();
11
+ if (!report?.header) return undefined;
12
+ return report.header.glibcVersionRuntime ? 'glibc' : 'musl';
13
+ } catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ /** The platform this process is running on. */ function currentPlatform() {
18
+ const libc = detectLibc();
19
+ return {
20
+ platform: process.platform,
21
+ arch: process.arch,
22
+ ...libc && {
23
+ libc
24
+ }
25
+ };
26
+ }
27
+ /** `linux-x64 (glibc)`, `darwin-arm64`. */ function describePlatform({ platform, arch, libc }) {
28
+ return `${platform}-${arch}${libc ? ` (${libc})` : ''}`;
29
+ }
30
+ /**
31
+ * Whether native binaries built for one platform can load on another.
32
+ *
33
+ * The C library is compared only when both sides are known, so a runtime that cannot report it
34
+ * is not refused on a guess.
35
+ */ function isSamePlatform(built, running) {
36
+ if (built.platform !== running.platform || built.arch !== running.arch) return false;
37
+ return !built.libc || !running.libc || built.libc === running.libc;
38
+ }
39
+ /** Records the platform a bundle's native addons were built for. */ function writePlatformManifest(distDir) {
40
+ writeFileSync(path.join(distDir, PLATFORM_MANIFEST), `${JSON.stringify(currentPlatform(), null, 2)}\n`);
41
+ }
42
+ /**
43
+ * Stops a bundle from starting on a platform its native addons were not built for.
44
+ *
45
+ * A binary for the wrong platform does not fail at startup. It fails when something first loads
46
+ * it -- for an image library, the first command that renders one -- with a dynamic linker error
47
+ * that names a file rather than the cause. Checking the manifest up front turns that into one
48
+ * clear message before the bot goes online.
49
+ *
50
+ * @param distDir - Directory holding the manifest. Defaults to the directory of the entry script.
51
+ */ function assertBuiltForThisPlatform(distDir = process.argv[1] ? path.dirname(process.argv[1]) : undefined) {
52
+ if (!distDir) return;
53
+ const manifest = path.join(distDir, PLATFORM_MANIFEST);
54
+ if (!existsSync(manifest)) return;
55
+ let built;
56
+ try {
57
+ built = JSON.parse(readFileSync(manifest, 'utf8'));
58
+ } catch {
59
+ return;
60
+ }
61
+ const running = currentPlatform();
62
+ if (isSamePlatform(built, running)) return;
63
+ throw new Error(`This build carries native addons compiled for ${describePlatform(built)}, but is running on ` + `${describePlatform(running)}. Compiled binaries only load on the platform they were built for. ` + 'Build on the same platform you deploy to -- for a container, run `meocord build` inside the image.');
64
+ }
65
+
66
+ export { PLATFORM_MANIFEST, assertBuiltForThisPlatform, currentPlatform, describePlatform, isSamePlatform, writePlatformManifest };
@@ -1,8 +1,4 @@
1
1
  /**
2
- * MeoCord Framework
3
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
4
- * SPDX-License-Identifier: MIT
5
- */ /**
6
2
  * Environment variable that pins the binary the application is spawned with.
7
3
  *
8
4
  * An escape hatch for pinning a specific install, or for running the application under a
@@ -61,12 +57,29 @@
61
57
  * @param runtime - Binary to run the application with.
62
58
  * @param mainJsPath - Absolute path to the built entry file.
63
59
  */ function buildAppCommand(runtime, mainJsPath) {
60
+ // With no node_modules directory in reach, bun installs a missing package from the registry
61
+ // the moment something imports it. A bot bundled with `bundleDependencies` is deployed exactly
62
+ // that way, so discord.js probing for its optional `zlib-sync` would download it in production
63
+ // instead of falling back. Nothing should reach the network at startup that the build did not
64
+ // put there.
65
+ const args = isBun(runtime) ? [
66
+ '--no-install',
67
+ mainJsPath
68
+ ] : [
69
+ mainJsPath
70
+ ];
64
71
  return {
65
72
  command: runtime,
66
- args: [
67
- mainJsPath
68
- ]
73
+ args
69
74
  };
70
75
  }
76
+ /**
77
+ * Whether a runtime binary is bun, by the name it was resolved to.
78
+ *
79
+ * Split on both separators rather than through path.basename, which only knows the separator
80
+ * of the platform it runs on.
81
+ */ function isBun(runtime) {
82
+ return /^bun(\.exe)?$/i.test(runtime.split(/[\\/]/).pop() ?? '');
83
+ }
71
84
 
72
85
  export { RUNTIME_OVERRIDE_ENV, buildAppCommand, resolveRuntime };
@@ -7,7 +7,7 @@ import { fixJSON } from './json.util.js';
7
7
 
8
8
  const logger = new Logger();
9
9
  /**
10
- * Prepares and modifies the project's `tsconfig.json` file for usage with tools like Webpack.
10
+ * Prepares and modifies the project's `tsconfig.json` file for the bundler.
11
11
  * - Verifies the existence of `tsconfig.json`.
12
12
  * - Fixes invalid JSON if necessary by correcting formatting issues like comments or trailing commas.
13
13
  * - Updates paths in `compilerOptions` and other sections to absolute paths.
@@ -1,8 +1,4 @@
1
- /**
2
- * MeoCord Framework
3
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
4
- * SPDX-License-Identifier: MIT
5
- */ function wait(ms) {
1
+ function wait(ms) {
6
2
  return new Promise((resolve)=>setTimeout(resolve, ms));
7
3
  }
8
4
 
@@ -1,10 +1,5 @@
1
1
  import { ColorResolvable } from 'discord.js';
2
2
 
3
- /**
4
- * MeoCord Framework
5
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
6
- * SPDX-License-Identifier: MIT
7
- */
8
3
  declare class Logger {
9
4
  private context?;
10
5
  private readonly colorMap;
@@ -19,12 +14,6 @@ declare class Logger {
19
14
  private logWithContext;
20
15
  }
21
16
 
22
- /**
23
- * MeoCord Framework
24
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
25
- * SPDX-License-Identifier: MIT
26
- */
27
-
28
17
  declare class Theme {
29
18
  static successColor: ColorResolvable;
30
19
  static infoColor: ColorResolvable;
@@ -32,11 +21,6 @@ declare class Theme {
32
21
  static warningColor: ColorResolvable;
33
22
  }
34
23
 
35
- /**
36
- * MeoCord Framework
37
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
38
- * SPDX-License-Identifier: MIT
39
- */
40
24
  /**
41
25
  * Composes multiple class or method decorators into a single decorator.
42
26
  *
@@ -1,12 +1,6 @@
1
1
  import { Container, ServiceIdentifier } from 'inversify';
2
2
  import { Client, ActivityOptions } from 'discord.js';
3
3
 
4
- /**
5
- * MeoCord Framework
6
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
7
- * SPDX-License-Identifier: MIT
8
- */
9
-
10
4
  declare class MeoCordApp {
11
5
  private readonly controllerClasses;
12
6
  private readonly container;
@@ -122,12 +116,6 @@ declare class MeoCordApp {
122
116
  private gracefulShutdown;
123
117
  }
124
118
 
125
- /**
126
- * MeoCord Framework
127
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
128
- * SPDX-License-Identifier: MIT
129
- */
130
-
131
119
  declare class MeoCordFactory {
132
120
  private static logger;
133
121
  static create(target: ServiceIdentifier): MeoCordApp;
@@ -2,13 +2,7 @@ import { BuildableCommandType, CommandBuilderBase, CommandBuilderConstructor, Co
2
2
  import { AutocompleteInteraction, OmitPartialGroupDMChannel, Message, MessageReaction, PartialMessageReaction, ClientOptions, ActivityOptions } from 'discord.js';
3
3
  import { CommandType } from '../enum/index.js';
4
4
  import { ServiceIdentifier } from 'inversify';
5
- import 'webpack';
6
-
7
- /**
8
- * MeoCord Framework
9
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
10
- * SPDX-License-Identifier: MIT
11
- */
5
+ import '@rsbuild/core';
12
6
 
13
7
  /**
14
8
  * `@Service()` decorator to mark a class as a service that can be injected into controllers or used as standalone services.
@@ -29,12 +23,6 @@ import 'webpack';
29
23
  */
30
24
  declare function Service<T>(): (target: new (...args: any[]) => T) => void;
31
25
 
32
- /**
33
- * MeoCord Framework
34
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
35
- * SPDX-License-Identifier: MIT
36
- */
37
-
38
26
  /**
39
27
  * This decorator is used to mark a class as a Discord command builder that later can be registered on the `@Command` decorator.
40
28
  * It defines the command type using metadata and dynamically makes the class injectable if it isn't already.
@@ -55,12 +43,6 @@ declare function Service<T>(): (target: new (...args: any[]) => T) => void;
55
43
  */
56
44
  declare function CommandBuilder<T extends BuildableCommandType>(commandType: T): (target: new () => CommandBuilderBase<T>) => void;
57
45
 
58
- /**
59
- * MeoCord Framework
60
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
61
- * SPDX-License-Identifier: MIT
62
- */
63
-
64
46
  /**
65
47
  * Decorator to register message handlers in the controller.
66
48
  *
@@ -229,12 +211,6 @@ declare function Controller(): (target: any) => void;
229
211
  */
230
212
  declare function findAmbiguousRoutes(patterns: string[]): [string, string][];
231
213
 
232
- /**
233
- * MeoCord Framework
234
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
235
- * SPDX-License-Identifier: MIT
236
- */
237
-
238
214
  /**
239
215
  * `@Guard()` decorator to mark a class as a Guard that later can be added on `@UseGuard` decorator.
240
216
  *
@@ -317,12 +293,6 @@ interface GuardWithParams {
317
293
  */
318
294
  declare function UseGuard(...guards: ((new (...args: any[]) => GuardInterface) | GuardWithParams)[]): any;
319
295
 
320
- /**
321
- * MeoCord Framework
322
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
323
- * SPDX-License-Identifier: MIT
324
- */
325
-
326
296
  /**
327
297
  * `@MeoCord()` decorator for declaring the MeoCord application class.
328
298
  *
@@ -1,10 +1,5 @@
1
1
  export { C as CommandType, R as ReactionHandlerAction } from '../controller.enum-DYfhYaat.js';
2
2
 
3
- /**
4
- * MeoCord Framework
5
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
6
- * SPDX-License-Identifier: MIT
7
- */
8
3
  /**
9
4
  * Centralised metadata keys used across the framework's `Reflect` calls.
10
5
  *
@@ -1,13 +1,8 @@
1
- import { SlashCommandBuilder, SlashCommandSubcommandsOnlyBuilder, ContextMenuCommandBuilder, RESTPostAPIPrimaryEntryPointApplicationCommandJSONBody, ChatInputCommandInteraction, UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, PrimaryEntryPointCommandInteraction, ButtonInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, RoleSelectMenuInteraction, MentionableSelectMenuInteraction, ChannelSelectMenuInteraction, ModalSubmitInteraction, User, PartialUser, BaseInteraction, Message, MessageReaction } from 'discord.js';
2
- import { Configuration } from 'webpack';
1
+ import { SlashCommandBuilder, SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandsOnlyBuilder, ContextMenuCommandBuilder, RESTPostAPIPrimaryEntryPointApplicationCommandJSONBody, ChatInputCommandInteraction, UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, PrimaryEntryPointCommandInteraction, ButtonInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, RoleSelectMenuInteraction, MentionableSelectMenuInteraction, ChannelSelectMenuInteraction, ModalSubmitInteraction, User, PartialUser, BaseInteraction, Message, MessageReaction } from 'discord.js';
2
+ import { RsbuildConfig } from '@rsbuild/core';
3
+ export { RsbuildConfig } from '@rsbuild/core';
3
4
  import { CommandType, ReactionHandlerAction } from '../enum/index.js';
4
5
 
5
- /**
6
- * MeoCord Framework
7
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
8
- * SPDX-License-Identifier: MIT
9
- */
10
-
11
6
  /**
12
7
  * The command types that are registered with Discord, and so need a builder.
13
8
  *
@@ -28,11 +23,16 @@ type PrimaryEntryPointCommandData = RESTPostAPIPrimaryEntryPointApplicationComma
28
23
  /**
29
24
  * The payload `build()` returns for a given command type.
30
25
  *
26
+ * A slash command's builder changes type as it is chained: adding an option narrows
27
+ * `SlashCommandBuilder` to `SlashCommandOptionsOnlyBuilder`, adding a subcommand to
28
+ * `SlashCommandSubcommandsOnlyBuilder`. All three are accepted; the options form is the most
29
+ * common builder there is, one command with an option.
30
+ *
31
31
  * `PRIMARY_ENTRY_POINT` yields a raw REST body rather than a builder because
32
32
  * `@discordjs/builders` ships none for it; `ApplicationCommandManager#set` accepts the
33
33
  * JSON body directly, so nothing is lost.
34
34
  */
35
- type CommandBuildResult<T extends BuildableCommandType> = T extends CommandType.SLASH ? SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder : T extends CommandType.CONTEXT_MENU ? ContextMenuCommandBuilder : T extends CommandType.PRIMARY_ENTRY_POINT ? PrimaryEntryPointCommandData : never;
35
+ type CommandBuildResult<T extends BuildableCommandType> = T extends CommandType.SLASH ? SlashCommandBuilder | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandsOnlyBuilder : T extends CommandType.CONTEXT_MENU ? ContextMenuCommandBuilder : T extends CommandType.PRIMARY_ENTRY_POINT ? PrimaryEntryPointCommandData : never;
36
36
  /**
37
37
  * Base interface for a command builder.
38
38
  */
@@ -88,12 +88,6 @@ interface ComponentInteractionMap {
88
88
  }
89
89
  type CommandInteractionType<CBC extends BuildableCommandType, T extends CommandBuilderConstructor<CBC> | CommandType> = T extends CommandBuilderConstructor<CommandType.SLASH> ? ChatInputCommandInteraction : T extends CommandBuilderConstructor<CommandType.CONTEXT_MENU> ? UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction : T extends CommandBuilderConstructor<CommandType.PRIMARY_ENTRY_POINT> ? PrimaryEntryPointCommandInteraction : T extends keyof ComponentInteractionMap ? ComponentInteractionMap[T] : never;
90
90
 
91
- /**
92
- * MeoCord Framework
93
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
94
- * SPDX-License-Identifier: MIT
95
- */
96
-
97
91
  /**
98
92
  * Interface for Guard classes.
99
93
  * Guards are used to handle permission checks before executing a method.
@@ -119,45 +113,10 @@ interface ReactionHandlerOptions {
119
113
  /** The action performed on the reaction, such as adding or removing it. */
120
114
  action: ReactionHandlerAction;
121
115
  }
122
- /**
123
- * Interface representing the Webpack configuration for the MeoCord framework.
124
- * This interface extends the base Webpack Configuration and provides stricter type definitions
125
- * with additional required properties to ensure a complete and valid Webpack setup.
126
- */
127
- interface MeoCordWebpackConfig extends Omit<Configuration, 'externals'> {
128
- /** Defines the mode of the Webpack build process (e.g., 'development' or 'production'). */
129
- mode: NonNullable<Configuration['mode']>;
130
- /** The entry point file path(s) for the application. Represents the starting point(s) of the build. */
131
- entry: string;
132
- /** Configuration for build optimization settings, such as code splitting and minimization. */
133
- optimization: NonNullable<Configuration['optimization']>;
134
- /**
135
- * Specifies external dependencies to exclude from the output bundle.
136
- * Can be used to exclude libraries from being bundled, like `node_modules`.
137
- */
138
- externals: Extract<NonNullable<Configuration['externals']>, any[]>;
139
- /**
140
- * Rules and configurations for handling module files during the build process.
141
- * Includes loaders for processing various file types.
142
- */
143
- module: NonNullable<Configuration['module']>;
144
- /**
145
- * Configuration for module resolution, including resolving extensions and alias paths.
146
- * Determines how imported files are resolved.
147
- */
148
- resolve: NonNullable<Configuration['resolve']>;
149
- /**
150
- * Specifies output settings for the Webpack build, excluding path, publicPath, and filename.
151
- * Defines properties like asset management and global settings.
152
- */
153
- output: Omit<NonNullable<Configuration['output']>, 'path' | 'publicPath' | 'filename'>;
154
- /** Configures the stats object to control the output of build process logs. */
155
- stats: NonNullable<Configuration['stats']>;
156
- }
157
116
  /**
158
117
  * Configuration interface for the MeoCord application.
159
118
  * This interface defines optional configurations for the application, including
160
- * metadata, authentication tokens, and Webpack configuration overrides.
119
+ * metadata, authentication tokens, and bundler configuration overrides.
161
120
  */
162
121
  interface MeoCordConfig {
163
122
  /**
@@ -170,12 +129,42 @@ interface MeoCordConfig {
170
129
  */
171
130
  discordToken: string;
172
131
  /**
173
- * Function to customize the Webpack configuration.
174
- * Allows overriding and extending the default Webpack setup for the application.
175
- * @param config - A callback function to modify the existing Webpack configuration.
176
- * @returns A modified Webpack configuration or `undefined` if no customization is needed.
132
+ * Put everything the bot needs inside `dist`, so it runs without `node_modules`.
133
+ *
134
+ * Off by default, matching how the build has always behaved: dependencies stay runtime imports,
135
+ * so `dist` needs `node_modules` beside it. Turn it on to deploy `dist` alone.
136
+ *
137
+ * Plain JavaScript is bundled into `main.js`. Native addons -- packages shipping a compiled
138
+ * `.node` binary, like `sharp` -- are found while building, kept out of the bundle, and copied
139
+ * with their platform binary into `dist/node_modules`. Such a build only runs on the platform it
140
+ * was built on; it records that platform, and refuses to start anywhere else.
141
+ */
142
+ bundleDependencies?: boolean;
143
+ /**
144
+ * Modules to keep out of the bundle.
145
+ *
146
+ * Native addons need not be listed; they are found and packed on their own. Anything listed here
147
+ * as a package name is also copied into `dist/node_modules` when {@link bundleDependencies} is on.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * // Loaded by the runtime rather than bundled, e.g. for instrumentation.
152
+ * externals: ['@opentelemetry/api']
153
+ * ```
154
+ */
155
+ externals?: (string | RegExp)[];
156
+ /**
157
+ * Function to customize the Rsbuild configuration.
158
+ * Allows overriding and extending the default bundler setup for the application.
159
+ *
160
+ * Rsbuild handles images, fonts, svg and media itself, so they need no rules;
161
+ * `output.distPath` controls where they land. Raw bundler rules go through `tools.rspack`,
162
+ * which takes a webpack-shaped config.
163
+ *
164
+ * @param config - The configuration to modify.
165
+ * @returns A modified configuration, or `undefined` to keep the default.
177
166
  */
178
- webpack?: (config: MeoCordWebpackConfig) => MeoCordWebpackConfig | undefined;
167
+ rsbuild?: (config: RsbuildConfig) => RsbuildConfig | undefined;
179
168
  }
180
169
 
181
- export type { AutocompleteMetadata, BuildableCommandType, CommandBuildResult, CommandBuilderBase, CommandBuilderConstructor, CommandInteractionType, CommandMetadata, GuardInterface, MeoCordConfig, MeoCordWebpackConfig, ReactionHandlerOptions };
170
+ export type { AutocompleteMetadata, BuildableCommandType, CommandBuildResult, CommandBuilderBase, CommandBuilderConstructor, CommandInteractionType, CommandMetadata, GuardInterface, MeoCordConfig, ReactionHandlerOptions };
@@ -1,15 +1,9 @@
1
1
  import { ServiceIdentifier, Container } from 'inversify';
2
2
  import { GuardInterface } from '../interface/index.js';
3
3
  import { CacheType, CommandInteractionOptionResolver, Channel, Client, Guild, Message, User } from 'discord.js';
4
- import 'webpack';
4
+ import '@rsbuild/core';
5
5
  import '../controller.enum-DYfhYaat.js';
6
6
 
7
- /**
8
- * MeoCord Framework
9
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
10
- * SPDX-License-Identifier: MIT
11
- */
12
-
13
7
  interface ValueProvider<T = any> {
14
8
  provide: ServiceIdentifier<T>;
15
9
  useValue: T;
@@ -76,11 +70,6 @@ declare class MeoCordTestingModule {
76
70
  static create(options: TestingModuleOptions): TestingModuleBuilder;
77
71
  }
78
72
 
79
- /**
80
- * MeoCord Framework
81
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
82
- * SPDX-License-Identifier: MIT
83
- */
84
73
  interface MockResult<T = unknown> {
85
74
  type: 'return' | 'throw';
86
75
  value: T;
@@ -140,12 +129,6 @@ declare function isMockFunction(fn: unknown): fn is MockInstance;
140
129
  */
141
130
  declare function createMockFn<T extends (...args: any[]) => any = (...args: any[]) => any>(impl?: T): MockedFunction<T>;
142
131
 
143
- /**
144
- * MeoCord Framework
145
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
146
- * SPDX-License-Identifier: MIT
147
- */
148
-
149
132
  /**
150
133
  * Recursively transforms all methods of T into MockedFunction and all
151
134
  * nested objects into DeepMocked. Depth cap at 5 prevents infinite recursion
@@ -273,7 +256,9 @@ declare function createMockGuild(): DeepMocked<Guild>;
273
256
  * - `ThreadChannel`: `messages`, `members`
274
257
  */
275
258
  declare function createMockChannel<T extends Channel>(Class: InteractionClass<T>): DeepMocked<T>;
276
- declare function createMockMessage(): DeepMocked<Message>;
259
+ declare function createMockMessage(): DeepMocked<Message> & {
260
+ deleted: boolean;
261
+ };
277
262
  interface ChatInputOptions {
278
263
  subcommandGroup?: string | null;
279
264
  subcommand?: string | null;
@@ -1,9 +1,3 @@
1
- /**
2
- * MeoCord Framework
3
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
4
- * SPDX-License-Identifier: MIT
5
- */
6
-
7
1
  const { importX } = require('eslint-plugin-import-x')
8
2
  const globals = require('globals')
9
3
  const tsParser = require('@typescript-eslint/parser')
@@ -1,9 +1,3 @@
1
- /**
2
- * MeoCord Framework
3
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
4
- * SPDX-License-Identifier: MIT
5
- */
6
-
7
1
  import type { Linter } from 'eslint'
8
2
 
9
3
  /**
@@ -1,9 +1,3 @@
1
- /**
2
- * MeoCord Framework
3
- * Copyright (c) 2025-present Ukasyah Rahmatullah Zada
4
- * SPDX-License-Identifier: MIT
5
- */
6
-
7
1
  import { importX } from 'eslint-plugin-import-x'
8
2
  import globals from 'globals'
9
3
  import tsParser from '@typescript-eslint/parser'