discordthing 0.1.2 → 0.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.
Files changed (49) hide show
  1. package/build/bot.d.ts +15 -19
  2. package/build/bot.js +28 -139
  3. package/build/commands/command.d.ts +26 -7
  4. package/build/commands/command.js +71 -37
  5. package/build/commands/context.d.ts +23 -0
  6. package/build/commands/context.js +75 -0
  7. package/build/commands/diff.js +0 -1
  8. package/build/commands/index.d.ts +3 -1
  9. package/build/commands/index.js +0 -1
  10. package/build/commands/manager.d.ts +64 -0
  11. package/build/commands/manager.js +138 -0
  12. package/build/commands/registration.js +0 -1
  13. package/build/context.d.ts +1 -1
  14. package/build/context.js +2 -3
  15. package/build/events/index.d.ts +1 -0
  16. package/build/events/index.js +0 -1
  17. package/build/events/listener.js +0 -1
  18. package/build/events/manager.d.ts +40 -0
  19. package/build/events/manager.js +86 -0
  20. package/build/index.js +0 -1
  21. package/build/logger.js +0 -1
  22. package/build/options/index.js +0 -1
  23. package/build/options/option.d.ts +12 -30
  24. package/build/options/option.js +7 -15
  25. package/build/options/options.d.ts +39 -30
  26. package/build/options/options.js +59 -36
  27. package/build/permissions.d.ts +4 -4
  28. package/build/permissions.js +2 -3
  29. package/build/plugin.js +0 -1
  30. package/build/utility-types.js +0 -1
  31. package/build/utils.js +0 -1
  32. package/package.json +6 -3
  33. package/build/bot.js.map +0 -1
  34. package/build/commands/command.js.map +0 -1
  35. package/build/commands/diff.js.map +0 -1
  36. package/build/commands/index.js.map +0 -1
  37. package/build/commands/registration.js.map +0 -1
  38. package/build/context.js.map +0 -1
  39. package/build/events/index.js.map +0 -1
  40. package/build/events/listener.js.map +0 -1
  41. package/build/index.js.map +0 -1
  42. package/build/logger.js.map +0 -1
  43. package/build/options/index.js.map +0 -1
  44. package/build/options/option.js.map +0 -1
  45. package/build/options/options.js.map +0 -1
  46. package/build/permissions.js.map +0 -1
  47. package/build/plugin.js.map +0 -1
  48. package/build/utility-types.js.map +0 -1
  49. package/build/utils.js.map +0 -1
@@ -0,0 +1,138 @@
1
+ import { err, NONE, Result } from "@l3dev/result";
2
+ import { Events, InteractionContextType } from "discord.js";
3
+ import { createCommandContext } from "./context.js";
4
+ import { CommandRegistration } from "./registration.js";
5
+ export class CommandManager {
6
+ bot;
7
+ commands = new Map();
8
+ commandFilters = [];
9
+ errorHandler = null;
10
+ constructor(bot, options) {
11
+ this.bot = bot;
12
+ for (const command of options.commands ?? []) {
13
+ this.commands.set(command.name, command);
14
+ }
15
+ bot.client.on(Events.InteractionCreate, this.onInteraction.bind(this));
16
+ }
17
+ /**
18
+ * Adds commands to the bot.
19
+ * @param commands The commands to add
20
+ * @returns A result indicating whether the commands were added successfully
21
+ * @example
22
+ * bot.commands.addMany(myCommand1, myCommand2);
23
+ * bot.commands.addMany([myCommand1, myCommand2]);
24
+ */
25
+ addMany(...commands) {
26
+ return Result.all(...commands.flat().map((command) => this.add(command)));
27
+ }
28
+ /**
29
+ * Adds a command to the bot.
30
+ * @param command The command to add
31
+ * @returns A result indicating whether the command was added successfully
32
+ * @example
33
+ * const myCommand = command({
34
+ * meta: {
35
+ * name: 'my-command',
36
+ * },
37
+ * handler: async (ctx) => {
38
+ * // your code here
39
+ * }
40
+ * });
41
+ *
42
+ * bot.commands.add(myCommand);
43
+ */
44
+ add(command) {
45
+ if (this.bot.client.isReady()) {
46
+ return err("BOT_ALREADY_STARTED", {
47
+ message: "Cannot add command after bot has started"
48
+ });
49
+ }
50
+ this.commands.set(command.name, command);
51
+ return NONE;
52
+ }
53
+ /**
54
+ * Adds a command filter that determines whether a command should be executed.
55
+ * @param filter The filter to add to the bot
56
+ * @example
57
+ * bot.commands.addFilter(async (interaction, command) => {
58
+ * if (interaction.guild.id !== process.env.GUILD_ID) return false;
59
+ * return true;
60
+ * });
61
+ */
62
+ addFilter(filter) {
63
+ this.commandFilters.push(filter);
64
+ }
65
+ /**
66
+ * Sets the command error handler for the bot.
67
+ * @param handler The error handler to use
68
+ * @example
69
+ * bot.commands.setErrorHandler(async (ctx, err) => {
70
+ * await ctx.interaction.reply("An error occurred!");
71
+ * });
72
+ */
73
+ setErrorHandler(handler) {
74
+ this.errorHandler = handler;
75
+ }
76
+ /** @internal */
77
+ async register(client) {
78
+ const commandRegistration = new CommandRegistration(this.bot.rest, client);
79
+ const globalCommands = Object.values(this.commands).filter((command) => {
80
+ const contexts = command.getContexts();
81
+ return (contexts.includes(InteractionContextType.BotDM) ||
82
+ contexts.includes(InteractionContextType.PrivateChannel));
83
+ });
84
+ const guildCommands = Object.values(this.commands).filter((command) => {
85
+ const contexts = command.getContexts();
86
+ return contexts.includes(InteractionContextType.Guild);
87
+ });
88
+ this.bot.logger.debug(`Registering global commands...`);
89
+ await commandRegistration.registerGlobalCommands(globalCommands);
90
+ const guilds = await client.guilds.fetch();
91
+ for (const guild of guilds.values()) {
92
+ this.bot.logger.debug(`Registering guild commands for guild ${guild.id}...`);
93
+ await commandRegistration.registerGuildCommands(guild.id, guildCommands);
94
+ }
95
+ }
96
+ async onInteraction(interaction) {
97
+ if (interaction.user.bot || !interaction.isChatInputCommand())
98
+ return;
99
+ const ctx = createCommandContext(this.bot, interaction);
100
+ const result = await this.executeCommand(ctx);
101
+ if (!result.ok && this.errorHandler) {
102
+ try {
103
+ await this.errorHandler(ctx, result);
104
+ }
105
+ catch (error) {
106
+ this.bot.logger.error(`Error while executing error handler:`, error);
107
+ }
108
+ }
109
+ }
110
+ async executeCommand(ctx) {
111
+ const commandName = ctx.interaction.commandName;
112
+ const command = this.commands.get(commandName);
113
+ if (!command) {
114
+ this.bot.logger.error(`Unknown command '${commandName}'`);
115
+ return err("UNKNOWN_COMMAND", {
116
+ command: commandName
117
+ });
118
+ }
119
+ if (!this.commandFilters.some((filter) => filter(ctx.interaction, command))) {
120
+ return NONE;
121
+ }
122
+ let result;
123
+ try {
124
+ result = await command.execute(ctx);
125
+ }
126
+ catch (error) {
127
+ result = err("COMMAND_FAILED", {
128
+ command: commandName,
129
+ error
130
+ });
131
+ }
132
+ const unwrapped = Result.unwrap(result);
133
+ if (!unwrapped.ok) {
134
+ this.bot.logger.error(`Error while executing command '${commandName}':`, result);
135
+ }
136
+ return unwrapped;
137
+ }
138
+ }
@@ -37,4 +37,3 @@ export class CommandRegistration {
37
37
  await Promise.all([...addPromises, ...removePromises]);
38
38
  }
39
39
  }
40
- //# sourceMappingURL=registration.js.map
@@ -6,4 +6,4 @@ export type GenericCtx = {
6
6
  permissions: PermissionsResolver;
7
7
  logger: ILogger;
8
8
  };
9
- export declare function createContext(bot: Bot, logger: ILogger): GenericCtx;
9
+ export declare function createGenericContext(bot: Bot): GenericCtx;
package/build/context.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { PermissionsResolver } from "./permissions.js";
2
- export function createContext(bot, logger) {
2
+ export function createGenericContext(bot) {
3
3
  return {
4
4
  bot,
5
5
  permissions: new PermissionsResolver(bot),
6
- logger
6
+ logger: bot.logger
7
7
  };
8
8
  }
9
- //# sourceMappingURL=context.js.map
@@ -1,2 +1,3 @@
1
1
  export { listen } from "./listener.js";
2
2
  export type { Listener } from "./listener.js";
3
+ export type { EventsManager, EventsManagerOptions } from "./manager.js";
@@ -1,2 +1 @@
1
1
  export { listen } from "./listener.js";
2
- //# sourceMappingURL=index.js.map
@@ -12,4 +12,3 @@ export class Listener {
12
12
  export function listen(listener) {
13
13
  return new Listener(listener.event, listener.handler, listener.once);
14
14
  }
15
- //# sourceMappingURL=listener.js.map
@@ -0,0 +1,40 @@
1
+ import { type RestOrArray } from "discord.js";
2
+ import type { Bot } from "../bot.js";
3
+ import type { Listener } from "./listener.js";
4
+ export type EventsManagerOptions = {
5
+ listeners?: Listener<any>[];
6
+ };
7
+ export declare class EventsManager {
8
+ private readonly bot;
9
+ private readonly readyListeners;
10
+ constructor(bot: Bot, options: EventsManagerOptions);
11
+ /**
12
+ * Adds event listeners to the bot.
13
+ * @param listeners The listeners to add
14
+ * @returns A result indicating whether the listeners were added successfully
15
+ * @example
16
+ * bot.events.addMany(myListener1, myListener2);
17
+ * bot.events.addMany([myListener1, myListener2]);
18
+ */
19
+ addMany(...listeners: RestOrArray<Listener<any>>): import("@l3dev/result").Ok<void[]> | import("@l3dev/result").Err<"BOT_ALREADY_STARTED", {
20
+ message: string;
21
+ }>;
22
+ /**
23
+ * Adds an event listener to the bot.
24
+ * @param listener The listener to add
25
+ * @returns A result indicating whether the listener was added successfully
26
+ * @example
27
+ * const myListener = listen({
28
+ * event: Events.InteractionCreate,
29
+ * handler: async (ctx, interaction) => {
30
+ * // your code here
31
+ * }
32
+ * });
33
+ *
34
+ * bot.events.add(myListener);
35
+ */
36
+ add(listener: Listener<any>): import("@l3dev/result").None | import("@l3dev/result").Err<"BOT_ALREADY_STARTED", {
37
+ message: string;
38
+ }>;
39
+ private createListenerFn;
40
+ }
@@ -0,0 +1,86 @@
1
+ import { err, NONE, Result } from "@l3dev/result";
2
+ import { Events } from "discord.js";
3
+ import { createGenericContext } from "../context.js";
4
+ export class EventsManager {
5
+ bot;
6
+ readyListeners = [];
7
+ constructor(bot, options) {
8
+ this.bot = bot;
9
+ for (const listener of options.listeners ?? []) {
10
+ const result = this.add(listener);
11
+ if (!result.ok) {
12
+ throw new (class extends Error {
13
+ result = result;
14
+ constructor(message) {
15
+ super(message);
16
+ }
17
+ })("Error adding listener while initializing events manager");
18
+ }
19
+ }
20
+ }
21
+ /**
22
+ * Adds event listeners to the bot.
23
+ * @param listeners The listeners to add
24
+ * @returns A result indicating whether the listeners were added successfully
25
+ * @example
26
+ * bot.events.addMany(myListener1, myListener2);
27
+ * bot.events.addMany([myListener1, myListener2]);
28
+ */
29
+ addMany(...listeners) {
30
+ return Result.all(...listeners.flat().map((listener) => this.add(listener)));
31
+ }
32
+ /**
33
+ * Adds an event listener to the bot.
34
+ * @param listener The listener to add
35
+ * @returns A result indicating whether the listener was added successfully
36
+ * @example
37
+ * const myListener = listen({
38
+ * event: Events.InteractionCreate,
39
+ * handler: async (ctx, interaction) => {
40
+ * // your code here
41
+ * }
42
+ * });
43
+ *
44
+ * bot.events.add(myListener);
45
+ */
46
+ add(listener) {
47
+ if (this.bot.client.isReady()) {
48
+ return err("BOT_ALREADY_STARTED", {
49
+ message: "Cannot add listener after bot has started"
50
+ });
51
+ }
52
+ if (listener.event === Events.ClientReady) {
53
+ this.readyListeners.push(listener);
54
+ return NONE;
55
+ }
56
+ (listener.once ? this.bot.client.once : this.bot.client.on)(listener.event, this.createListenerFn(listener));
57
+ return NONE;
58
+ }
59
+ createListenerFn(listener) {
60
+ return async (...args) => {
61
+ const ctx = createGenericContext(this.bot);
62
+ try {
63
+ await listener.handler(ctx, ...args);
64
+ }
65
+ catch (error) {
66
+ this.bot.logger.error(`Error in listener ${listener.event}:`, error);
67
+ }
68
+ };
69
+ }
70
+ /** @internal */
71
+ async runReadyListeners(client) {
72
+ // Make a copy so we can remove _once_ listeners
73
+ const listeners = [...this.readyListeners];
74
+ await Promise.all(listeners.map(async (listener) => {
75
+ const handler = this.createListenerFn(listener);
76
+ await handler(client);
77
+ if (listener.once) {
78
+ const index = this.readyListeners.indexOf(listener);
79
+ if (index === -1) {
80
+ return;
81
+ }
82
+ this.readyListeners.splice(index, 1);
83
+ }
84
+ }));
85
+ }
86
+ }
package/build/index.js CHANGED
@@ -1,4 +1,3 @@
1
1
  export { Bot } from "./bot.js";
2
2
  export { plugin, ResolvedPlugin } from "./plugin.js";
3
3
  export * from "./utility-types.js";
4
- //# sourceMappingURL=index.js.map
package/build/logger.js CHANGED
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=logger.js.map
@@ -1,2 +1 @@
1
1
  export { o, optionsToJson } from "./option.js";
2
- //# sourceMappingURL=index.js.map
@@ -1,4 +1,5 @@
1
- import { type APIApplicationCommandOption, type ApplicationCommandOptionAllowedChannelTypes, type RestOrArray } from "discord.js";
1
+ import { type APIApplicationCommandOption } from "discord.js";
2
+ import type * as z from "zod";
2
3
  import { AttachmentOption, BooleanOption, ChannelOption, Choice, IntegerOption, MentionableOption, NumberOption, RoleOption, StringOption, UserOption, type AsOptional, type Option, type OptionalType } from "./options.js";
3
4
  import type { Expand } from "../utility-types.js";
4
5
  export type GenericOption = Option<any, any>;
@@ -14,34 +15,15 @@ export declare const o: {
14
15
  /**
15
16
  * A command attachment option.
16
17
  */
17
- attachment: () => AttachmentOption<import("discord.js").Attachment, "required">;
18
+ attachment: () => AttachmentOption<import("discord.js").Attachment, "required", z.ZodType<import("discord.js").Attachment, import("discord.js").Attachment, z.core.$ZodTypeInternals<import("discord.js").Attachment, import("discord.js").Attachment>>>;
18
19
  /**
19
20
  * A command boolean option.
20
21
  */
21
- boolean: () => BooleanOption<boolean, "required">;
22
+ boolean: () => BooleanOption<boolean, "required", z.ZodType<boolean, boolean, z.core.$ZodTypeInternals<boolean, boolean>>>;
22
23
  /**
23
24
  * A command channel option.
24
- * @param channelTypes The channel types.
25
25
  */
26
- channel: <T extends ApplicationCommandOptionAllowedChannelTypes>(...channelTypes: RestOrArray<T>) => ChannelOption<Extract<import("discord.js").CategoryChannel, {
27
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
28
- }> | Extract<import("discord.js").NewsChannel, {
29
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
30
- }> | Extract<import("discord.js").StageChannel, {
31
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
32
- }> | Extract<import("discord.js").TextChannel, {
33
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
34
- }> | Extract<import("discord.js").PublicThreadChannel<boolean>, {
35
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
36
- }> | Extract<import("discord.js").PrivateThreadChannel, {
37
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
38
- }> | Extract<import("discord.js").VoiceChannel, {
39
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
40
- }> | Extract<import("discord.js").ForumChannel, {
41
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
42
- }> | Extract<import("discord.js").MediaChannel, {
43
- type: T | (T extends readonly (infer InnerArr)[] ? InnerArr : T);
44
- }>, "required">;
26
+ channel: () => ChannelOption<import("discord.js").GuildBasedChannel, "required", z.ZodType<import("discord.js").GuildBasedChannel, import("discord.js").GuildBasedChannel, z.core.$ZodTypeInternals<import("discord.js").GuildBasedChannel, import("discord.js").GuildBasedChannel>>>;
45
27
  /**
46
28
  * A choice for a command option.
47
29
  * @param name The name of the choice.
@@ -51,27 +33,27 @@ export declare const o: {
51
33
  /**
52
34
  * A command integer option.
53
35
  */
54
- integer: () => IntegerOption<number, "required">;
36
+ integer: () => IntegerOption<number, "required", z.ZodType<number, number, z.core.$ZodTypeInternals<number, number>>>;
55
37
  /**
56
38
  * A command number option.
57
39
  */
58
- number: () => NumberOption<number, "required">;
40
+ number: () => NumberOption<number, "required", z.ZodType<number, number, z.core.$ZodTypeInternals<number, number>>>;
59
41
  /**
60
42
  * A command mentionable option.
61
43
  */
62
- mentionable: () => MentionableOption<import("discord.js").GuildMember | import("discord.js").User | import("discord.js").Role, "required">;
44
+ mentionable: () => MentionableOption<import("discord.js").User | import("discord.js").GuildMember | import("discord.js").Role, "required", z.ZodType<import("discord.js").User | import("discord.js").GuildMember | import("discord.js").Role, import("discord.js").User | import("discord.js").GuildMember | import("discord.js").Role, z.core.$ZodTypeInternals<import("discord.js").User | import("discord.js").GuildMember | import("discord.js").Role, import("discord.js").User | import("discord.js").GuildMember | import("discord.js").Role>>>;
63
45
  /**
64
46
  * A command role option.
65
47
  */
66
- role: () => RoleOption<import("discord.js").Role, "required">;
48
+ role: () => RoleOption<import("discord.js").Role, "required", z.ZodType<import("discord.js").Role, import("discord.js").Role, z.core.$ZodTypeInternals<import("discord.js").Role, import("discord.js").Role>>>;
67
49
  /**
68
50
  * A command string option.
69
51
  */
70
- string: () => StringOption<string, "required">;
52
+ string: () => StringOption<string, "required", z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>;
71
53
  /**
72
54
  * A command user option.
73
55
  */
74
- user: () => UserOption<import("discord.js").User, "required">;
56
+ user: () => UserOption<import("discord.js").User, "required", z.ZodType<import("discord.js").User, import("discord.js").User, z.core.$ZodTypeInternals<import("discord.js").User, import("discord.js").User>>>;
75
57
  /**
76
58
  * Allows not specifying an option for a command.
77
59
  * @param option The option to make optional.
@@ -112,5 +94,5 @@ type RequiredKeys<Options extends Record<string, GenericOption>> = Exclude<keyof
112
94
  *
113
95
  * @public
114
96
  */
115
- export type Infer<T extends Option<any, OptionalType>> = T["type"];
97
+ export type Infer<T extends Option<any, OptionalType>> = T["validator"] extends z.ZodType<infer Type> ? Type : T["type"];
116
98
  export {};
@@ -1,15 +1,10 @@
1
1
  import { SlashCommandAttachmentOption, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption } from "discord.js";
2
- import { AttachmentOption, BooleanOption, BuilderOption, ChannelOption, Choice, IntegerOption, MentionableOption, NumberOption, RoleOption, StringOption, UserOption } from "./options.js";
2
+ import { AttachmentOption, BooleanOption, ChannelOption, Choice, IntegerOption, MentionableOption, NumberOption, RoleOption, StringOption, UserOption } from "./options.js";
3
3
  export function optionsToJson(options) {
4
- return Object.entries(options)
5
- .map(([name, option]) => {
6
- if (option instanceof BuilderOption) {
7
- const builder = option.getBuilder();
8
- return builder.setName(name).toJSON();
9
- }
10
- return null;
11
- })
12
- .filter((json) => json !== null);
4
+ return Object.entries(options).map(([name, option]) => {
5
+ const builder = option.getBuilder();
6
+ return builder.setName(name).toJSON();
7
+ });
13
8
  }
14
9
  /**
15
10
  * The option builder.
@@ -33,11 +28,9 @@ export const o = {
33
28
  },
34
29
  /**
35
30
  * A command channel option.
36
- * @param channelTypes The channel types.
37
31
  */
38
- channel: (...channelTypes) => {
39
- const option = new ChannelOption(new SlashCommandChannelOption(), "required");
40
- return option.union(channelTypes.flat());
32
+ channel: () => {
33
+ return new ChannelOption(new SlashCommandChannelOption(), "required");
41
34
  },
42
35
  /**
43
36
  * A choice for a command option.
@@ -98,4 +91,3 @@ export const o = {
98
91
  return option.asOptional();
99
92
  }
100
93
  };
101
- //# sourceMappingURL=option.js.map
@@ -1,34 +1,37 @@
1
1
  import { SlashCommandAttachmentOption, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption, type APIApplicationCommandOptionChoice, type ApplicationCommandNumericOptionMinMaxValueMixin, type ApplicationCommandOptionAllowedChannelTypes, type ApplicationCommandOptionBase, type ApplicationCommandOptionWithAutocompleteMixin, type ApplicationCommandOptionWithChoicesMixin, type Attachment, type GuildBasedChannel, type GuildMember, type LocalizationMap, type RestOrArray, type Role, type User } from "discord.js";
2
- declare abstract class BaseOption<Type, IsOptional extends OptionalType = "required"> {
2
+ import type * as z from "zod";
3
+ export declare abstract class BaseOption<Builder extends ApplicationCommandOptionBase, Type, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> {
4
+ readonly isOptional: IsOptional;
5
+ readonly validator: Validator | undefined;
3
6
  /**
4
7
  * Only for Typescript.
5
8
  */
6
9
  readonly type: Type;
7
- readonly isOptional: IsOptional;
8
- constructor(isOptional: IsOptional);
9
- }
10
- export declare abstract class BuilderOption<Builder extends ApplicationCommandOptionBase, Type, IsOptional extends OptionalType = "required"> extends BaseOption<Type, IsOptional> {
11
10
  protected builder: Builder;
12
- constructor(builder: Builder, isOptional: IsOptional);
11
+ constructor(builder: Builder, isOptional: IsOptional, validator: Validator | undefined);
13
12
  describe(description: string): this;
14
13
  localize({ name, description }: {
15
14
  name?: LocalizationMap;
16
15
  description?: LocalizationMap;
17
16
  }): this;
17
+ abstract validate<T extends z.ZodType<any, Type>>(validator: T): Option<Type, IsOptional, T>;
18
18
  }
19
- export declare class AttachmentOption<Type = Attachment, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandAttachmentOption, Type, IsOptional> {
20
- constructor(builder: SlashCommandAttachmentOption, isOptional: IsOptional);
19
+ export declare class AttachmentOption<Type = Attachment, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandAttachmentOption, Type, IsOptional, Validator> {
20
+ constructor(builder: SlashCommandAttachmentOption, isOptional: IsOptional, validator?: Validator);
21
+ validate<T extends z.ZodType<any, Type>>(validator: T): AttachmentOption<Type, IsOptional, T>;
21
22
  }
22
- export declare class BooleanOption<Type = boolean, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandBooleanOption, Type, IsOptional> {
23
- constructor(builder: SlashCommandBooleanOption, isOptional: IsOptional);
23
+ export declare class BooleanOption<Type = boolean, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandBooleanOption, Type, IsOptional, Validator> {
24
+ constructor(builder: SlashCommandBooleanOption, isOptional: IsOptional, validator?: Validator);
25
+ validate<T extends z.ZodType<any, Type>>(validator: T): BooleanOption<Type, IsOptional, T>;
24
26
  }
25
- export declare class ChannelOption<Type = GuildBasedChannel, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandChannelOption, Type, IsOptional> {
26
- constructor(builder: SlashCommandChannelOption, isOptional: IsOptional);
27
- union<T extends ApplicationCommandOptionAllowedChannelTypes>(channelTypes: T[]): ChannelOption<Extract<GuildBasedChannel, {
27
+ export declare class ChannelOption<Type = GuildBasedChannel, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandChannelOption, Type, IsOptional, Validator> {
28
+ constructor(builder: SlashCommandChannelOption, isOptional: IsOptional, validator?: Validator);
29
+ narrow<T extends ApplicationCommandOptionAllowedChannelTypes>(channelTypes: T[]): ChannelOption<Extract<GuildBasedChannel, {
28
30
  type: T;
29
31
  }>, IsOptional>;
32
+ validate<T extends z.ZodType<any, Type>>(validator: T): ChannelOption<Type, IsOptional, T>;
30
33
  }
31
- declare abstract class AutocompleteOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin, Type, IsOptional extends OptionalType = "required"> extends BuilderOption<Builder, Type, IsOptional> {
34
+ declare abstract class AutocompleteOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin, Type, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<Builder, Type, IsOptional, Validator> {
32
35
  autocomplete(autocomplete?: boolean): this;
33
36
  }
34
37
  export declare class Choice<Type extends number | string> {
@@ -39,40 +42,46 @@ export declare class Choice<Type extends number | string> {
39
42
  }): this;
40
43
  }
41
44
  type InferChoiceType<T extends ApplicationCommandOptionWithChoicesMixin<any>> = T extends ApplicationCommandOptionWithChoicesMixin<infer Type> ? Type : never;
42
- declare abstract class ChoicesOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<any>, Type, IsOptional extends OptionalType = "required"> extends AutocompleteOption<Builder, Type, IsOptional> {
45
+ declare abstract class ChoicesOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<any>, Type, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends AutocompleteOption<Builder, Type, IsOptional, Validator> {
43
46
  abstract union<UnionType extends InferChoiceType<Builder>>(...choices: RestOrArray<Choice<UnionType>>): Option<UnionType, IsOptional>;
44
47
  }
45
- declare abstract class NumbericOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandNumericOptionMinMaxValueMixin & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<number>, Type = number, IsOptional extends OptionalType = "required"> extends ChoicesOption<Builder, Type, IsOptional> {
48
+ declare abstract class NumbericOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandNumericOptionMinMaxValueMixin & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<number>, Type = number, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends ChoicesOption<Builder, Type, IsOptional, Validator> {
46
49
  min(min: number): this;
47
50
  max(max: number): this;
48
51
  }
49
- export declare class IntegerOption<Type = number, IsOptional extends OptionalType = "required"> extends NumbericOption<SlashCommandIntegerOption, Type, IsOptional> {
50
- constructor(builder: SlashCommandIntegerOption, isOptional: IsOptional);
52
+ export declare class IntegerOption<Type = number, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends NumbericOption<SlashCommandIntegerOption, Type, IsOptional, Validator> {
53
+ constructor(builder: SlashCommandIntegerOption, isOptional: IsOptional, validator?: Validator);
51
54
  union<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>): IntegerOption<UnionType, IsOptional>;
55
+ validate<T extends z.ZodType<any, Type>>(validator: T): IntegerOption<Type, IsOptional, T>;
52
56
  }
53
- export declare class NumberOption<Type = number, IsOptional extends OptionalType = "required"> extends NumbericOption<SlashCommandNumberOption, Type, IsOptional> {
54
- constructor(builder: SlashCommandNumberOption, isOptional: IsOptional);
57
+ export declare class NumberOption<Type = number, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends NumbericOption<SlashCommandNumberOption, Type, IsOptional, Validator> {
58
+ constructor(builder: SlashCommandNumberOption, isOptional: IsOptional, validator?: Validator);
55
59
  union<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>): NumberOption<UnionType, IsOptional>;
60
+ validate<T extends z.ZodType<any, Type>>(validator: T): NumberOption<Type, IsOptional, T>;
56
61
  }
57
- export declare class MentionableOption<Type = User | GuildMember | Role, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandMentionableOption, Type, IsOptional> {
58
- constructor(builder: SlashCommandMentionableOption, isOptional: IsOptional);
62
+ export declare class MentionableOption<Type = User | GuildMember | Role, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandMentionableOption, Type, IsOptional, Validator> {
63
+ constructor(builder: SlashCommandMentionableOption, isOptional: IsOptional, validator?: Validator);
64
+ validate<T extends z.ZodType<any, Type>>(validator: T): MentionableOption<Type, IsOptional, T>;
59
65
  }
60
- export declare class RoleOption<Type = Role, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandRoleOption, Type, IsOptional> {
61
- constructor(builder: SlashCommandRoleOption, isOptional: IsOptional);
66
+ export declare class RoleOption<Type = Role, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandRoleOption, Type, IsOptional, Validator> {
67
+ constructor(builder: SlashCommandRoleOption, isOptional: IsOptional, validator?: Validator);
68
+ validate<T extends z.ZodType<any, Type>>(validator: T): RoleOption<Type, IsOptional, T>;
62
69
  }
63
- export declare class StringOption<Type = string, IsOptional extends OptionalType = "required"> extends ChoicesOption<SlashCommandStringOption, Type, IsOptional> {
64
- constructor(builder: SlashCommandStringOption, isOptional: IsOptional);
70
+ export declare class StringOption<Type = string, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends ChoicesOption<SlashCommandStringOption, Type, IsOptional, Validator> {
71
+ constructor(builder: SlashCommandStringOption, isOptional: IsOptional, validator?: Validator);
65
72
  min(min: number): this;
66
73
  max(max: number): this;
67
74
  union<UnionType extends string>(...choices: RestOrArray<Choice<UnionType>>): StringOption<UnionType, IsOptional>;
75
+ validate<T extends z.ZodType<any, Type>>(validator: T): StringOption<Type, IsOptional, T>;
68
76
  }
69
- export declare class UserOption<Type = User, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandUserOption, Type, IsOptional> {
70
- constructor(builder: SlashCommandUserOption, isOptional: IsOptional);
77
+ export declare class UserOption<Type = User, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> extends BaseOption<SlashCommandUserOption, Type, IsOptional, Validator> {
78
+ constructor(builder: SlashCommandUserOption, isOptional: IsOptional, validator?: Validator);
79
+ validate<T extends z.ZodType<any, Type>>(validator: T): UserOption<Type, IsOptional, T>;
71
80
  }
72
81
  /**
73
82
  * A type representing whether an option is optional or not.
74
83
  */
75
84
  export type OptionalType = "required" | "optional";
76
- export type AsOptional<T extends Option<any, OptionalType>> = T extends AttachmentOption<infer Type, OptionalType> ? AttachmentOption<Type, "optional"> : T extends BooleanOption<infer Type, OptionalType> ? BooleanOption<Type, "optional"> : T extends ChannelOption<infer Type, OptionalType> ? ChannelOption<Type, "optional"> : T extends IntegerOption<infer Type, OptionalType> ? IntegerOption<Type, "optional"> : T extends NumberOption<infer Type, OptionalType> ? NumberOption<Type, "optional"> : T extends MentionableOption<infer Type, OptionalType> ? MentionableOption<Type, "optional"> : T extends RoleOption<infer Type, OptionalType> ? RoleOption<Type, "optional"> : T extends StringOption<infer Type, OptionalType> ? StringOption<Type, "optional"> : T extends UserOption<infer Type, OptionalType> ? UserOption<Type, "optional"> : never;
77
- export type Option<Type, IsOptional extends OptionalType = "required"> = AttachmentOption<Type, IsOptional> | BooleanOption<Type, IsOptional> | ChannelOption<Type, IsOptional> | IntegerOption<Type, IsOptional> | NumberOption<Type, IsOptional> | MentionableOption<Type, IsOptional> | RoleOption<Type, IsOptional> | StringOption<Type, IsOptional> | UserOption<Type, IsOptional>;
85
+ export type AsOptional<T extends Option<any, OptionalType>> = T extends AttachmentOption<infer Type, OptionalType, infer Validator> ? AttachmentOption<Type, "optional", Validator> : T extends BooleanOption<infer Type, OptionalType, infer Validator> ? BooleanOption<Type, "optional", Validator> : T extends ChannelOption<infer Type, OptionalType, infer Validator> ? ChannelOption<Type, "optional", Validator> : T extends IntegerOption<infer Type, OptionalType, infer Validator> ? IntegerOption<Type, "optional", Validator> : T extends NumberOption<infer Type, OptionalType, infer Validator> ? NumberOption<Type, "optional", Validator> : T extends MentionableOption<infer Type, OptionalType, infer Validator> ? MentionableOption<Type, "optional", Validator> : T extends RoleOption<infer Type, OptionalType, infer Validator> ? RoleOption<Type, "optional", Validator> : T extends StringOption<infer Type, OptionalType, infer Validator> ? StringOption<Type, "optional", Validator> : T extends UserOption<infer Type, OptionalType, infer Validator> ? UserOption<Type, "optional", Validator> : never;
86
+ export type Option<Type, IsOptional extends OptionalType = "required", Validator extends z.ZodType<any, Type> = z.ZodType<Type, Type>> = AttachmentOption<Type, IsOptional, Validator> | BooleanOption<Type, IsOptional, Validator> | ChannelOption<Type, IsOptional, Validator> | IntegerOption<Type, IsOptional, Validator> | NumberOption<Type, IsOptional, Validator> | MentionableOption<Type, IsOptional, Validator> | RoleOption<Type, IsOptional, Validator> | StringOption<Type, IsOptional, Validator> | UserOption<Type, IsOptional, Validator>;
78
87
  export {};