@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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GenericResponderInteraction } from "./manager.js";
|
|
2
|
+
export type WithCustomId<T> = T & {
|
|
3
|
+
customId: string;
|
|
4
|
+
};
|
|
5
|
+
type EmitResponderInteraction = Omit<GenericResponderInteraction, "customId">;
|
|
6
|
+
interface EmitResponderData {
|
|
7
|
+
customId: string;
|
|
8
|
+
interaction: EmitResponderInteraction;
|
|
9
|
+
}
|
|
10
|
+
export declare function emitResponder(customId: string, interaction: EmitResponderInteraction): void;
|
|
11
|
+
export declare function emitResponder(data: EmitResponderData): void;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/creators/responders/emit.ts
|
|
2
|
+
import { EzziApp } from "../../app.js";
|
|
3
|
+
function emitResponder(a, b) {
|
|
4
|
+
const { customId, interaction } = typeof a === "string" ? { customId: a, interaction: b } : a;
|
|
5
|
+
const app = EzziApp.getInstance();
|
|
6
|
+
app.responders.onResponder(Object.assign(interaction, { customId }));
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
emitResponder
|
|
10
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CacheType, ChatInputCommandInteraction, MessageComponentInteraction, MessageContextMenuCommandInteraction, ModalSubmitInteraction, UserContextMenuCommandInteraction } from "discord.js";
|
|
2
|
+
import { BaseManager } from "../manager.js";
|
|
3
|
+
import type { WithCustomId } from "./emit.js";
|
|
4
|
+
import { Responder, ResponderType } from "./responder.js";
|
|
5
|
+
export type GenericResponder = Responder<string, readonly ResponderType[], any, CacheType>;
|
|
6
|
+
export type GenericResponderInteraction = MessageComponentInteraction | ModalSubmitInteraction | WithCustomId<ChatInputCommandInteraction> | WithCustomId<UserContextMenuCommandInteraction> | WithCustomId<MessageContextMenuCommandInteraction>;
|
|
7
|
+
export declare class ResponderManager extends BaseManager {
|
|
8
|
+
private get config();
|
|
9
|
+
private readonly router;
|
|
10
|
+
set(responder: GenericResponder): void;
|
|
11
|
+
getHandler(type: ResponderType, customId: string): import("rou3").MatchedRoute<GenericResponder> | undefined;
|
|
12
|
+
private getType;
|
|
13
|
+
onResponder(interaction: GenericResponderInteraction): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/creators/responders/manager.ts
|
|
2
|
+
import { styleText } from "node:util";
|
|
3
|
+
import { Router } from "../../utils/router.js";
|
|
4
|
+
import { BaseManager } from "../manager.js";
|
|
5
|
+
import { ResponderType } from "./responder.js";
|
|
6
|
+
|
|
7
|
+
class ResponderManager extends BaseManager {
|
|
8
|
+
get config() {
|
|
9
|
+
return this.app.config.responders;
|
|
10
|
+
}
|
|
11
|
+
router = new Router;
|
|
12
|
+
set(responder) {
|
|
13
|
+
const path = responder.data.customId;
|
|
14
|
+
for (const type of new Set(responder.data.types)) {
|
|
15
|
+
this.router.add(type, path, responder);
|
|
16
|
+
this.logs.push([
|
|
17
|
+
styleText("greenBright", `▸ ${type}`),
|
|
18
|
+
styleText("gray", `>`),
|
|
19
|
+
styleText(["blue", "underline"], path),
|
|
20
|
+
styleText("green", "✓")
|
|
21
|
+
].join(" "));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getHandler(type, customId) {
|
|
25
|
+
return this.router.find(type, customId);
|
|
26
|
+
}
|
|
27
|
+
getType(interaction) {
|
|
28
|
+
return interaction.isButton() ? ResponderType.Button : interaction.isChatInputCommand() ? ResponderType.ChatInput : interaction.isMessageContextMenuCommand() ? ResponderType.MessageContextMenu : interaction.isUserContextMenuCommand() ? ResponderType.UserContextMenu : interaction.isStringSelectMenu() ? ResponderType.StringSelect : interaction.isChannelSelectMenu() ? ResponderType.ChannelSelect : interaction.isRoleSelectMenu() ? ResponderType.RoleSelect : interaction.isUserSelectMenu() ? ResponderType.UserSelect : interaction.isMentionableSelectMenu() ? ResponderType.MentionableSelect : interaction.isModalSubmit() && interaction.isFromMessage() ? ResponderType.ModalComponent : interaction.isModalSubmit() ? ResponderType.Modal : undefined;
|
|
29
|
+
}
|
|
30
|
+
async onResponder(interaction) {
|
|
31
|
+
const { middleware, onError, onNotFound } = this.config;
|
|
32
|
+
const responderType = this.getType(interaction);
|
|
33
|
+
if (!responderType) {
|
|
34
|
+
onNotFound?.(interaction);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const handler = this.getHandler(responderType, interaction.customId);
|
|
38
|
+
if (!handler) {
|
|
39
|
+
onNotFound?.(interaction);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const data = handler.data.data;
|
|
43
|
+
const params = handler.params && data.parse ? data.parse(handler.params) : handler.params ?? {};
|
|
44
|
+
let isBlock = false;
|
|
45
|
+
const block = () => isBlock = true;
|
|
46
|
+
if (middleware)
|
|
47
|
+
await middleware(interaction, block, params);
|
|
48
|
+
if (isBlock)
|
|
49
|
+
return;
|
|
50
|
+
await data.run(interaction, params).catch((err) => {
|
|
51
|
+
if (onError) {
|
|
52
|
+
onError(err, interaction, params);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw err;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
ResponderManager
|
|
61
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ButtonInteraction, CacheType, ChannelSelectMenuInteraction, ChatInputCommandInteraction, MentionableSelectMenuInteraction, MessageContextMenuCommandInteraction, ModalMessageModalSubmitInteraction, ModalSubmitInteraction, RoleSelectMenuInteraction, StringSelectMenuInteraction, UserContextMenuCommandInteraction, UserSelectMenuInteraction } from "discord.js";
|
|
2
|
+
import { type InferRouteParams } from "rou3";
|
|
3
|
+
import type { NotEmptyArray, Prettify, UniqueArray } from "../../utils/types.js";
|
|
4
|
+
import type { WithCustomId } from "./emit.js";
|
|
5
|
+
export declare enum ResponderType {
|
|
6
|
+
Button = "button",
|
|
7
|
+
StringSelect = "select.string",
|
|
8
|
+
UserSelect = "select.user",
|
|
9
|
+
RoleSelect = "select.role",
|
|
10
|
+
ChannelSelect = "select.channel",
|
|
11
|
+
MentionableSelect = "select.mentionable",
|
|
12
|
+
Modal = "modal",
|
|
13
|
+
ModalComponent = "modal.component",
|
|
14
|
+
ChatInput = "command.chat.input",
|
|
15
|
+
UserContextMenu = "command.context.user",
|
|
16
|
+
MessageContextMenu = "command.context.message"
|
|
17
|
+
}
|
|
18
|
+
export type ResponderInteraction<Type extends ResponderType, Cache extends CacheType> = {
|
|
19
|
+
[ResponderType.Button]: ButtonInteraction<Cache>;
|
|
20
|
+
[ResponderType.StringSelect]: StringSelectMenuInteraction<Cache>;
|
|
21
|
+
[ResponderType.UserSelect]: UserSelectMenuInteraction<Cache>;
|
|
22
|
+
[ResponderType.RoleSelect]: RoleSelectMenuInteraction<Cache>;
|
|
23
|
+
[ResponderType.ChannelSelect]: ChannelSelectMenuInteraction<Cache>;
|
|
24
|
+
[ResponderType.MentionableSelect]: MentionableSelectMenuInteraction<Cache>;
|
|
25
|
+
[ResponderType.Modal]: ModalSubmitInteraction<Cache>;
|
|
26
|
+
[ResponderType.ModalComponent]: ModalMessageModalSubmitInteraction<Cache>;
|
|
27
|
+
[ResponderType.ChatInput]: WithCustomId<ChatInputCommandInteraction<Cache>>;
|
|
28
|
+
[ResponderType.UserContextMenu]: WithCustomId<UserContextMenuCommandInteraction<Cache>>;
|
|
29
|
+
[ResponderType.MessageContextMenu]: WithCustomId<MessageContextMenuCommandInteraction<Cache>>;
|
|
30
|
+
}[Type];
|
|
31
|
+
type ResolveParams<Path extends string, Parsed> = Prettify<Parsed extends {
|
|
32
|
+
[x: string | number | symbol]: any;
|
|
33
|
+
} ? Parsed : InferRouteParams<Path>>;
|
|
34
|
+
export interface ResponderData<Path extends string, Types extends readonly ResponderType[], out Parsed, Cache extends CacheType> {
|
|
35
|
+
customId: Path;
|
|
36
|
+
types: NotEmptyArray<UniqueArray<Types>>;
|
|
37
|
+
cache?: Cache;
|
|
38
|
+
parse?(this: void, params: InferRouteParams<Path>): Parsed;
|
|
39
|
+
run(this: void, interaction: ResponderInteraction<Types[number], Cache>, params: ResolveParams<Path, Parsed>): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export declare class Responder<Path extends string, Types extends readonly ResponderType[], out Parsed, Cache extends CacheType> {
|
|
42
|
+
readonly data: ResponderData<Path, Types, Parsed, Cache>;
|
|
43
|
+
constructor(data: ResponderData<Path, Types, Parsed, Cache>);
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/creators/responders/responder.ts
|
|
2
|
+
var ResponderType;
|
|
3
|
+
((ResponderType2) => {
|
|
4
|
+
ResponderType2["Button"] = "button";
|
|
5
|
+
ResponderType2["StringSelect"] = "select.string";
|
|
6
|
+
ResponderType2["UserSelect"] = "select.user";
|
|
7
|
+
ResponderType2["RoleSelect"] = "select.role";
|
|
8
|
+
ResponderType2["ChannelSelect"] = "select.channel";
|
|
9
|
+
ResponderType2["MentionableSelect"] = "select.mentionable";
|
|
10
|
+
ResponderType2["Modal"] = "modal";
|
|
11
|
+
ResponderType2["ModalComponent"] = "modal.component";
|
|
12
|
+
ResponderType2["ChatInput"] = "command.chat.input";
|
|
13
|
+
ResponderType2["UserContextMenu"] = "command.context.user";
|
|
14
|
+
ResponderType2["MessageContextMenu"] = "command.context.message";
|
|
15
|
+
})(ResponderType ||= {});
|
|
16
|
+
|
|
17
|
+
class Responder {
|
|
18
|
+
data;
|
|
19
|
+
constructor(data) {
|
|
20
|
+
this.data = data;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
ResponderType,
|
|
25
|
+
Responder
|
|
26
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ApplicationCommandType, type CacheType, type ClientEvents, type PermissionResolvable } from "discord.js";
|
|
2
|
+
import { type BaseCommandsConfig, type BaseEventsConfig, type BaseRespondersConfig } from "../app.js";
|
|
3
|
+
import { type AppCommandData, type CommandType } from "./commands/command.js";
|
|
4
|
+
import { type EventData } from "./events/event.js";
|
|
5
|
+
import { Responder, type ResponderData, type ResponderType } from "./responders/responder.js";
|
|
6
|
+
export interface SetupCreatorsOptions {
|
|
7
|
+
commands?: Partial<BaseCommandsConfig> & {
|
|
8
|
+
defaultMemberPermissions?: PermissionResolvable[];
|
|
9
|
+
defaultBotPermissions?: PermissionResolvable[];
|
|
10
|
+
};
|
|
11
|
+
responders?: Partial<BaseRespondersConfig>;
|
|
12
|
+
events?: Partial<BaseEventsConfig>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initializes the Ezzi command/event/responder creation system.
|
|
16
|
+
*
|
|
17
|
+
* This function configures the Ezzi application’s internal registries
|
|
18
|
+
* for commands, events, and responders, and returns a set of factory
|
|
19
|
+
* functions used to create each type of component.
|
|
20
|
+
*/
|
|
21
|
+
export declare function setupCreators(options?: SetupCreatorsOptions): {
|
|
22
|
+
createCommand<T extends CommandType = ApplicationCommandType.ChatInput, P extends boolean = false, R = void>(data: AppCommandData<T, P, R>): any;
|
|
23
|
+
createEvent<EventName extends keyof ClientEvents>(data: EventData<EventName>): void;
|
|
24
|
+
createResponder<Path extends string, const Types extends readonly ResponderType[], Schema, Cache extends CacheType = CacheType>(data: ResponderData<Path, Types, Schema, Cache>): Responder<string, readonly ResponderType[], unknown, CacheType>;
|
|
25
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/creators/setup.ts
|
|
2
|
+
import {
|
|
3
|
+
ApplicationCommandOptionType,
|
|
4
|
+
ApplicationCommandType
|
|
5
|
+
} from "discord.js";
|
|
6
|
+
import {
|
|
7
|
+
EzziApp
|
|
8
|
+
} from "../app.js";
|
|
9
|
+
import { Event } from "./events/event.js";
|
|
10
|
+
import {
|
|
11
|
+
Responder
|
|
12
|
+
} from "./responders/responder.js";
|
|
13
|
+
function setupCreators(options = {}) {
|
|
14
|
+
const app = EzziApp.getInstance();
|
|
15
|
+
app.config.commands = { ...options.commands ?? {} };
|
|
16
|
+
app.config.commands.guilds ??= [];
|
|
17
|
+
app.config.responders = { ...options.responders ?? {} };
|
|
18
|
+
app.config.events = { ...options.events ?? {} };
|
|
19
|
+
if (process.env.GUILD_ID?.length) {
|
|
20
|
+
app.config.commands.guilds.push(process.env.GUILD_ID);
|
|
21
|
+
}
|
|
22
|
+
const defaultMemberPerms = options.commands?.defaultMemberPermissions;
|
|
23
|
+
const defaultBotPerms = options.commands?.defaultBotPermissions;
|
|
24
|
+
return {
|
|
25
|
+
createCommand(data) {
|
|
26
|
+
const currentApp = EzziApp.getInstance();
|
|
27
|
+
if (defaultMemberPerms) {
|
|
28
|
+
data.defaultMemberPermissions ??= defaultMemberPerms;
|
|
29
|
+
}
|
|
30
|
+
if (defaultBotPerms && !data.botPermissions?.length) {
|
|
31
|
+
data.botPermissions = defaultBotPerms;
|
|
32
|
+
}
|
|
33
|
+
const resolved = currentApp.commands.set(data);
|
|
34
|
+
if (typeof currentApp.commands.addLog === "function") {
|
|
35
|
+
currentApp.commands.addLog(resolved);
|
|
36
|
+
}
|
|
37
|
+
if (resolved.type !== ApplicationCommandType.ChatInput) {
|
|
38
|
+
return resolved;
|
|
39
|
+
}
|
|
40
|
+
const commandName = resolved.name;
|
|
41
|
+
const createSubcommand = (group) => (subData) => {
|
|
42
|
+
const subApp = EzziApp.getInstance();
|
|
43
|
+
if (defaultBotPerms && !subData.botPermissions?.length) {
|
|
44
|
+
subData = { ...subData, botPermissions: defaultBotPerms };
|
|
45
|
+
}
|
|
46
|
+
subApp.commands.addModule(commandName, {
|
|
47
|
+
...subData,
|
|
48
|
+
group,
|
|
49
|
+
type: ApplicationCommandOptionType.Subcommand
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
return Object.assign(data, {
|
|
53
|
+
...resolved,
|
|
54
|
+
group(groupData) {
|
|
55
|
+
const groupApp = EzziApp.getInstance();
|
|
56
|
+
if (defaultBotPerms && !groupData.botPermissions?.length) {
|
|
57
|
+
groupData = { ...groupData, botPermissions: defaultBotPerms };
|
|
58
|
+
}
|
|
59
|
+
groupApp.commands.addModule(commandName, {
|
|
60
|
+
...groupData,
|
|
61
|
+
type: ApplicationCommandOptionType.SubcommandGroup
|
|
62
|
+
});
|
|
63
|
+
return { subcommand: createSubcommand(groupData.name) };
|
|
64
|
+
},
|
|
65
|
+
subcommand: createSubcommand()
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
createEvent(data) {
|
|
69
|
+
const currentApp = EzziApp.getInstance();
|
|
70
|
+
const resolved = new Event({
|
|
71
|
+
...data,
|
|
72
|
+
once: data.event === "ready" || data.event === "clientReady" ? true : data.once
|
|
73
|
+
});
|
|
74
|
+
return currentApp.events.add(resolved);
|
|
75
|
+
},
|
|
76
|
+
createResponder(data) {
|
|
77
|
+
const currentApp = EzziApp.getInstance();
|
|
78
|
+
const responderInstance = new Responder(data);
|
|
79
|
+
currentApp.responders.set(responderInstance);
|
|
80
|
+
return responderInstance;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
setupCreators
|
|
86
|
+
};
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "./standard-schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates the current process environment variables using a StandardSchema.
|
|
4
|
+
*
|
|
5
|
+
* This function executes the schema validation against `process.env`
|
|
6
|
+
* and ensures all required environment variables follow the expected shape.
|
|
7
|
+
* @example
|
|
8
|
+
* // "env.ts" — Using Zod
|
|
9
|
+
* import { z } from "zod";
|
|
10
|
+
* import { validateEnv } from "@ezzi/base";
|
|
11
|
+
*
|
|
12
|
+
* export const env = await validateEnv(z.object({
|
|
13
|
+
* BOT_TOKEN: z.string("BOT_TOKEN is required").min(1)
|
|
14
|
+
* }).passthrough());
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // "env.ts" — Using ArkType
|
|
18
|
+
* import { type } from "arktype";
|
|
19
|
+
* import { validateEnv } from "@ezzi/base";
|
|
20
|
+
*
|
|
21
|
+
* export const env = await validateEnv(type({
|
|
22
|
+
* BOT_TOKEN: "string > 0"
|
|
23
|
+
* }));
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateEnv<const T extends StandardSchemaV1>(schema: T): Promise<StandardSchemaV1.InferOutput<T>>;
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/env.ts
|
|
2
|
+
import { format, styleText } from "node:util";
|
|
3
|
+
async function validateEnv(schema) {
|
|
4
|
+
const result = await schema["~standard"].validate(process.env);
|
|
5
|
+
if (result.issues) {
|
|
6
|
+
console.log(result.issues.map((issue) => format(styleText("red", "✖︎ ENV VAR %s ➜ %s"), styleText("bold", issue.path?.join(".") ?? ""), styleText("gray", issue.message))).join(`
|
|
7
|
+
`));
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
console.log(styleText("dim", "☰ Environment variables validated ✓"));
|
|
11
|
+
return result.value;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
validateEnv
|
|
15
|
+
};
|
package/dist/error.d.ts
ADDED
package/dist/error.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/error.ts
|
|
2
|
+
import {
|
|
3
|
+
codeBlock,
|
|
4
|
+
parseWebhookURL,
|
|
5
|
+
REST,
|
|
6
|
+
Routes,
|
|
7
|
+
TextDisplayBuilder,
|
|
8
|
+
time
|
|
9
|
+
} from "discord.js";
|
|
10
|
+
import console from "node:console";
|
|
11
|
+
import { styleText } from "node:util";
|
|
12
|
+
|
|
13
|
+
class EzziError extends Error {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class RunBlockError {
|
|
20
|
+
}
|
|
21
|
+
async function baseErrorHandler(error, client) {
|
|
22
|
+
if (client?.user)
|
|
23
|
+
console.log(client.user.displayName);
|
|
24
|
+
const text = [];
|
|
25
|
+
const hightlight = (text2) => text2.replace(/\(([^)]+)\)/g, (_, match) => [
|
|
26
|
+
styleText("gray", "("),
|
|
27
|
+
styleText("cyan", match),
|
|
28
|
+
styleText("gray", ")")
|
|
29
|
+
].join(""));
|
|
30
|
+
if ("message" in error)
|
|
31
|
+
text.push(styleText("red", `${error.message}`));
|
|
32
|
+
if ("stack" in error) {
|
|
33
|
+
const formated = `${error.stack}`.replaceAll(process.cwd(), ".").replaceAll("at ", styleText("gray", "at "));
|
|
34
|
+
text.push(hightlight(formated));
|
|
35
|
+
}
|
|
36
|
+
console.log(text.join(`
|
|
37
|
+
`));
|
|
38
|
+
const url = process.env.WEBHOOK_LOGS_URL;
|
|
39
|
+
if (!url)
|
|
40
|
+
return;
|
|
41
|
+
const data = parseWebhookURL(url);
|
|
42
|
+
if (!data)
|
|
43
|
+
return;
|
|
44
|
+
const rest = new REST;
|
|
45
|
+
if (process.env.BOT_TOKEN)
|
|
46
|
+
rest.setToken(process.env.BOT_TOKEN);
|
|
47
|
+
try {
|
|
48
|
+
const username = client?.user?.username;
|
|
49
|
+
rest.post(Routes.webhook(data.id, data.token), {
|
|
50
|
+
body: {
|
|
51
|
+
flags: ["IsComponentsV2"],
|
|
52
|
+
components: [
|
|
53
|
+
new TextDisplayBuilder({
|
|
54
|
+
content: [
|
|
55
|
+
codeBlock("ansi", text.join(`
|
|
56
|
+
`)),
|
|
57
|
+
time(new Date, "R")
|
|
58
|
+
].join(`
|
|
59
|
+
`)
|
|
60
|
+
})
|
|
61
|
+
],
|
|
62
|
+
withComponents: true,
|
|
63
|
+
avatarURL: client?.user?.displayAvatarURL({ size: 512 }),
|
|
64
|
+
username: username ? `${username} logs` : "Logs"
|
|
65
|
+
}
|
|
66
|
+
}).catch(console.error);
|
|
67
|
+
} catch {
|
|
68
|
+
console.log();
|
|
69
|
+
console.error("ENV VAR → %s Invalid webhook url", styleText(["bold", "underline"], "WEBHOOK_LOGS_URL"));
|
|
70
|
+
console.log();
|
|
71
|
+
console.warn("Unable to send logs to webhook because the url is invalid");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
baseErrorHandler,
|
|
76
|
+
RunBlockError,
|
|
77
|
+
EzziError
|
|
78
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./bootstrap.js";
|
|
2
|
+
export * from "./creators/index.js";
|
|
3
|
+
export * from "./env.js";
|
|
4
|
+
export * from "./version.js";
|
|
5
|
+
export * from "./creators/commands/command.js";
|
|
6
|
+
export * from "./creators/commands/context.js";
|
|
7
|
+
export * from "./creators/events/event.js";
|
|
8
|
+
export * from "./creators/responders/responder.js";
|
|
9
|
+
export * from "./tools/index.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
export * from "./bootstrap.js";
|
|
3
|
+
export * from "./creators/index.js";
|
|
4
|
+
export * from "./env.js";
|
|
5
|
+
export * from "./version.js";
|
|
6
|
+
export * from "./creators/commands/command.js";
|
|
7
|
+
export * from "./creators/commands/context.js";
|
|
8
|
+
export * from "./creators/events/event.js";
|
|
9
|
+
export * from "./creators/responders/responder.js";
|
|
10
|
+
export * from "./tools/index.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ModuleImported {
|
|
2
|
+
module: any;
|
|
3
|
+
filepath: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Dynamically loads modules using glob patterns, returning each imported module
|
|
7
|
+
* along with its file path.
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadModules(meta: ImportMeta, modules?: string[]): Promise<ModuleImported[]>;
|
package/dist/modules.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/modules.ts
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { glob } from "tinyglobby";
|
|
4
|
+
async function loadModules(meta, modules = []) {
|
|
5
|
+
const ignore = modules.filter((path) => path.charAt(0) == "!").map((path) => path.slice(1));
|
|
6
|
+
const filepaths = await glob(modules, { cwd: meta.dirname, ignore });
|
|
7
|
+
const loadedModules = [];
|
|
8
|
+
for (const path of filepaths) {
|
|
9
|
+
await import("file://" + join(meta.dirname, path)).then((imported) => loadedModules.push({
|
|
10
|
+
module: imported,
|
|
11
|
+
filepath: path
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
return loadedModules;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
loadModules
|
|
18
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** The Standard Schema interface. */
|
|
2
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
3
|
+
/** The Standard Schema properties. */
|
|
4
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
5
|
+
}
|
|
6
|
+
export declare namespace StandardSchemaV1 {
|
|
7
|
+
/** The Standard Schema properties interface. */
|
|
8
|
+
interface Props<Input = unknown, Output = Input> {
|
|
9
|
+
/** The version number of the standard. */
|
|
10
|
+
readonly version: 1;
|
|
11
|
+
/** The vendor name of the schema library. */
|
|
12
|
+
readonly vendor: string;
|
|
13
|
+
/** Validates unknown input values. */
|
|
14
|
+
readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
|
|
15
|
+
/** Inferred types associated with the schema. */
|
|
16
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** The result interface of the validate function. */
|
|
19
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
20
|
+
/** The result interface if validation succeeds. */
|
|
21
|
+
interface SuccessResult<Output> {
|
|
22
|
+
/** The typed output value. */
|
|
23
|
+
readonly value: Output;
|
|
24
|
+
/** A falsy value for `issues` indicates success. */
|
|
25
|
+
readonly issues?: undefined;
|
|
26
|
+
}
|
|
27
|
+
interface Options {
|
|
28
|
+
/** Explicit support for additional vendor-specific parameters, if needed. */
|
|
29
|
+
readonly libraryOptions?: Record<string, unknown> | undefined;
|
|
30
|
+
}
|
|
31
|
+
/** The result interface if validation fails. */
|
|
32
|
+
interface FailureResult {
|
|
33
|
+
/** The issues of failed validation. */
|
|
34
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
35
|
+
}
|
|
36
|
+
/** The issue interface of the failure output. */
|
|
37
|
+
interface Issue {
|
|
38
|
+
/** The error message of the issue. */
|
|
39
|
+
readonly message: string;
|
|
40
|
+
/** The path of the issue, if any. */
|
|
41
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
42
|
+
}
|
|
43
|
+
/** The path segment interface of the issue. */
|
|
44
|
+
interface PathSegment {
|
|
45
|
+
/** The key representing a path segment. */
|
|
46
|
+
readonly key: PropertyKey;
|
|
47
|
+
}
|
|
48
|
+
/** The Standard Schema types interface. */
|
|
49
|
+
interface Types<Input = unknown, Output = Input> {
|
|
50
|
+
/** The input type of the schema. */
|
|
51
|
+
readonly input: Input;
|
|
52
|
+
/** The output type of the schema. */
|
|
53
|
+
readonly output: Output;
|
|
54
|
+
}
|
|
55
|
+
/** Infers the input type of a Standard Schema. */
|
|
56
|
+
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
57
|
+
/** Infers the output type of a Standard Schema. */
|
|
58
|
+
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
59
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type LogParams = [message?: any, ...params: any[]];
|
|
2
|
+
declare function log(...params: LogParams): void;
|
|
3
|
+
declare function success(...params: LogParams): void;
|
|
4
|
+
declare function warn(...params: LogParams): void;
|
|
5
|
+
declare function error(...params: LogParams): void;
|
|
6
|
+
export declare const logger: {
|
|
7
|
+
log: typeof log;
|
|
8
|
+
success: typeof success;
|
|
9
|
+
warn: typeof warn;
|
|
10
|
+
error: typeof error;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/tools/logger.ts
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
function log(...params) {
|
|
4
|
+
return console.log(...params);
|
|
5
|
+
}
|
|
6
|
+
function success(...params) {
|
|
7
|
+
return log(chalk.green(`✓`), ...params);
|
|
8
|
+
}
|
|
9
|
+
function warn(...params) {
|
|
10
|
+
return console.warn(chalk.yellow(`▲`), ...params);
|
|
11
|
+
}
|
|
12
|
+
function error(...params) {
|
|
13
|
+
return console.error(chalk.red(`✖︎`), ...params);
|
|
14
|
+
}
|
|
15
|
+
var logger = {
|
|
16
|
+
log,
|
|
17
|
+
success,
|
|
18
|
+
warn,
|
|
19
|
+
error
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
logger
|
|
23
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Client, type LocalizationMap } from "discord.js";
|
|
2
|
+
export interface ParsedCommand {
|
|
3
|
+
id: string | null;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
category: string;
|
|
7
|
+
options: string;
|
|
8
|
+
slash: {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
} | null;
|
|
12
|
+
localizations?: LocalizationMap;
|
|
13
|
+
aliases?: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function parseCommands(client: Client): ParsedCommand[];
|