meocord 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHOR.md +2 -3
- package/README.md +361 -55
- package/dist/cjs/_shared/controller.decorator-MUHA_A3z.cjs +529 -0
- package/dist/cjs/core/index.cjs +246 -86
- package/dist/cjs/decorator/index.cjs +4 -2
- package/dist/cjs/enum/index.cjs +17 -4
- package/dist/cjs/testing/index.cjs +88 -4
- package/dist/esm/bin/app-template/README.md.template +61 -0
- package/dist/esm/bin/app-template/_env.example.template +2 -0
- package/dist/esm/bin/app-template/_gitignore.template +22 -0
- package/dist/esm/bin/app-template/_prettierrc.mjs.template +10 -0
- package/dist/esm/bin/app-template/eslint.config.ts.template +25 -0
- package/dist/esm/bin/app-template/meocord.config.ts.template +25 -0
- package/dist/esm/bin/app-template/package.json.template +38 -0
- package/dist/esm/bin/app-template/src/app.ts.template +44 -0
- package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.ts.template +19 -0
- package/dist/esm/bin/app-template/src/controllers/context-menu/builders/sample.builder.ts.template +10 -0
- package/dist/esm/bin/app-template/src/controllers/context-menu/sample.context-menu.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/context-menu/sample.context-menu.controller.ts.template +13 -0
- package/dist/esm/bin/app-template/src/controllers/message/sample.message.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/message/sample.message.controller.ts.template +28 -0
- package/dist/esm/bin/app-template/src/controllers/modal-submit/sample.modal-submit.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/modal-submit/sample.modal-submit.controller.ts.template +13 -0
- package/dist/esm/bin/app-template/src/controllers/reaction/sample.reaction.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/reaction/sample.reaction.controller.ts.template +29 -0
- package/dist/esm/bin/app-template/src/controllers/select-menu/sample.select-menu.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/select-menu/sample.select-menu.controller.ts.template +11 -0
- package/dist/esm/bin/app-template/src/controllers/slash/builders/sample.builder.ts.template +10 -0
- package/dist/esm/bin/app-template/src/controllers/slash/sample.slash.controller.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/controllers/slash/sample.slash.controller.ts.template +19 -0
- package/dist/esm/bin/app-template/src/guards/rate-limit.guard.spec.ts.template +13 -0
- package/dist/esm/bin/app-template/src/guards/rate-limit.guard.ts.template +52 -0
- package/dist/esm/bin/app-template/src/main.ts.template +14 -0
- package/dist/esm/bin/app-template/src/services/sample.service.spec.ts.template +17 -0
- package/dist/esm/bin/app-template/src/services/sample.service.ts.template +9 -0
- package/dist/esm/bin/app-template/tsconfig.eslint.json.template +5 -0
- package/dist/esm/bin/app-template/tsconfig.json.template +30 -0
- package/dist/esm/bin/app-template/tsconfig.test.json.template +8 -0
- package/dist/esm/bin/app-template/vitest.config.ts.template +35 -0
- package/dist/esm/bin/builder-template/builder/primary-entry-point.builder.template +26 -0
- package/dist/esm/bin/builder-template/controller/autocomplete.controller.template +16 -0
- package/dist/esm/bin/builder-template/controller/button.controller.template +1 -1
- package/dist/esm/bin/builder-template/controller/channel-select-menu.controller.template +12 -0
- package/dist/esm/bin/builder-template/controller/context-menu.controller.template +2 -2
- package/dist/esm/bin/builder-template/controller/mentionable-select-menu.controller.template +12 -0
- package/dist/esm/bin/builder-template/controller/modal-submit.controller.template +1 -1
- package/dist/esm/bin/builder-template/controller/primary-entry-point.controller.template +12 -0
- package/dist/esm/bin/builder-template/controller/role-select-menu.controller.template +12 -0
- package/dist/esm/bin/builder-template/controller/slash.controller.template +1 -1
- package/dist/esm/bin/builder-template/controller/user-select-menu.controller.template +12 -0
- package/dist/esm/bin/generator.js +4 -9
- package/dist/esm/bin/helper/app-generator.helper.js +78 -0
- package/dist/esm/bin/helper/controller-generator.helper.js +24 -7
- package/dist/esm/bin/meocord.js +156 -75
- package/dist/esm/core/meocord.app.js +247 -86
- package/dist/esm/decorator/controller.decorator.js +73 -10
- package/dist/esm/decorator/guard.decorator.js +1 -1
- package/dist/esm/decorator/index.js +1 -1
- package/dist/esm/enum/controller.enum.js +23 -4
- package/dist/esm/testing/mock-interaction.js +89 -5
- package/dist/esm/util/common.util.js +11 -3
- package/dist/esm/util/generator-cli.util.js +21 -4
- package/dist/esm/util/interaction.util.js +174 -0
- package/dist/esm/util/package-manager.util.js +9 -2
- package/dist/esm/util/package-version.util.js +32 -0
- package/dist/esm/util/runtime.util.js +72 -0
- package/dist/types/controller.enum-DYfhYaat.d.ts +36 -0
- package/dist/types/core/index.d.ts +75 -2
- package/dist/types/decorator/index.d.ts +61 -49
- package/dist/types/enum/index.d.ts +1 -1
- package/dist/types/interface/index.d.ts +89 -3
- package/dist/types/testing/index.d.ts +3 -21
- package/package.json +11 -12
- package/dist/cjs/_shared/controller.decorator-CC6BjHkS.cjs +0 -288
- package/dist/types/controller.enum-QA-IuReF.d.ts +0 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { BuildableCommandType, CommandBuilderBase, CommandBuilderConstructor, CommandInteractionType, ReactionHandlerOptions, AutocompleteMetadata, CommandMetadata, GuardInterface } from '../interface/index.js';
|
|
2
|
+
import { AutocompleteInteraction, OmitPartialGroupDMChannel, Message, MessageReaction, PartialMessageReaction, ClientOptions, ActivityOptions } from 'discord.js';
|
|
1
3
|
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
4
|
import { ServiceIdentifier } from 'inversify';
|
|
5
5
|
import 'webpack';
|
|
6
6
|
|
|
@@ -29,44 +29,6 @@ import 'webpack';
|
|
|
29
29
|
*/
|
|
30
30
|
declare function Service<T>(): (target: new (...args: any[]) => T) => void;
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* MeoCord Framework
|
|
34
|
-
* Copyright (c) 2025 Ukasyah Rahmatullah Zada
|
|
35
|
-
* SPDX-License-Identifier: MIT
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Base interface for a command builder.
|
|
40
|
-
*/
|
|
41
|
-
interface CommandBuilderBase<T extends CommandType.SLASH | CommandType.CONTEXT_MENU = CommandType.SLASH | CommandType.CONTEXT_MENU> {
|
|
42
|
-
/**
|
|
43
|
-
* Builds the command structure using the specified command name.
|
|
44
|
-
*
|
|
45
|
-
* @param commandName - The name of the command.
|
|
46
|
-
* @returns A SlashCommandBuilder or ContextMenuCommandBuilder instance.
|
|
47
|
-
*/
|
|
48
|
-
build: (commandName: string) => T extends CommandType.SLASH ? SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder : T extends CommandType.CONTEXT_MENU ? ContextMenuCommandBuilder : never;
|
|
49
|
-
}
|
|
50
|
-
type CommandBuilderConstructor<T extends CommandType.SLASH | CommandType.CONTEXT_MENU> = new () => CommandBuilderBase<T>;
|
|
51
|
-
/**
|
|
52
|
-
* Command metadata describing a registered command method.
|
|
53
|
-
*/
|
|
54
|
-
interface CommandMetadata<T extends string = string> {
|
|
55
|
-
methodName: string;
|
|
56
|
-
builder: ReturnType<CommandBuilderBase['build']> | undefined;
|
|
57
|
-
type: CommandType;
|
|
58
|
-
regex?: RegExp;
|
|
59
|
-
dynamicParams?: T[];
|
|
60
|
-
/**
|
|
61
|
-
* How specific this pattern is; higher wins when more than one route matches the
|
|
62
|
-
* same customId. A greedy parameter can overlap a more literal sibling —
|
|
63
|
-
* `gi-profile-{uuid:*}-{uid}` also matches an id meant for
|
|
64
|
-
* `gi-profile-summary-{ownerId}-{uid}` — so dispatch cannot rely on declaration order.
|
|
65
|
-
*/
|
|
66
|
-
specificity?: number;
|
|
67
|
-
}
|
|
68
|
-
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;
|
|
69
|
-
|
|
70
32
|
/**
|
|
71
33
|
* MeoCord Framework
|
|
72
34
|
* Copyright (c) 2025 Ukasyah Rahmatullah Zada
|
|
@@ -91,7 +53,7 @@ type CommandInteractionType<CBC extends CommandType.SLASH | CommandType.CONTEXT_
|
|
|
91
53
|
* @returns A decorator function that makes the target class injectable
|
|
92
54
|
* and assigns the `commandType` metadata.
|
|
93
55
|
*/
|
|
94
|
-
declare function CommandBuilder<T extends
|
|
56
|
+
declare function CommandBuilder<T extends BuildableCommandType>(commandType: T): (target: new () => CommandBuilderBase<T>) => void;
|
|
95
57
|
|
|
96
58
|
/**
|
|
97
59
|
* MeoCord Framework
|
|
@@ -162,8 +124,13 @@ declare const PARAM_SEPARATOR = "/";
|
|
|
162
124
|
/**
|
|
163
125
|
* Decorator to register command methods in a controller.
|
|
164
126
|
*
|
|
165
|
-
* @param commandName -
|
|
166
|
-
*
|
|
127
|
+
* @param commandName - What the command is addressed by. Commands registered with
|
|
128
|
+
* Discord use their name, and a subcommand its full path — `settings notify email`,
|
|
129
|
+
* parts separated by a space, the way Discord displays it. Components use a customId
|
|
130
|
+
* pattern, where `{name}` captures one `/`-separated segment.
|
|
131
|
+
* @param builderOrType - A command builder class, or a `CommandType` for a handler that
|
|
132
|
+
* registers nothing of its own: every component, and every subcommand of a command
|
|
133
|
+
* whose builder already describes it.
|
|
167
134
|
*
|
|
168
135
|
* @example
|
|
169
136
|
* ```typescript
|
|
@@ -172,13 +139,23 @@ declare const PARAM_SEPARATOR = "/";
|
|
|
172
139
|
* await interaction.reply('This is the help command!')
|
|
173
140
|
* }
|
|
174
141
|
*
|
|
175
|
-
* @Command('
|
|
176
|
-
* public async
|
|
177
|
-
* await
|
|
142
|
+
* @Command('settings notify email', CommandType.SLASH)
|
|
143
|
+
* public async handleNotifyEmail(interaction: ChatInputCommandInteraction, { enabled }) {
|
|
144
|
+
* await interaction.reply(`Email notifications ${enabled ? 'on' : 'off'}`)
|
|
145
|
+
* }
|
|
146
|
+
*
|
|
147
|
+
* @Command('stats/{id}', CommandType.BUTTON)
|
|
148
|
+
* public async handleStats(interaction: ButtonInteraction, { id }) {
|
|
149
|
+
* await interaction.reply(`Fetching stats for ID: ${id}`);
|
|
150
|
+
* }
|
|
151
|
+
*
|
|
152
|
+
* @Command('assign/{taskId}', CommandType.USER_SELECT_MENU)
|
|
153
|
+
* public async handleAssign(interaction: UserSelectMenuInteraction, { taskId }) {
|
|
154
|
+
* await interaction.reply(`Assigned ${interaction.users.size} user(s) to ${taskId}`)
|
|
178
155
|
* }
|
|
179
156
|
* ```
|
|
180
157
|
*/
|
|
181
|
-
declare function Command<CBC extends
|
|
158
|
+
declare function Command<CBC extends BuildableCommandType, 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;
|
|
182
159
|
/**
|
|
183
160
|
* Retrieves the command map for a given controller.
|
|
184
161
|
*
|
|
@@ -186,6 +163,41 @@ declare function Command<CBC extends CommandType.SLASH | CommandType.CONTEXT_MEN
|
|
|
186
163
|
* @returns A record containing command metadata indexed by command names.
|
|
187
164
|
*/
|
|
188
165
|
declare function getCommandMap<T extends string>(controller: any): Record<string, CommandMetadata<T>[]>;
|
|
166
|
+
/**
|
|
167
|
+
* Decorator to register an autocomplete handler for a chat input command's option.
|
|
168
|
+
*
|
|
169
|
+
* Autocomplete is a separate interaction from the command it belongs to, and Discord
|
|
170
|
+
* sends it while the user is still typing. It is not a `@Command`: nothing is
|
|
171
|
+
* registered for it — the option's own `setAutocomplete(true)` is what turns it on —
|
|
172
|
+
* and it is answered with `interaction.respond()` rather than a reply. Leaving it
|
|
173
|
+
* unhandled is not silent to the user: the client shows a loading state until the
|
|
174
|
+
* three-second window closes.
|
|
175
|
+
*
|
|
176
|
+
* @param commandPath - The command to complete, e.g. `settings` or `settings notify email`
|
|
177
|
+
* for a subcommand. Parts are separated by a single space, as Discord displays them.
|
|
178
|
+
* @param optionName - The option to complete. Omit to handle every option of the command,
|
|
179
|
+
* branching on `interaction.options.getFocused(true)`.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* @Autocomplete('search', 'query')
|
|
184
|
+
* async completeQuery(interaction: AutocompleteInteraction) {
|
|
185
|
+
* const { value } = interaction.options.getFocused(true)
|
|
186
|
+
* await interaction.respond(this.search(value).map(name => ({ name, value: name })))
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
declare function Autocomplete<R extends void | Promise<void>>(commandPath: string, optionName?: string): <P extends Record<string, any>>(target: object, propertyKey: string, _descriptor: TypedPropertyDescriptor<(interaction: AutocompleteInteraction, params: P) => R> | TypedPropertyDescriptor<(interaction: AutocompleteInteraction) => R>) => void;
|
|
191
|
+
/**
|
|
192
|
+
* Retrieves autocomplete handler metadata from a given controller.
|
|
193
|
+
*
|
|
194
|
+
* Handlers naming an option come first, so a command-wide handler acts as the fallback
|
|
195
|
+
* for options no specific handler claimed rather than shadowing them by declaration order.
|
|
196
|
+
*
|
|
197
|
+
* @param controller - The controller class instance.
|
|
198
|
+
* @returns The registered autocomplete handlers, most specific first.
|
|
199
|
+
*/
|
|
200
|
+
declare function getAutocompleteHandlers(controller: any): AutocompleteMetadata[];
|
|
189
201
|
/**
|
|
190
202
|
* Decorator to mark a class as a controller that can later be registered to the App class `(app.ts)` using the `@MeoCord` decorator.
|
|
191
203
|
*
|
|
@@ -283,7 +295,7 @@ interface GuardWithParams {
|
|
|
283
295
|
* @example
|
|
284
296
|
* ```typescript
|
|
285
297
|
* // Method-level usage
|
|
286
|
-
* @Command('profile
|
|
298
|
+
* @Command('profile/{id}', CommandType.BUTTON)
|
|
287
299
|
* @UseGuard(
|
|
288
300
|
* { provide: RateLimiterGuard, params: { limit: 2, window: 3000 } },
|
|
289
301
|
* ButtonInteractionGuard
|
|
@@ -355,4 +367,4 @@ declare function MeoCord(options: {
|
|
|
355
367
|
services?: ServiceIdentifier[];
|
|
356
368
|
}): (target: any) => void;
|
|
357
369
|
|
|
358
|
-
export { Command, CommandBuilder, Controller, Guard, MeoCord, MessageHandler, PARAM_SEPARATOR, ReactionHandler, Service, UseGuard, findAmbiguousRoutes, getCommandMap, getMessageHandlers, getReactionHandlers };
|
|
370
|
+
export { Autocomplete, Command, CommandBuilder, Controller, Guard, MeoCord, MessageHandler, PARAM_SEPARATOR, ReactionHandler, Service, UseGuard, findAmbiguousRoutes, getAutocompleteHandlers, getCommandMap, getMessageHandlers, getReactionHandlers };
|
|
@@ -1,6 +1,92 @@
|
|
|
1
|
-
import { User, PartialUser, BaseInteraction, Message, MessageReaction } from 'discord.js';
|
|
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
2
|
import { Configuration } from 'webpack';
|
|
3
|
-
import { ReactionHandlerAction } from '../enum/index.js';
|
|
3
|
+
import { CommandType, ReactionHandlerAction } from '../enum/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MeoCord Framework
|
|
7
|
+
* Copyright (c) 2025 Ukasyah Rahmatullah Zada
|
|
8
|
+
* SPDX-License-Identifier: MIT
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The command types that are registered with Discord, and so need a builder.
|
|
13
|
+
*
|
|
14
|
+
* Components are addressed by a customId the application makes up, so they have
|
|
15
|
+
* nothing to register; these three are published through `application.commands.set`.
|
|
16
|
+
*/
|
|
17
|
+
type BuildableCommandType = CommandType.SLASH | CommandType.CONTEXT_MENU | CommandType.PRIMARY_ENTRY_POINT;
|
|
18
|
+
/**
|
|
19
|
+
* The body an entry point command is registered with.
|
|
20
|
+
*
|
|
21
|
+
* `description` is added back on top of the discord-api-types body: that type omits it
|
|
22
|
+
* from every non-chat-input command, but the API accepts one for entry point commands
|
|
23
|
+
* — Discord's own default activity command ships with it set.
|
|
24
|
+
*/
|
|
25
|
+
type PrimaryEntryPointCommandData = RESTPostAPIPrimaryEntryPointApplicationCommandJSONBody & {
|
|
26
|
+
description?: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The payload `build()` returns for a given command type.
|
|
30
|
+
*
|
|
31
|
+
* `PRIMARY_ENTRY_POINT` yields a raw REST body rather than a builder because
|
|
32
|
+
* `@discordjs/builders` ships none for it; `ApplicationCommandManager#set` accepts the
|
|
33
|
+
* JSON body directly, so nothing is lost.
|
|
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;
|
|
36
|
+
/**
|
|
37
|
+
* Base interface for a command builder.
|
|
38
|
+
*/
|
|
39
|
+
interface CommandBuilderBase<T extends BuildableCommandType = BuildableCommandType> {
|
|
40
|
+
/**
|
|
41
|
+
* Builds the command structure using the specified command name.
|
|
42
|
+
*
|
|
43
|
+
* @param commandName - The name of the command.
|
|
44
|
+
* @returns A builder instance, or a raw command body for entry point commands.
|
|
45
|
+
*/
|
|
46
|
+
build: (commandName: string) => CommandBuildResult<T>;
|
|
47
|
+
}
|
|
48
|
+
type CommandBuilderConstructor<T extends BuildableCommandType> = new () => CommandBuilderBase<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Command metadata describing a registered command method.
|
|
51
|
+
*/
|
|
52
|
+
interface CommandMetadata<T extends string = string> {
|
|
53
|
+
methodName: string;
|
|
54
|
+
builder: ReturnType<CommandBuilderBase['build']> | undefined;
|
|
55
|
+
type: CommandType;
|
|
56
|
+
regex?: RegExp;
|
|
57
|
+
dynamicParams?: T[];
|
|
58
|
+
/**
|
|
59
|
+
* How specific this pattern is; higher wins when more than one route matches the
|
|
60
|
+
* same customId. A parameter takes whatever fills its segment, so a broad pattern can
|
|
61
|
+
* also match an id a more literal sibling owns — `gi-profile/{uuid}/{uid}` matches
|
|
62
|
+
* `gi-profile/summary/123/456` just as `gi-profile/summary/{ownerId}/{uid}` does — and
|
|
63
|
+
* ranking is what settles it, since declaration order would make the winner depend on
|
|
64
|
+
* file layout.
|
|
65
|
+
*/
|
|
66
|
+
specificity?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Metadata describing one `@Autocomplete` handler. */
|
|
69
|
+
interface AutocompleteMetadata {
|
|
70
|
+
/** The command path the handler serves, e.g. `settings` or `settings notify email`. */
|
|
71
|
+
commandPath: string;
|
|
72
|
+
/** The option it completes, or `undefined` to complete every option of that command. */
|
|
73
|
+
optionName?: string;
|
|
74
|
+
methodName: string;
|
|
75
|
+
}
|
|
76
|
+
/** The interaction class each non-buildable command type hands to its handler. */
|
|
77
|
+
interface ComponentInteractionMap {
|
|
78
|
+
[CommandType.BUTTON]: ButtonInteraction;
|
|
79
|
+
[CommandType.SELECT_MENU]: StringSelectMenuInteraction;
|
|
80
|
+
[CommandType.USER_SELECT_MENU]: UserSelectMenuInteraction;
|
|
81
|
+
[CommandType.ROLE_SELECT_MENU]: RoleSelectMenuInteraction;
|
|
82
|
+
[CommandType.MENTIONABLE_SELECT_MENU]: MentionableSelectMenuInteraction;
|
|
83
|
+
[CommandType.CHANNEL_SELECT_MENU]: ChannelSelectMenuInteraction;
|
|
84
|
+
[CommandType.MODAL_SUBMIT]: ModalSubmitInteraction;
|
|
85
|
+
[CommandType.SLASH]: ChatInputCommandInteraction;
|
|
86
|
+
[CommandType.CONTEXT_MENU]: UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction;
|
|
87
|
+
[CommandType.PRIMARY_ENTRY_POINT]: PrimaryEntryPointCommandInteraction;
|
|
88
|
+
}
|
|
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;
|
|
4
90
|
|
|
5
91
|
/**
|
|
6
92
|
* MeoCord Framework
|
|
@@ -92,4 +178,4 @@ interface MeoCordConfig {
|
|
|
92
178
|
webpack?: (config: MeoCordWebpackConfig) => MeoCordWebpackConfig | undefined;
|
|
93
179
|
}
|
|
94
180
|
|
|
95
|
-
export type { GuardInterface, MeoCordConfig, MeoCordWebpackConfig, ReactionHandlerOptions };
|
|
181
|
+
export type { AutocompleteMetadata, BuildableCommandType, CommandBuildResult, CommandBuilderBase, CommandBuilderConstructor, CommandInteractionType, CommandMetadata, GuardInterface, MeoCordConfig, MeoCordWebpackConfig, ReactionHandlerOptions };
|
|
@@ -2,7 +2,7 @@ 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
4
|
import 'webpack';
|
|
5
|
-
import '../controller.enum-
|
|
5
|
+
import '../controller.enum-DYfhYaat.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* MeoCord Framework
|
|
@@ -277,30 +277,12 @@ declare function createMockMessage(): DeepMocked<Message>;
|
|
|
277
277
|
interface ChatInputOptions {
|
|
278
278
|
subcommandGroup?: string | null;
|
|
279
279
|
subcommand?: string | null;
|
|
280
|
+
/** The option the user is currently typing, for autocomplete interactions. */
|
|
281
|
+
focused?: string | null;
|
|
280
282
|
[name: string]: string | number | boolean | {
|
|
281
283
|
id: string;
|
|
282
284
|
} | null | undefined;
|
|
283
285
|
}
|
|
284
|
-
/**
|
|
285
|
-
* Builds a typed options resolver from a plain record. Mirrors how the real
|
|
286
|
-
* `CommandInteractionOptionResolver` works: declare what options the command
|
|
287
|
-
* was invoked with, and the resolver finds them by name.
|
|
288
|
-
*
|
|
289
|
-
* All explicit methods are mock functions — override per test with `.mockReturnValue()`.
|
|
290
|
-
* Methods not listed (e.g. `getAttachment`) are auto-stubbed by the Proxy.
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```ts
|
|
294
|
-
* const interaction = createMockInteraction(ChatInputCommandInteraction)
|
|
295
|
-
* interaction.options = createChatInputOptions({
|
|
296
|
-
* subcommandGroup: 'daily',
|
|
297
|
-
* subcommand: 'notes',
|
|
298
|
-
* uid: 12345678,
|
|
299
|
-
* })
|
|
300
|
-
* interaction.options.getSubcommand() // → 'notes'
|
|
301
|
-
* interaction.options.getNumber('uid') // → 12345678
|
|
302
|
-
* ```
|
|
303
|
-
*/
|
|
304
286
|
declare function createChatInputOptions<Cached extends CacheType = any>(opts?: ChatInputOptions): DeepMocked<CommandInteractionOptionResolver<Cached>>;
|
|
305
287
|
|
|
306
288
|
export { MeoCordTestingModule, TestingModule, TestingModuleBuilder, createChatInputOptions, createMock, createMockChannel, createMockClient, createMockFn, createMockGuild, createMockInteraction, createMockMessage, createMockUser, isMockFunction };
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meocord",
|
|
3
3
|
"description": "Decorator-based Discord bot framework built on discord.js. Brings NestJS-style controllers, dependency injection, guards, and testing utilities to bot development — with a full CLI and TypeScript-first design.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=22"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"
|
|
10
|
+
"format": "prettier --write \"**/*.md\" \"src/bin/app-template/**/*.template\"",
|
|
11
|
+
"format:check": "prettier --check \"**/*.md\" \"src/bin/app-template/**/*.template\"",
|
|
12
|
+
"lint": "bun run format && eslint --fix . && tsc --noEmit && tsc --noEmit --project tsconfig.test.json && tsc --noEmit --project tsconfig.eslint.json",
|
|
11
13
|
"build": "rm -rf ./dist && rollup -c",
|
|
12
14
|
"prepare": "husky",
|
|
13
15
|
"test": "vitest run",
|
|
16
|
+
"verify:generated": "bun scripts/verify-generated.ts",
|
|
14
17
|
"test:watch": "vitest",
|
|
15
18
|
"test:coverage": "vitest run --coverage",
|
|
16
19
|
"test:typecheck": "tsc --noEmit --project tsconfig.test.json"
|
|
@@ -75,16 +78,14 @@
|
|
|
75
78
|
],
|
|
76
79
|
"dependencies": {
|
|
77
80
|
"@clack/prompts": "^1.7.0",
|
|
78
|
-
"@swc/core": "1.
|
|
81
|
+
"@swc/core": "1.16.1",
|
|
79
82
|
"chalk": "^6.0.0",
|
|
80
83
|
"cli-table3": "^0.6.5",
|
|
81
84
|
"commander": "^15.0.0",
|
|
82
|
-
"dayjs": "^1.11.
|
|
83
|
-
"dotenv": "^17.4.2",
|
|
85
|
+
"dayjs": "^1.11.23",
|
|
84
86
|
"inversify": "^8.2.3",
|
|
85
87
|
"jiti": "^2.7.0",
|
|
86
88
|
"lodash-es": "^4.18.1",
|
|
87
|
-
"nodemon": "^3.1.14",
|
|
88
89
|
"reflect-metadata": "^0.2.2",
|
|
89
90
|
"simple-git": "^3.36.0",
|
|
90
91
|
"swc-loader": "^0.2.7",
|
|
@@ -100,14 +101,13 @@
|
|
|
100
101
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
101
102
|
"@rollup/plugin-swc": "^0.4.1",
|
|
102
103
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
103
|
-
"@semantic-release/exec": "^7.1.0",
|
|
104
104
|
"@semantic-release/github": "^12.0.9",
|
|
105
105
|
"@semantic-release/release-notes-generator": "^14.1.1",
|
|
106
106
|
"@types/lodash-es": "^4.17.12",
|
|
107
107
|
"@types/webpack-node-externals": "^3.0.4",
|
|
108
108
|
"@typescript-eslint/parser": "^8.67.0",
|
|
109
109
|
"discord.js": "^14.27.0",
|
|
110
|
-
"eslint": "^10.
|
|
110
|
+
"eslint": "^10.9.0",
|
|
111
111
|
"eslint-config-prettier": "^10.1.8",
|
|
112
112
|
"eslint-plugin-headers": "^1.3.4",
|
|
113
113
|
"eslint-plugin-import-x": "^4.17.1",
|
|
@@ -116,16 +116,15 @@
|
|
|
116
116
|
"globals": "^17.11.0",
|
|
117
117
|
"husky": "^9.1.7",
|
|
118
118
|
"prettier": "^3.9.6",
|
|
119
|
-
"rollup": "^4.62.
|
|
119
|
+
"rollup": "^4.62.5",
|
|
120
120
|
"rollup-plugin-copy": "^3.5.0",
|
|
121
121
|
"rollup-plugin-dts": "^6.5.1",
|
|
122
122
|
"semantic-release": "^25.0.9",
|
|
123
|
-
"ts-node": "^10.9.2",
|
|
124
123
|
"typescript": "^6.0.3",
|
|
125
124
|
"typescript-eslint": "^8.67.0",
|
|
126
|
-
"@vitest/coverage-istanbul": "^4.1.
|
|
125
|
+
"@vitest/coverage-istanbul": "^4.1.11",
|
|
127
126
|
"unplugin-swc": "^1.5.11",
|
|
128
|
-
"vitest": "^4.1.
|
|
127
|
+
"vitest": "^4.1.11"
|
|
129
128
|
},
|
|
130
129
|
"peerDependencies": {
|
|
131
130
|
"discord.js": "^14.26.4",
|