@ezzi/base 1.0.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/README.md +29 -0
- package/dist/app.d.ts +47 -0
- package/dist/app.js +54 -0
- package/dist/bootstrap.d.ts +68 -0
- package/dist/bootstrap.js +35 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.js +42 -0
- package/dist/creators/commands/command.d.ts +140 -0
- package/dist/creators/commands/command.js +63 -0
- package/dist/creators/commands/context.d.ts +33 -0
- package/dist/creators/commands/context.js +204 -0
- package/dist/creators/commands/manager.d.ts +50 -0
- package/dist/creators/commands/manager.js +560 -0
- package/dist/creators/events/event.d.ts +21 -0
- package/dist/creators/events/event.js +10 -0
- package/dist/creators/events/manager.d.ts +12 -0
- package/dist/creators/events/manager.js +71 -0
- package/dist/creators/index.d.ts +5 -0
- package/dist/creators/index.js +11 -0
- package/dist/creators/manager.d.ts +6 -0
- package/dist/creators/manager.js +12 -0
- package/dist/creators/responders/emit.d.ts +12 -0
- package/dist/creators/responders/emit.js +10 -0
- package/dist/creators/responders/manager.d.ts +14 -0
- package/dist/creators/responders/manager.js +61 -0
- package/dist/creators/responders/responder.d.ts +45 -0
- package/dist/creators/responders/responder.js +26 -0
- package/dist/creators/setup.d.ts +25 -0
- package/dist/creators/setup.js +86 -0
- package/dist/env.d.ts +25 -0
- package/dist/env.js +15 -0
- package/dist/error.d.ts +7 -0
- package/dist/error.js +78 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/modules.d.ts +9 -0
- package/dist/modules.js +18 -0
- package/dist/standard-schema.d.ts +59 -0
- package/dist/standard-schema.js +0 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +3 -0
- package/dist/tools/logger.d.ts +12 -0
- package/dist/tools/logger.js +23 -0
- package/dist/tools/parseCommand.d.ts +15 -0
- package/dist/tools/parseCommand.js +144 -0
- package/dist/utils/router.d.ts +9 -0
- package/dist/utils/router.js +24 -0
- package/dist/utils/types.d.ts +7 -0
- package/dist/utils/types.js +0 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +5 -0
- package/package.json +79 -0
- package/tsconfig/base.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Ezzi Base
|
|
2
|
+
|
|
3
|
+
Library with structures and functions for creating modern Discord applications.
|
|
4
|
+
|
|
5
|
+
It all starts with the bootstrap function.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { bootstrap } from "@ezzi/base";
|
|
9
|
+
|
|
10
|
+
await bootstrap({ meta: import.meta });
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Migrating from Constatic to Ezzi is very simple! Just replace `@constatic/base` with `@ezzi/base`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🍴 About this project (Fork)
|
|
18
|
+
|
|
19
|
+
**Ezzi** is a fork of the original project [Constatic](https://github.com/rinckodev/constatic) developed by [@rinckodev](https://github.com/rinckodev).
|
|
20
|
+
|
|
21
|
+
While keeping the excellent core ideas and structure of the original project, Ezzi was created to introduce customized modifications, adjustments, and improvements tailored specifically for our ecosystem's needs. All credits for the brilliant base architecture go to the original author.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Constatic
|
|
26
|
+
|
|
27
|
+
⚠️ It is recommended to use the [Constant CLI](https://constatic-docs.vercel.app/pt/docs/discord/start) to generate a project instead of doing it manually.
|
|
28
|
+
|
|
29
|
+
[📚 Read the full documentation here](https://constatic-docs.vercel.app/pt/docs)
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Client, type CommandInteraction, type Message, type PermissionResolvable } from "discord.js";
|
|
2
|
+
import { type OptionNeed } from "./creators/commands/command.js";
|
|
3
|
+
import { type CommandContext } from "./creators/commands/context.js";
|
|
4
|
+
import { CommandManager } from "./creators/commands/manager.js";
|
|
5
|
+
import type { EventPropData } from "./creators/events/event.js";
|
|
6
|
+
import { EventManager } from "./creators/events/manager.js";
|
|
7
|
+
import { ResponderManager, type GenericResponderInteraction } from "./creators/responders/manager.js";
|
|
8
|
+
export interface BaseCommandsConfig {
|
|
9
|
+
guilds?: string[];
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
prefix?(message: Message): string[] | Promise<string[]>;
|
|
12
|
+
middleware?(ctx: CommandContext, block: () => void): Promise<void>;
|
|
13
|
+
onNotFound?(interaction: CommandInteraction): void;
|
|
14
|
+
onError?(ctx: CommandContext, error: unknown): void;
|
|
15
|
+
onOptionsError?(message: Message, options: OptionNeed[]): void;
|
|
16
|
+
onMemberPermissionsFailed?(ctx: CommandContext, missing: PermissionResolvable[]): void;
|
|
17
|
+
onBotPermissionsFailed?(ctx: CommandContext, missing: PermissionResolvable[]): void;
|
|
18
|
+
}
|
|
19
|
+
export interface BaseRespondersConfig {
|
|
20
|
+
middleware?(interaction: GenericResponderInteraction, block: () => void, params: object): Promise<void>;
|
|
21
|
+
onNotFound?(interaction: GenericResponderInteraction): void;
|
|
22
|
+
onError?(error: unknown, interaction: GenericResponderInteraction, params: object): void;
|
|
23
|
+
}
|
|
24
|
+
export interface BaseEventsConfig {
|
|
25
|
+
middleware?(event: EventPropData, block: (...tags: string[]) => void): Promise<void>;
|
|
26
|
+
onError?(error: unknown, event: EventPropData): void;
|
|
27
|
+
}
|
|
28
|
+
export type BaseErrorHandler = (error: Error | unknown, client: Client) => void;
|
|
29
|
+
export interface BaseConfig {
|
|
30
|
+
commands: BaseCommandsConfig;
|
|
31
|
+
events: BaseEventsConfig;
|
|
32
|
+
responders: BaseRespondersConfig;
|
|
33
|
+
errorHandler: BaseErrorHandler;
|
|
34
|
+
}
|
|
35
|
+
export declare class EzziApp {
|
|
36
|
+
readonly commands: CommandManager;
|
|
37
|
+
readonly responders: ResponderManager;
|
|
38
|
+
readonly events: EventManager;
|
|
39
|
+
readonly config: BaseConfig;
|
|
40
|
+
private static "~instance";
|
|
41
|
+
private constructor();
|
|
42
|
+
static getInstance(): EzziApp;
|
|
43
|
+
static destroy(): void;
|
|
44
|
+
setErrorHandler(handler: BaseErrorHandler): void;
|
|
45
|
+
intro(): void;
|
|
46
|
+
printLogs(): void;
|
|
47
|
+
}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/app.ts
|
|
2
|
+
import { brBuilder } from "@magicyan/discord";
|
|
3
|
+
import {
|
|
4
|
+
version as djsVersion
|
|
5
|
+
} from "discord.js";
|
|
6
|
+
import { styleText } from "node:util";
|
|
7
|
+
import { CommandManager } from "./creators/commands/manager.js";
|
|
8
|
+
import { EventManager } from "./creators/events/manager.js";
|
|
9
|
+
import {
|
|
10
|
+
ResponderManager
|
|
11
|
+
} from "./creators/responders/manager.js";
|
|
12
|
+
import { baseErrorHandler } from "./error.js";
|
|
13
|
+
import { version } from "./version.js";
|
|
14
|
+
var isBun = typeof Bun !== "undefined";
|
|
15
|
+
|
|
16
|
+
class EzziApp {
|
|
17
|
+
commands;
|
|
18
|
+
responders;
|
|
19
|
+
events;
|
|
20
|
+
config;
|
|
21
|
+
static "~instance" = null;
|
|
22
|
+
constructor() {
|
|
23
|
+
this.events = new EventManager(this);
|
|
24
|
+
this.commands = new CommandManager(this);
|
|
25
|
+
this.responders = new ResponderManager(this);
|
|
26
|
+
this.config = {
|
|
27
|
+
commands: {},
|
|
28
|
+
responders: {},
|
|
29
|
+
events: {},
|
|
30
|
+
errorHandler: baseErrorHandler
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
static getInstance() {
|
|
34
|
+
return this["~instance"] ??= new EzziApp;
|
|
35
|
+
}
|
|
36
|
+
static destroy() {
|
|
37
|
+
this["~instance"] = null;
|
|
38
|
+
}
|
|
39
|
+
setErrorHandler(handler) {
|
|
40
|
+
this.config.errorHandler = handler;
|
|
41
|
+
}
|
|
42
|
+
intro() {
|
|
43
|
+
console.log();
|
|
44
|
+
console.log("%s %s", styleText("blue", "★ Ezzi Base"), styleText("dim", version));
|
|
45
|
+
console.log("%s %s | %s %s", styleText("blueBright", "◌ discord.js"), styleText("dim", djsVersion), isBun ? "◌ Bun" : styleText("green", "⬢ Node.js"), styleText("dim", isBun ? Bun.version : process.versions.node));
|
|
46
|
+
console.log();
|
|
47
|
+
}
|
|
48
|
+
printLogs() {
|
|
49
|
+
console.log(brBuilder(...this.commands.logs, ...this.responders.logs, ...this.events.logs));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
EzziApp
|
|
54
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Client } from "discord.js";
|
|
2
|
+
import { type BaseErrorHandler } from "./app.js";
|
|
3
|
+
import { type CustomClientOptions } from "./client.js";
|
|
4
|
+
export interface BootstrapOptions extends CustomClientOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The caller module's `import.meta`.
|
|
7
|
+
* Internally used for resolving file paths when dynamically loading modules.
|
|
8
|
+
*/
|
|
9
|
+
meta: ImportMeta;
|
|
10
|
+
/**
|
|
11
|
+
* The Discord bot token.
|
|
12
|
+
* If omitted, bootstrap will attempt to use:
|
|
13
|
+
* - `env.BOT_TOKEN`
|
|
14
|
+
* - `process.env.BOT_TOKEN`
|
|
15
|
+
*/
|
|
16
|
+
token?: string;
|
|
17
|
+
/**
|
|
18
|
+
* A custom error handler that overrides the default one
|
|
19
|
+
* configured by `EzziApp`.
|
|
20
|
+
*
|
|
21
|
+
* If provided, all global errors such as:
|
|
22
|
+
* - `uncaughtException`
|
|
23
|
+
* - `unhandledRejection`
|
|
24
|
+
*
|
|
25
|
+
* will be handled by this function.
|
|
26
|
+
*/
|
|
27
|
+
errorHandler?: BaseErrorHandler;
|
|
28
|
+
/**
|
|
29
|
+
* A hook executed before loading the modules.
|
|
30
|
+
* Can be used to register services, prepare caches,
|
|
31
|
+
* validate dependencies, or modify the client before initialization.
|
|
32
|
+
*/
|
|
33
|
+
beforeLoad?(client: Client<boolean>): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Additional glob patterns used to load application modules.
|
|
36
|
+
*/
|
|
37
|
+
modules?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Whether initialization logs should be displayed.
|
|
40
|
+
* Defaults to `true`.
|
|
41
|
+
*/
|
|
42
|
+
loadLogs?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Custom environment variables that may complement or override
|
|
45
|
+
* values from `process.env`.
|
|
46
|
+
*/
|
|
47
|
+
env?: Record<string, any>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* Bootstraps and initializes a Ezzi application, creating the Discord client,
|
|
52
|
+
* loading modules, registering events, and applying global error handlers.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* import { bootstrap } from "@ezzi/base";
|
|
56
|
+
*
|
|
57
|
+
* await bootstrap({ meta: import.meta });
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* import { env } from "#env";
|
|
61
|
+
* import { bootstrap } from "@ezzi/base";
|
|
62
|
+
*
|
|
63
|
+
* await bootstrap({ meta: import.meta, env });
|
|
64
|
+
*/
|
|
65
|
+
export declare function bootstrap(options: BootstrapOptions): Promise<{
|
|
66
|
+
client: Client<boolean>;
|
|
67
|
+
imports: import("./modules.js").ModuleImported[];
|
|
68
|
+
}>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/bootstrap.ts
|
|
2
|
+
import { EzziApp } from "./app.js";
|
|
3
|
+
import { createClient } from "./client.js";
|
|
4
|
+
import { EzziError } from "./error.js";
|
|
5
|
+
import { loadModules } from "./modules.js";
|
|
6
|
+
async function bootstrap(options) {
|
|
7
|
+
const token = options.token ?? options.env?.BOT_TOKEN ?? process.env?.BOT_TOKEN;
|
|
8
|
+
if (!token)
|
|
9
|
+
throw new EzziError("The application token was not provided!");
|
|
10
|
+
const app = EzziApp.getInstance();
|
|
11
|
+
if (options.errorHandler) {
|
|
12
|
+
app.setErrorHandler(options.errorHandler);
|
|
13
|
+
}
|
|
14
|
+
const client = createClient(token, options);
|
|
15
|
+
process.on("uncaughtException", (error) => app.config.errorHandler(error, client));
|
|
16
|
+
process.on("unhandledRejection", (error) => app.config.errorHandler(error, client));
|
|
17
|
+
if (options.beforeLoad) {
|
|
18
|
+
await options.beforeLoad(client);
|
|
19
|
+
}
|
|
20
|
+
const imports = await loadModules(options.meta, [
|
|
21
|
+
"./discord/**/*.{js,ts,jsx,tsx}",
|
|
22
|
+
"!./discord/index.{js,ts,jsx,tsx}",
|
|
23
|
+
...options.modules ?? []
|
|
24
|
+
]);
|
|
25
|
+
if (options.loadLogs ?? true) {
|
|
26
|
+
app.printLogs();
|
|
27
|
+
}
|
|
28
|
+
app.intro();
|
|
29
|
+
app.events.register(client);
|
|
30
|
+
client.login();
|
|
31
|
+
return { client, imports };
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
bootstrap
|
|
35
|
+
};
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Client, type ClientOptions } from "discord.js";
|
|
2
|
+
export type CustomClientOptions = Partial<ClientOptions>;
|
|
3
|
+
/**
|
|
4
|
+
* Creates and configures a Discord.js client instance integrated with EzziApp.
|
|
5
|
+
*
|
|
6
|
+
* This function initializes a `Client`, assigns the provided bot token, binds
|
|
7
|
+
* lifecycle events, and automatically wires command handlers, autocomplete
|
|
8
|
+
* handlers, prefix messages, and general interaction responders from the Ezzi framework.
|
|
9
|
+
*
|
|
10
|
+
* The client will log a formatted startup message once it becomes ready.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createClient(token: string, options: CustomClientOptions): Client<boolean>;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { CustomItents, CustomPartials } from "@magicyan/discord";
|
|
3
|
+
import { Client } from "discord.js";
|
|
4
|
+
import { styleText } from "node:util";
|
|
5
|
+
import { EzziApp } from "./app.js";
|
|
6
|
+
function createClient(token, options) {
|
|
7
|
+
const app = EzziApp.getInstance();
|
|
8
|
+
const client = new Client({
|
|
9
|
+
...options,
|
|
10
|
+
intents: options.intents ?? CustomItents.All,
|
|
11
|
+
partials: options.partials ?? CustomPartials.All,
|
|
12
|
+
failIfNotExists: options.failIfNotExists ?? false
|
|
13
|
+
});
|
|
14
|
+
client.token = token;
|
|
15
|
+
client.once("clientReady", async (readyClient) => {
|
|
16
|
+
console.log("%s %s %s", styleText("green", "●"), styleText(["greenBright", "underline"], readyClient.user.username), styleText("green", "application is ready!"));
|
|
17
|
+
await app.commands.register(readyClient);
|
|
18
|
+
if (typeof app.events.runReady === "function") {
|
|
19
|
+
await app.events.runReady(readyClient);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
client.on("messageCreate", async (message) => {
|
|
23
|
+
if (message.author.bot)
|
|
24
|
+
return;
|
|
25
|
+
await app.commands.onPrefixCommand(message);
|
|
26
|
+
});
|
|
27
|
+
client.on("interactionCreate", async (interaction) => {
|
|
28
|
+
if (interaction.isAutocomplete()) {
|
|
29
|
+
await app.commands.onAutocomplete(interaction);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (interaction.isCommand()) {
|
|
33
|
+
await app.commands.onCommand(interaction);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await app.responders.onResponder(interaction);
|
|
37
|
+
});
|
|
38
|
+
return client;
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
createClient
|
|
42
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type APIInteractionDataResolvedGuildMember, type APIRole, type ApplicationCommandOptionAllowedChannelTypes, type ApplicationCommandOptionChoiceData, ApplicationCommandOptionType, ApplicationCommandType, Attachment, AutocompleteInteraction, type BaseApplicationCommandData, type CacheType, type Channel, ChatInputCommandInteraction, GuildMember, InteractionContextType, type LocalizationMap, MessageContextMenuCommandInteraction, type PermissionResolvable, Role, User, UserContextMenuCommandInteraction } from "discord.js";
|
|
2
|
+
import type { NotEmptyArray, UniqueArray } from "../../utils/types.js";
|
|
3
|
+
import { CommandContext } from "./context.js";
|
|
4
|
+
export declare const IgnoreCommand: {
|
|
5
|
+
readonly Slash: "slash";
|
|
6
|
+
readonly Message: "message";
|
|
7
|
+
};
|
|
8
|
+
export type IgnoreCommandType = (typeof IgnoreCommand)[keyof typeof IgnoreCommand];
|
|
9
|
+
export type CommandType = Exclude<ApplicationCommandType, ApplicationCommandType.PrimaryEntryPoint>;
|
|
10
|
+
export type CommandContextOptions = {
|
|
11
|
+
getString(name: string, required?: boolean): string | null;
|
|
12
|
+
getNumber(name: string, required?: boolean): number | null;
|
|
13
|
+
getInteger(name: string, required?: boolean): number | null;
|
|
14
|
+
getBoolean(name: string, required?: boolean): boolean | null;
|
|
15
|
+
getUser(name: string, required?: boolean): User | null;
|
|
16
|
+
getMember(name: string): GuildMember | APIInteractionDataResolvedGuildMember | null;
|
|
17
|
+
getRole(name: string, required?: boolean): Role | APIRole | null;
|
|
18
|
+
getChannel(name: string, required?: boolean): ReturnType<ChatInputCommandInteraction["options"]["getChannel"]> | Channel | null;
|
|
19
|
+
getMentionable(name: string, required?: boolean): User | GuildMember | Role | APIInteractionDataResolvedGuildMember | APIRole | null;
|
|
20
|
+
getAttachment(name: string, required?: boolean): Attachment | null;
|
|
21
|
+
getSubcommand(required?: true): string | null;
|
|
22
|
+
getSubcommandGroup(required?: true): string | null;
|
|
23
|
+
};
|
|
24
|
+
export type CommandCategoryType = string;
|
|
25
|
+
export type OptionValueType = "text" | "number" | "integer" | "user" | "role" | "mentionable" | "channel" | "attachment" | "boolean";
|
|
26
|
+
export interface OptionNeed {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
value: OptionValueType;
|
|
30
|
+
}
|
|
31
|
+
type AutocompleteData<T> = Promise<readonly ApplicationCommandOptionChoiceData<T extends number | string ? T : number | string>[] | undefined | void>;
|
|
32
|
+
export type CacheMode<Contexts> = Contexts extends readonly InteractionContextType[] ? {
|
|
33
|
+
[InteractionContextType.Guild]: "cached";
|
|
34
|
+
[InteractionContextType.BotDM]: CacheType;
|
|
35
|
+
[InteractionContextType.PrivateChannel]: CacheType;
|
|
36
|
+
}[Contexts[number]] : CacheType;
|
|
37
|
+
export type AutocompleteRun<T, Contexts> = (this: void, interaction: AutocompleteInteraction<CacheMode<Contexts>>) => AutocompleteData<T>;
|
|
38
|
+
interface AutocompleteOptionData<T, Contexts> {
|
|
39
|
+
autocomplete?: true | AutocompleteRun<T, Contexts>;
|
|
40
|
+
}
|
|
41
|
+
interface BaseOptionData {
|
|
42
|
+
name: string;
|
|
43
|
+
nameLocalizations?: LocalizationMap;
|
|
44
|
+
description?: string;
|
|
45
|
+
descriptionLocalizations?: LocalizationMap;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
}
|
|
48
|
+
interface StringOptionData<Contexts> extends BaseOptionData, AutocompleteOptionData<string, Contexts> {
|
|
49
|
+
type: ApplicationCommandOptionType.String;
|
|
50
|
+
choices?: readonly ApplicationCommandOptionChoiceData<string>[];
|
|
51
|
+
minLength?: number;
|
|
52
|
+
maxLength?: number;
|
|
53
|
+
}
|
|
54
|
+
interface NumberOptionData<Contexts> extends BaseOptionData, AutocompleteOptionData<number, Contexts> {
|
|
55
|
+
type: ApplicationCommandOptionType.Number | ApplicationCommandOptionType.Integer;
|
|
56
|
+
choices?: readonly ApplicationCommandOptionChoiceData<number>[];
|
|
57
|
+
minValue?: number;
|
|
58
|
+
maxValue?: number;
|
|
59
|
+
}
|
|
60
|
+
interface ChannelOptionData extends BaseOptionData {
|
|
61
|
+
type: ApplicationCommandOptionType.Channel;
|
|
62
|
+
channelTypes?: readonly ApplicationCommandOptionAllowedChannelTypes[];
|
|
63
|
+
}
|
|
64
|
+
interface CommonOptionData extends BaseOptionData {
|
|
65
|
+
type: ApplicationCommandOptionType.Attachment | ApplicationCommandOptionType.Boolean | ApplicationCommandOptionType.Mentionable | ApplicationCommandOptionType.Role | ApplicationCommandOptionType.User;
|
|
66
|
+
}
|
|
67
|
+
export type SlashCommandPrimitiveOptionData<Contexts> = StringOptionData<Contexts> | NumberOptionData<Contexts> | CommonOptionData | ChannelOptionData;
|
|
68
|
+
export interface SubCommandOptionData<Contexts> extends Omit<BaseOptionData, "required"> {
|
|
69
|
+
type: ApplicationCommandOptionType.Subcommand;
|
|
70
|
+
defaultMemberPermissions?: PermissionResolvable;
|
|
71
|
+
botPermissions?: PermissionResolvable[];
|
|
72
|
+
options?: SlashCommandPrimitiveOptionData<Contexts>[];
|
|
73
|
+
}
|
|
74
|
+
export interface GroupOptionData<Contexts> extends Omit<BaseOptionData, "required"> {
|
|
75
|
+
type: ApplicationCommandOptionType.SubcommandGroup;
|
|
76
|
+
defaultMemberPermissions?: PermissionResolvable;
|
|
77
|
+
botPermissions?: PermissionResolvable[];
|
|
78
|
+
options: SubCommandOptionData<Contexts>[];
|
|
79
|
+
}
|
|
80
|
+
export type SlashCommandOptionData<Contexts> = SlashCommandPrimitiveOptionData<Contexts> | GroupOptionData<Contexts> | SubCommandOptionData<Contexts>;
|
|
81
|
+
export type RunInteraction<T, Contexts> = T extends ApplicationCommandType.Message ? MessageContextMenuCommandInteraction<CacheMode<Contexts>> : T extends ApplicationCommandType.User ? UserContextMenuCommandInteraction<CacheMode<Contexts>> : ChatInputCommandInteraction<CacheMode<Contexts>>;
|
|
82
|
+
interface CommandRunThis {
|
|
83
|
+
/** Blocks the flow of executions */
|
|
84
|
+
block(): never;
|
|
85
|
+
}
|
|
86
|
+
type BaseAppCommandData = Omit<BaseApplicationCommandData, "contexts" | "dmPermission"> & Pick<BaseOptionData, "descriptionLocalizations">;
|
|
87
|
+
type ResolveCommandModuleData<R> = R extends void ? undefined : R;
|
|
88
|
+
export type SubCommandModuleData<Contexts, R> = Omit<BaseOptionData, "required"> & {
|
|
89
|
+
group?: string;
|
|
90
|
+
shortcut?: boolean;
|
|
91
|
+
aliases?: string[];
|
|
92
|
+
ignore?: IgnoreCommandType;
|
|
93
|
+
defaultMemberPermissions?: PermissionResolvable;
|
|
94
|
+
botPermissions?: PermissionResolvable[];
|
|
95
|
+
run(this: CommandRunThis, ctx: CommandContext, data: ResolveCommandModuleData<R>): Promise<void>;
|
|
96
|
+
options?: SlashCommandPrimitiveOptionData<Contexts>[];
|
|
97
|
+
};
|
|
98
|
+
export type SubCommandGroupModuleData<Contexts, R, T> = Omit<BaseOptionData, "required"> & {
|
|
99
|
+
aliases?: string[];
|
|
100
|
+
defaultMemberPermissions?: PermissionResolvable;
|
|
101
|
+
botPermissions?: PermissionResolvable[];
|
|
102
|
+
options?: Omit<SubCommandOptionData<Contexts>, "type">[];
|
|
103
|
+
run?(this: CommandRunThis, ctx: CommandContext, data: ResolveCommandModuleData<R>): Promise<T>;
|
|
104
|
+
};
|
|
105
|
+
export type CommandModule = (SubCommandGroupModuleData<any, any, any> & {
|
|
106
|
+
type: ApplicationCommandOptionType.SubcommandGroup;
|
|
107
|
+
}) | (SubCommandModuleData<any, any> & {
|
|
108
|
+
type: ApplicationCommandOptionType.Subcommand;
|
|
109
|
+
group?: string;
|
|
110
|
+
});
|
|
111
|
+
export interface AppCommandData<T, Contexts, R> extends BaseAppCommandData {
|
|
112
|
+
name: string;
|
|
113
|
+
aliases?: string[];
|
|
114
|
+
category?: CommandCategoryType;
|
|
115
|
+
description?: string;
|
|
116
|
+
contexts?: NotEmptyArray<UniqueArray<Contexts>>;
|
|
117
|
+
dmPermission?: boolean;
|
|
118
|
+
type?: T;
|
|
119
|
+
global?: boolean;
|
|
120
|
+
ignore?: IgnoreCommandType;
|
|
121
|
+
botPermissions?: PermissionResolvable[];
|
|
122
|
+
run?(this: CommandRunThis, ctx: CommandContext): Promise<R>;
|
|
123
|
+
autocomplete?: AutocompleteRun<string | number, Contexts>;
|
|
124
|
+
options?: SlashCommandPrimitiveOptionData<Contexts>[] | (GroupOptionData<Contexts> | SubCommandOptionData<Contexts>)[];
|
|
125
|
+
}
|
|
126
|
+
export type GenericAppCommandData = AppCommandData<CommandType, readonly InteractionContextType[], unknown>;
|
|
127
|
+
declare class GroupCommandModule<Type, Contexts extends readonly InteractionContextType[], Return, ModuleReturn> {
|
|
128
|
+
readonly command: Command<Type, Contexts, Return>;
|
|
129
|
+
readonly data: SubCommandGroupModuleData<Contexts, Return, ModuleReturn>;
|
|
130
|
+
constructor(command: Command<Type, Contexts, Return>, data: SubCommandGroupModuleData<Contexts, Return, ModuleReturn>);
|
|
131
|
+
subcommand(data: SubCommandModuleData<Contexts, ModuleReturn>): this;
|
|
132
|
+
}
|
|
133
|
+
export declare class Command<Type, Contexts extends readonly InteractionContextType[] = readonly [typeof InteractionContextType.Guild], Return = unknown> {
|
|
134
|
+
readonly modules: CommandModule[];
|
|
135
|
+
readonly data: AppCommandData<Type, Contexts, Return>;
|
|
136
|
+
constructor(data: AppCommandData<Type, Contexts, Return>);
|
|
137
|
+
group<ModuleReturn = Return>(data: SubCommandGroupModuleData<Contexts, Return, ModuleReturn>): GroupCommandModule<Type, Contexts, Return, ModuleReturn>;
|
|
138
|
+
subcommand<R = Return>(data: SubCommandModuleData<Contexts, R>): this;
|
|
139
|
+
}
|
|
140
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/creators/commands/command.ts
|
|
2
|
+
import {
|
|
3
|
+
ApplicationCommandOptionType,
|
|
4
|
+
ApplicationCommandType,
|
|
5
|
+
InteractionContextType
|
|
6
|
+
} from "discord.js";
|
|
7
|
+
var IgnoreCommand = {
|
|
8
|
+
Slash: "slash",
|
|
9
|
+
Message: "message"
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
class GroupCommandModule {
|
|
13
|
+
command;
|
|
14
|
+
data;
|
|
15
|
+
constructor(command, data) {
|
|
16
|
+
this.command = command;
|
|
17
|
+
this.data = data;
|
|
18
|
+
}
|
|
19
|
+
subcommand(data) {
|
|
20
|
+
data.group ??= this.data.name;
|
|
21
|
+
this.command.subcommand(data);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class Command {
|
|
27
|
+
modules = [];
|
|
28
|
+
data;
|
|
29
|
+
constructor(data) {
|
|
30
|
+
this.data = data;
|
|
31
|
+
this.data.type ??= ApplicationCommandType.ChatInput;
|
|
32
|
+
if (this.data.type === ApplicationCommandType.ChatInput) {
|
|
33
|
+
this.data.description ??= this.data.name;
|
|
34
|
+
this.data.name = this.data.name.toLowerCase().replaceAll(" ", "");
|
|
35
|
+
}
|
|
36
|
+
if (this.data.name.length > 32) {
|
|
37
|
+
this.data.name = this.data.name.slice(0, 32);
|
|
38
|
+
}
|
|
39
|
+
if (!this.data.contexts) {
|
|
40
|
+
Object.assign(this.data, {
|
|
41
|
+
contexts: [InteractionContextType.Guild]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
group(data) {
|
|
46
|
+
this.modules.push({
|
|
47
|
+
...data,
|
|
48
|
+
type: ApplicationCommandOptionType.SubcommandGroup
|
|
49
|
+
});
|
|
50
|
+
return new GroupCommandModule(this, data);
|
|
51
|
+
}
|
|
52
|
+
subcommand(data) {
|
|
53
|
+
this.modules.push({
|
|
54
|
+
...data,
|
|
55
|
+
type: ApplicationCommandOptionType.Subcommand
|
|
56
|
+
});
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
IgnoreCommand,
|
|
62
|
+
Command
|
|
63
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Client, CommandInteraction, GuildMember, type InteractionEditReplyOptions, type InteractionReplyOptions, Message, type MessageEditOptions, type MessageReplyOptions, User } from "discord.js";
|
|
2
|
+
import type { CommandContextOptions, SlashCommandPrimitiveOptionData } from "./command.js";
|
|
3
|
+
type Source = Message | CommandInteraction;
|
|
4
|
+
type ReplyOptions = string | InteractionReplyOptions | MessageReplyOptions;
|
|
5
|
+
type EditOptions = string | InteractionEditReplyOptions | MessageEditOptions;
|
|
6
|
+
export declare class CommandContext {
|
|
7
|
+
readonly client: Client;
|
|
8
|
+
readonly source: Source;
|
|
9
|
+
private _botReply;
|
|
10
|
+
readonly args: string[];
|
|
11
|
+
private _parsedOptions;
|
|
12
|
+
constructor(client: Client, source: Source, args?: string[], optionDefs?: SlashCommandPrimitiveOptionData<boolean>[]);
|
|
13
|
+
private _parsePrefixOptions;
|
|
14
|
+
get user(): User;
|
|
15
|
+
get member(): GuildMember | null;
|
|
16
|
+
get message(): Message<boolean> | null;
|
|
17
|
+
get guild(): import("discord.js").Guild | null;
|
|
18
|
+
get guildId(): string | null;
|
|
19
|
+
get channel(): import("discord.js").TextBasedChannel | null;
|
|
20
|
+
isInteraction(): this is CommandContext & {
|
|
21
|
+
source: CommandInteraction;
|
|
22
|
+
};
|
|
23
|
+
isMessage(): this is CommandContext & {
|
|
24
|
+
source: Message;
|
|
25
|
+
};
|
|
26
|
+
get options(): CommandContextOptions;
|
|
27
|
+
getRaw(name: string): string | null;
|
|
28
|
+
deferReply(ephemeral?: boolean): Promise<void>;
|
|
29
|
+
reply(options: ReplyOptions): Promise<Message | undefined>;
|
|
30
|
+
editReply(options: EditOptions): Promise<Message | undefined>;
|
|
31
|
+
delete(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|