spearkit 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context.ts","../src/commands/options.ts","../src/commands/context.ts","../src/commands/command.ts","../src/commands/registry.ts","../src/events.ts","../src/components/customId.ts","../src/components/context.ts","../src/components/registry.ts","../src/components/builders.ts","../src/components/row.ts","../src/loader.ts","../src/client.ts","../src/plugin.ts"],"names":["modal","ApplicationCommandOptionType","command","MessageFlags","toError","ActionRowBuilder"],"mappings":"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","file":"index.js","sourcesContent":["import {\n MessageFlags,\n type InteractionEditReplyOptions,\n type InteractionReplyOptions,\n type InteractionResponse,\n type Message,\n type RepliableInteraction,\n} from \"discord.js\";\n\n/** Reply options with an ergonomic `ephemeral` shortcut (mapped to flags). */\nexport type ReplyData = InteractionReplyOptions & { ephemeral?: boolean };\n\n/** Either a plain string or full reply options. */\nexport type ReplyInput = string | ReplyData;\n\ntype Flags = InteractionReplyOptions[\"flags\"];\n\nfunction withEphemeralFlag(flags: Flags): Flags {\n if (flags == null) return MessageFlags.Ephemeral;\n if (typeof flags === \"number\" || typeof flags === \"bigint\") {\n return Number(flags) | MessageFlags.Ephemeral;\n }\n if (Array.isArray(flags)) return [...flags, MessageFlags.Ephemeral] as Flags;\n return [flags, MessageFlags.Ephemeral] as Flags;\n}\n\n/** Normalises spearkit reply input into a discord.js reply payload. */\nexport function normalizeReply(input: ReplyInput): InteractionReplyOptions {\n if (typeof input === \"string\") return { content: input };\n const { ephemeral, ...rest } = input;\n if (ephemeral) return { ...rest, flags: withEphemeralFlag(rest.flags) };\n return rest;\n}\n\nfunction normalizeEdit(input: ReplyInput): InteractionEditReplyOptions {\n if (typeof input === \"string\") return { content: input };\n const { ephemeral: _ephemeral, flags: _flags, ...rest } = input;\n return rest;\n}\n\n/** Marks an input as ephemeral, regardless of how it was passed. */\nexport function asEphemeral(input: ReplyInput): ReplyData {\n if (typeof input === \"string\") return { content: input, ephemeral: true };\n return { ...input, ephemeral: true };\n}\n\n/**\n * Ergonomic base wrapper shared by every interaction context (commands,\n * buttons, selects, modals). Exposes the common actor/location accessors plus\n * reply helpers that smooth over discord.js' state machine.\n */\nexport abstract class BaseContext<I extends RepliableInteraction = RepliableInteraction> {\n constructor(readonly interaction: I) {}\n\n get client(): I[\"client\"] {\n return this.interaction.client;\n }\n get user() {\n return this.interaction.user;\n }\n get member() {\n return this.interaction.member;\n }\n get guild() {\n return this.interaction.guild;\n }\n get guildId() {\n return this.interaction.guildId;\n }\n get channel() {\n return this.interaction.channel;\n }\n get channelId() {\n return this.interaction.channelId;\n }\n get locale() {\n return this.interaction.locale;\n }\n /** Whether the interaction is already deferred. */\n get deferred() {\n return this.interaction.deferred;\n }\n /** Whether the interaction already received an initial response. */\n get replied() {\n return this.interaction.replied;\n }\n\n /** Send the initial response to the interaction. */\n reply(input: ReplyInput): Promise<InteractionResponse<boolean>> {\n return this.interaction.reply(normalizeReply(input));\n }\n\n /** Reply, but always hidden to everyone except the invoking user. */\n replyEphemeral(input: ReplyInput): Promise<InteractionResponse<boolean>> {\n return this.reply(asEphemeral(input));\n }\n\n /** Acknowledge now and respond later via {@link editReply}. */\n defer(options: { ephemeral?: boolean } = {}): Promise<InteractionResponse<boolean>> {\n return this.interaction.deferReply(\n options.ephemeral ? { flags: MessageFlags.Ephemeral } : {},\n );\n }\n\n /** Edit the original (or deferred) response. */\n editReply(input: ReplyInput): Promise<Message> {\n return this.interaction.editReply(normalizeEdit(input));\n }\n\n /** Add an additional message after the initial response. */\n followUp(input: ReplyInput): Promise<Message> {\n return this.interaction.followUp(normalizeReply(input));\n }\n\n /**\n * State-aware send: replies, edits a deferred response, or follows up —\n * whichever is valid given the current interaction state. The single method\n * most handlers ever need.\n */\n async send(input: ReplyInput): Promise<void> {\n if (this.interaction.deferred) {\n await this.editReply(input);\n } else if (this.interaction.replied) {\n await this.followUp(input);\n } else {\n await this.reply(input);\n }\n }\n\n /** State-aware ephemeral error message. */\n error(message: string): Promise<void> {\n return this.send(asEphemeral(message));\n }\n}\n","import {\n ApplicationCommandOptionType,\n type APIApplicationCommandBasicOption,\n type APIApplicationCommandChannelOption,\n type APIApplicationCommandOptionChoice,\n type Attachment,\n type Awaitable,\n type ChatInputCommandInteraction,\n type CommandInteractionOption,\n type LocalizationMap,\n} from \"discord.js\";\nimport type { AutocompleteContext } from \"./context.js\";\n\n/**\n * Resolved runtime value types, derived directly from discord.js' option\n * resolver so spearkit stays exactly in lockstep with the underlying getters.\n */\ntype Opt = CommandInteractionOption;\ntype UserValue = NonNullable<Opt[\"user\"]>;\ntype ChannelValue = NonNullable<Opt[\"channel\"]>;\ntype RoleValue = NonNullable<Opt[\"role\"]>;\ntype MentionableValue = NonNullable<Opt[\"user\" | \"role\" | \"member\"]>;\ntype AttachmentValue = Attachment;\n\n/** The discord-allowed channel types for a channel option. */\nexport type AllowedChannelType = NonNullable<APIApplicationCommandChannelOption[\"channel_types\"]>[number];\n\n/** The reader surface spearkit needs off a chat-input interaction. */\ntype OptionReader = ChatInputCommandInteraction[\"options\"];\n\n/** The closed set of values a slash option can resolve to. */\nexport type OptionValue =\n | string\n | number\n | boolean\n | UserValue\n | ChannelValue\n | RoleValue\n | MentionableValue\n | AttachmentValue;\n\n/** A single choice for string/integer/number options. */\nexport interface OptionChoice<V extends string | number = string | number> {\n readonly name: string;\n readonly value: V;\n readonly nameLocalizations?: LocalizationMap;\n}\n\n/** Provides autocomplete suggestions for an option as the user types. */\nexport type AutocompleteHandler<V extends string | number = string | number> = (\n ctx: AutocompleteContext,\n) => Awaitable<OptionChoice<V>[]>;\n\n/**\n * A fully-described slash command option. The two type parameters are phantom\n * markers used purely for compile-time inference of the resolved value:\n * - `TValue` is the type produced for the command handler.\n * - `TRequired` controls nullability (`true` => value, `false` => `| undefined`).\n */\nexport interface OptionDef<TValue extends OptionValue, TRequired extends boolean> {\n readonly type: ApplicationCommandOptionType;\n readonly description: string;\n readonly required: TRequired;\n readonly choices?: readonly OptionChoice[];\n readonly minValue?: number;\n readonly maxValue?: number;\n readonly minLength?: number;\n readonly maxLength?: number;\n readonly channelTypes?: readonly AllowedChannelType[];\n readonly autocomplete?: AutocompleteHandler;\n readonly nameLocalizations?: LocalizationMap;\n readonly descriptionLocalizations?: LocalizationMap;\n /** Phantom-only marker. Never populated at runtime. */\n readonly __value?: TValue;\n}\n\n/** Any option definition, regardless of value/required type. */\nexport type AnyOptionDef = OptionDef<OptionValue, boolean>;\n\n/** A map of option name => definition. */\nexport type OptionMap = Record<string, AnyOptionDef>;\n\n/** Maps an {@link OptionDef} to the value passed into the command handler. */\nexport type ResolvedOption<O extends AnyOptionDef> = O extends OptionDef<infer V, infer Req>\n ? Req extends true\n ? V\n : V | undefined\n : never;\n\n/** Resolves a whole {@link OptionMap} into the handler's `options` object. */\nexport type ResolvedOptions<O extends OptionMap> = {\n [K in keyof O]: ResolvedOption<O[K]>;\n};\n\n// --- builder config shapes -------------------------------------------------\n\ninterface BaseConfig {\n readonly description: string;\n readonly required?: boolean;\n readonly nameLocalizations?: LocalizationMap;\n readonly descriptionLocalizations?: LocalizationMap;\n}\n\ntype IsRequired<C extends BaseConfig> = C[\"required\"] extends true ? true : false;\n\ninterface StringConfig extends BaseConfig {\n readonly choices?: readonly OptionChoice<string>[];\n readonly minLength?: number;\n readonly maxLength?: number;\n readonly autocomplete?: AutocompleteHandler<string>;\n}\n\ninterface NumericConfig extends BaseConfig {\n readonly choices?: readonly OptionChoice<number>[];\n readonly minValue?: number;\n readonly maxValue?: number;\n readonly autocomplete?: AutocompleteHandler<number>;\n}\n\ninterface ChannelConfig extends BaseConfig {\n readonly channelTypes?: readonly AllowedChannelType[];\n}\n\ntype ChoiceValue<C, Fallback extends string | number> = C extends {\n readonly choices: readonly { value: infer V }[];\n}\n ? [V] extends [string | number]\n ? V\n : Fallback\n : Fallback;\n\n/**\n * The single boundary assertion in the option system: the runtime `required`\n * value is a wide `boolean`, but the public type narrows it to the literal the\n * caller supplied. Centralised so every builder stays otherwise cast-free.\n */\nfunction makeOption<TValue extends OptionValue, C extends BaseConfig>(\n type: ApplicationCommandOptionType,\n config: C,\n): OptionDef<TValue, IsRequired<C>> {\n return { type, ...config, required: (config.required ?? false) as IsRequired<C> };\n}\n\n/**\n * Type-safe slash command option builders.\n *\n * @example\n * ```ts\n * options: {\n * target: option.user({ description: \"Who to greet\", required: true }),\n * loud: option.boolean({ description: \"Shout it\" }),\n * }\n * ```\n */\nexport const option = {\n string<const C extends StringConfig>(config: C): OptionDef<ChoiceValue<C, string>, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.String, config);\n },\n integer<const C extends NumericConfig>(config: C): OptionDef<ChoiceValue<C, number>, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Integer, config);\n },\n number<const C extends NumericConfig>(config: C): OptionDef<ChoiceValue<C, number>, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Number, config);\n },\n boolean<const C extends BaseConfig>(config: C): OptionDef<boolean, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Boolean, config);\n },\n user<const C extends BaseConfig>(config: C): OptionDef<UserValue, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.User, config);\n },\n channel<const C extends ChannelConfig>(config: C): OptionDef<ChannelValue, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Channel, config);\n },\n role<const C extends BaseConfig>(config: C): OptionDef<RoleValue, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Role, config);\n },\n mentionable<const C extends BaseConfig>(config: C): OptionDef<MentionableValue, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Mentionable, config);\n },\n attachment<const C extends BaseConfig>(config: C): OptionDef<AttachmentValue, IsRequired<C>> {\n return makeOption(ApplicationCommandOptionType.Attachment, config);\n },\n} as const;\n\nfunction mapChoices<V extends string | number>(\n choices: readonly OptionChoice[] | undefined,\n): APIApplicationCommandOptionChoice<V>[] | undefined {\n return choices?.map((c) => ({\n name: c.name,\n value: c.value as V,\n name_localizations: c.nameLocalizations,\n }));\n}\n\n/** Converts a spearkit option definition into the discord REST option payload. */\nexport function toAPIOption(name: string, def: AnyOptionDef): APIApplicationCommandBasicOption {\n const shared = {\n name,\n description: def.description,\n required: def.required,\n name_localizations: def.nameLocalizations,\n description_localizations: def.descriptionLocalizations,\n };\n\n switch (def.type) {\n case ApplicationCommandOptionType.String: {\n const base = { ...shared, min_length: def.minLength, max_length: def.maxLength };\n return def.autocomplete !== undefined\n ? { ...base, type: ApplicationCommandOptionType.String, autocomplete: true }\n : { ...base, type: ApplicationCommandOptionType.String, choices: mapChoices<string>(def.choices) };\n }\n case ApplicationCommandOptionType.Integer: {\n const base = { ...shared, min_value: def.minValue, max_value: def.maxValue };\n return def.autocomplete !== undefined\n ? { ...base, type: ApplicationCommandOptionType.Integer, autocomplete: true }\n : { ...base, type: ApplicationCommandOptionType.Integer, choices: mapChoices<number>(def.choices) };\n }\n case ApplicationCommandOptionType.Number: {\n const base = { ...shared, min_value: def.minValue, max_value: def.maxValue };\n return def.autocomplete !== undefined\n ? { ...base, type: ApplicationCommandOptionType.Number, autocomplete: true }\n : { ...base, type: ApplicationCommandOptionType.Number, choices: mapChoices<number>(def.choices) };\n }\n case ApplicationCommandOptionType.Channel:\n return {\n ...shared,\n type: ApplicationCommandOptionType.Channel,\n channel_types: def.channelTypes ? [...def.channelTypes] : undefined,\n };\n case ApplicationCommandOptionType.User:\n return { ...shared, type: ApplicationCommandOptionType.User };\n case ApplicationCommandOptionType.Boolean:\n return { ...shared, type: ApplicationCommandOptionType.Boolean };\n case ApplicationCommandOptionType.Role:\n return { ...shared, type: ApplicationCommandOptionType.Role };\n case ApplicationCommandOptionType.Mentionable:\n return { ...shared, type: ApplicationCommandOptionType.Mentionable };\n case ApplicationCommandOptionType.Attachment:\n return { ...shared, type: ApplicationCommandOptionType.Attachment };\n default:\n return { ...shared, type: ApplicationCommandOptionType.String };\n }\n}\n\n/** Reads a resolved option value off a discord.js option resolver. */\nexport function readOption(\n resolver: OptionReader,\n name: string,\n def: AnyOptionDef,\n): OptionValue | undefined {\n switch (def.type) {\n case ApplicationCommandOptionType.String:\n return resolver.getString(name) ?? undefined;\n case ApplicationCommandOptionType.Integer:\n return resolver.getInteger(name) ?? undefined;\n case ApplicationCommandOptionType.Number:\n return resolver.getNumber(name) ?? undefined;\n case ApplicationCommandOptionType.Boolean:\n return resolver.getBoolean(name) ?? undefined;\n case ApplicationCommandOptionType.User:\n return resolver.getUser(name) ?? undefined;\n case ApplicationCommandOptionType.Channel:\n return resolver.getChannel(name) ?? undefined;\n case ApplicationCommandOptionType.Role:\n return resolver.getRole(name) ?? undefined;\n case ApplicationCommandOptionType.Mentionable:\n return resolver.getMentionable(name) ?? undefined;\n case ApplicationCommandOptionType.Attachment:\n return resolver.getAttachment(name) ?? undefined;\n default:\n return undefined;\n }\n}\n\n/** True if any option in the map declares an autocomplete handler. */\nexport function optionsHaveAutocomplete(options: OptionMap): boolean {\n for (const def of Object.values(options)) {\n if (def.autocomplete !== undefined) return true;\n }\n return false;\n}\n","import type {\n AutocompleteInteraction,\n ChatInputCommandInteraction,\n JSONEncodable,\n ModalComponentData,\n ModalBuilder,\n APIModalInteractionResponseCallbackData,\n} from \"discord.js\";\nimport { BaseContext } from \"../context.js\";\nimport type { OptionChoice, OptionMap, ResolvedOptions } from \"./options.js\";\n\n/**\n * The handler argument for a slash command. Wraps the discord.js interaction\n * and exposes the resolved, fully-typed {@link options}.\n */\nexport class CommandContext<O extends OptionMap = OptionMap> extends BaseContext<ChatInputCommandInteraction> {\n constructor(\n interaction: ChatInputCommandInteraction,\n /** Resolved option values, typed from the command's `options` map. */\n readonly options: ResolvedOptions<O>,\n ) {\n super(interaction);\n }\n\n get commandName(): string {\n return this.interaction.commandName;\n }\n\n /** The invoked subcommand name, if any. */\n get subcommand(): string | null {\n return this.interaction.options.getSubcommand(false);\n }\n\n /** Present a modal to the user in response to this command. */\n async showModal(\n modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData | ModalBuilder,\n ): Promise<void> {\n await this.interaction.showModal(modal);\n }\n}\n\n/**\n * The handler argument for autocomplete requests. Provides the focused value\n * and a typed {@link respond} helper.\n */\nexport class AutocompleteContext {\n constructor(readonly interaction: AutocompleteInteraction) {}\n\n get client() {\n return this.interaction.client;\n }\n get user() {\n return this.interaction.user;\n }\n get guild() {\n return this.interaction.guild;\n }\n get guildId() {\n return this.interaction.guildId;\n }\n get commandName(): string {\n return this.interaction.commandName;\n }\n\n /** Name of the option currently being completed. */\n get focusedName(): string {\n return this.interaction.options.getFocused(true).name;\n }\n\n /** Current partial value typed by the user. */\n get value(): string {\n return this.interaction.options.getFocused();\n }\n\n /** Send autocomplete suggestions (capped at the discord limit of 25). */\n respond(choices: OptionChoice<string | number>[]): Promise<void> {\n return this.interaction.respond(\n choices.slice(0, 25).map((c) => ({\n name: c.name,\n value: c.value,\n name_localizations: c.nameLocalizations,\n })),\n );\n }\n}\n","import {\n ApplicationCommandOptionType,\n ApplicationCommandType,\n InteractionContextType,\n PermissionsBitField,\n type APIApplicationCommandSubcommandGroupOption,\n type APIApplicationCommandSubcommandOption,\n type AutocompleteInteraction,\n type Awaitable,\n type ChatInputCommandInteraction,\n type LocalizationMap,\n type PermissionResolvable,\n type RESTPostAPIChatInputApplicationCommandsJSONBody,\n} from \"discord.js\";\nimport { AutocompleteContext, CommandContext } from \"./context.js\";\nimport {\n optionsHaveAutocomplete,\n readOption,\n toAPIOption,\n type OptionMap,\n type OptionValue,\n type ResolvedOptions,\n} from \"./options.js\";\n\n/** Metadata shared by every kind of command. */\ninterface CommonMeta {\n /** Permissions a member must have by default to see/use the command. */\n defaultMemberPermissions?: PermissionResolvable | null;\n /** Mark the command NSFW (age-restricted). */\n nsfw?: boolean;\n /** Restrict invocation to guilds only. */\n guildOnly?: boolean;\n nameLocalizations?: LocalizationMap;\n descriptionLocalizations?: LocalizationMap;\n}\n\n/** Configuration for a leaf (non-subcommand) slash command. */\nexport interface CommandConfig<O extends OptionMap, R> extends CommonMeta {\n name: string;\n description: string;\n options?: O;\n run: (ctx: CommandContext<O>) => Awaitable<R>;\n}\n\n/** Configuration for one subcommand. */\nexport interface SubcommandConfig<O extends OptionMap, R> {\n description: string;\n options?: O;\n nameLocalizations?: LocalizationMap;\n descriptionLocalizations?: LocalizationMap;\n run: (ctx: CommandContext<O>) => Awaitable<R>;\n}\n\n/** A type-erased, ready-to-run subcommand created with {@link subcommand}. */\nexport interface Subcommand {\n readonly kind: \"subcommand\";\n readonly description: string;\n readonly options: OptionMap;\n readonly nameLocalizations?: LocalizationMap;\n readonly descriptionLocalizations?: LocalizationMap;\n readonly hasAutocomplete: boolean;\n readonly execute: (interaction: ChatInputCommandInteraction) => Promise<void>;\n readonly autocomplete: (interaction: AutocompleteInteraction) => Promise<void>;\n}\n\n/** Configuration for a subcommand group (a folder of subcommands). */\nexport interface SubcommandGroupConfig {\n description: string;\n subcommands: Record<string, Subcommand>;\n nameLocalizations?: LocalizationMap;\n descriptionLocalizations?: LocalizationMap;\n}\n\n/** A subcommand group created with {@link subcommandGroup}. */\nexport interface SubcommandGroup extends SubcommandGroupConfig {\n readonly kind: \"group\";\n}\n\n/** Configuration for a command that contains subcommands and/or groups. */\nexport interface CommandGroupConfig extends CommonMeta {\n name: string;\n description: string;\n subcommands?: Record<string, Subcommand>;\n groups?: Record<string, SubcommandGroup>;\n}\n\n/** Everything {@link SlashCommand} needs, pre-built by the factories. */\ninterface SlashCommandSpec {\n name: string;\n json: RESTPostAPIChatInputApplicationCommandsJSONBody;\n hasAutocomplete: boolean;\n executor: (interaction: ChatInputCommandInteraction) => Promise<void>;\n autocompleter: (interaction: AutocompleteInteraction) => Promise<void>;\n}\n\n/**\n * A registered slash command. Serialises itself for the discord REST API and\n * executes its matching interactions. Construct via {@link command} or\n * {@link commandGroup} rather than directly.\n */\nexport class SlashCommand {\n /** The top-level command name (used as the registry lookup key). */\n readonly name: string;\n /** Whether any option declares an autocomplete handler. */\n readonly hasAutocomplete: boolean;\n private readonly json: RESTPostAPIChatInputApplicationCommandsJSONBody;\n private readonly executor: (interaction: ChatInputCommandInteraction) => Promise<void>;\n private readonly autocompleter: (interaction: AutocompleteInteraction) => Promise<void>;\n\n /** @internal */\n constructor(spec: SlashCommandSpec) {\n this.name = spec.name;\n this.hasAutocomplete = spec.hasAutocomplete;\n this.json = spec.json;\n this.executor = spec.executor;\n this.autocompleter = spec.autocompleter;\n }\n\n /** Serialise to the discord REST chat-input command payload. */\n toJSON(): RESTPostAPIChatInputApplicationCommandsJSONBody {\n return this.json;\n }\n\n /** Execute the command for an incoming chat-input interaction. */\n execute(interaction: ChatInputCommandInteraction): Promise<void> {\n return this.executor(interaction);\n }\n\n /** Execute autocomplete for the focused option. */\n autocomplete(interaction: AutocompleteInteraction): Promise<void> {\n return this.autocompleter(interaction);\n }\n}\n\nfunction resolveOptions(\n interaction: ChatInputCommandInteraction,\n options: OptionMap,\n): Record<string, OptionValue | undefined> {\n const resolved: Record<string, OptionValue | undefined> = {};\n for (const [name, def] of Object.entries(options)) {\n resolved[name] = readOption(interaction.options, name, def);\n }\n return resolved;\n}\n\nfunction makeAutocompleter(\n options: OptionMap,\n): (interaction: AutocompleteInteraction) => Promise<void> {\n return async (interaction) => {\n const focused = interaction.options.getFocused(true);\n const def = options[focused.name];\n if (def?.autocomplete === undefined) {\n if (!interaction.responded) await interaction.respond([]);\n return;\n }\n const ctx = new AutocompleteContext(interaction);\n const choices = await def.autocomplete(ctx);\n if (!interaction.responded) await ctx.respond(choices);\n };\n}\n\nfunction baseJSON(\n meta: CommonMeta & { name: string; description: string },\n options: RESTPostAPIChatInputApplicationCommandsJSONBody[\"options\"],\n): RESTPostAPIChatInputApplicationCommandsJSONBody {\n return {\n type: ApplicationCommandType.ChatInput,\n name: meta.name,\n description: meta.description,\n name_localizations: meta.nameLocalizations,\n description_localizations: meta.descriptionLocalizations,\n nsfw: meta.nsfw,\n default_member_permissions:\n meta.defaultMemberPermissions == null\n ? meta.defaultMemberPermissions\n : new PermissionsBitField(meta.defaultMemberPermissions).bitfield.toString(),\n contexts: meta.guildOnly ? [InteractionContextType.Guild] : undefined,\n options,\n };\n}\n\nfunction leafOptionsJSON(options: OptionMap): RESTPostAPIChatInputApplicationCommandsJSONBody[\"options\"] {\n return Object.entries(options).map(([name, def]) => toAPIOption(name, def));\n}\n\nfunction subcommandJSON(name: string, sub: Subcommand): APIApplicationCommandSubcommandOption {\n return {\n type: ApplicationCommandOptionType.Subcommand,\n name,\n description: sub.description,\n name_localizations: sub.nameLocalizations,\n description_localizations: sub.descriptionLocalizations,\n options: Object.entries(sub.options).map(([n, def]) => toAPIOption(n, def)),\n };\n}\n\nfunction routeSubcommand(\n groupName: string | null,\n subName: string | null,\n subcommands: Record<string, Subcommand> | undefined,\n groups: Record<string, SubcommandGroup> | undefined,\n): Subcommand | undefined {\n if (groupName !== null) return groups?.[groupName]?.subcommands[subName ?? \"\"];\n if (subName !== null) return subcommands?.[subName];\n return undefined;\n}\n\n/**\n * Define a slash command with type-safe options and a co-located handler.\n *\n * @example\n * ```ts\n * export default command({\n * name: \"echo\",\n * description: \"Repeat a message\",\n * options: { msg: option.string({ description: \"Text\", required: true }) },\n * run: (ctx) => ctx.reply(ctx.options.msg),\n * });\n * ```\n */\nexport function command<O extends OptionMap = Record<string, never>, R = void>(\n config: CommandConfig<O, R>,\n): SlashCommand {\n const options: OptionMap = config.options ?? {};\n const { run } = config;\n const executor = async (interaction: ChatInputCommandInteraction): Promise<void> => {\n const resolved = resolveOptions(interaction, options) as ResolvedOptions<O>;\n await run(new CommandContext<O>(interaction, resolved));\n };\n return new SlashCommand({\n name: config.name,\n json: baseJSON(config, leafOptionsJSON(options)),\n hasAutocomplete: optionsHaveAutocomplete(options),\n executor,\n autocompleter: makeAutocompleter(options),\n });\n}\n\n/** Define a single subcommand with type-safe options and a handler. */\nexport function subcommand<O extends OptionMap = Record<string, never>, R = void>(\n config: SubcommandConfig<O, R>,\n): Subcommand {\n const options: OptionMap = config.options ?? {};\n const { run } = config;\n const execute = async (interaction: ChatInputCommandInteraction): Promise<void> => {\n const resolved = resolveOptions(interaction, options) as ResolvedOptions<O>;\n await run(new CommandContext<O>(interaction, resolved));\n };\n return {\n kind: \"subcommand\",\n description: config.description,\n options,\n nameLocalizations: config.nameLocalizations,\n descriptionLocalizations: config.descriptionLocalizations,\n hasAutocomplete: optionsHaveAutocomplete(options),\n execute,\n autocomplete: makeAutocompleter(options),\n };\n}\n\n/** Group several subcommands under a shared name. */\nexport function subcommandGroup(config: SubcommandGroupConfig): SubcommandGroup {\n return { kind: \"group\", ...config };\n}\n\n/** Define a command that routes to subcommands and/or subcommand groups. */\nexport function commandGroup(config: CommandGroupConfig): SlashCommand {\n const { subcommands, groups } = config;\n\n const options: (APIApplicationCommandSubcommandOption | APIApplicationCommandSubcommandGroupOption)[] =\n [];\n for (const [name, sub] of Object.entries(subcommands ?? {})) {\n options.push(subcommandJSON(name, sub));\n }\n for (const [name, group] of Object.entries(groups ?? {})) {\n options.push({\n type: ApplicationCommandOptionType.SubcommandGroup,\n name,\n description: group.description,\n name_localizations: group.nameLocalizations,\n description_localizations: group.descriptionLocalizations,\n options: Object.entries(group.subcommands).map(([n, s]) => subcommandJSON(n, s)),\n });\n }\n\n const hasAutocomplete =\n Object.values(subcommands ?? {}).some((s) => s.hasAutocomplete) ||\n Object.values(groups ?? {}).some((g) => Object.values(g.subcommands).some((s) => s.hasAutocomplete));\n\n const executor = async (interaction: ChatInputCommandInteraction): Promise<void> => {\n const target = routeSubcommand(\n interaction.options.getSubcommandGroup(false),\n interaction.options.getSubcommand(false),\n subcommands,\n groups,\n );\n if (target === undefined) {\n throw new Error(`spearkit: no subcommand handler for /${config.name}`);\n }\n await target.execute(interaction);\n };\n\n const autocompleter = async (interaction: AutocompleteInteraction): Promise<void> => {\n const target = routeSubcommand(\n interaction.options.getSubcommandGroup(false),\n interaction.options.getSubcommand(false),\n subcommands,\n groups,\n );\n if (target === undefined) {\n if (!interaction.responded) await interaction.respond([]);\n return;\n }\n await target.autocomplete(interaction);\n };\n\n return new SlashCommand({\n name: config.name,\n json: baseJSON(config, options),\n hasAutocomplete,\n executor,\n autocompleter,\n });\n}\n","import {\n MessageFlags,\n REST,\n Routes,\n type AutocompleteInteraction,\n type Awaitable,\n type ChatInputCommandInteraction,\n type RESTPostAPIApplicationCommandsJSONBody,\n type RESTPutAPIApplicationCommandsResult,\n type RESTPutAPIApplicationGuildCommandsResult,\n} from \"discord.js\";\nimport type { SlashCommand } from \"./command.js\";\n\n/** Error hook invoked when a command handler throws. */\nexport type CommandErrorHandler = (\n error: Error,\n interaction: ChatInputCommandInteraction,\n) => Awaitable<void>;\n\n/** Options for pushing commands to discord. */\nexport interface DeployOptions {\n /** Bot token. Falls back to the client token when omitted. */\n token?: string;\n /** Application (client) id. */\n applicationId: string;\n /** Deploy to a single guild (updates instantly) instead of globally. */\n guildId?: string;\n /** Reuse an existing REST instance instead of creating one. */\n rest?: REST;\n}\n\n/** Result of a {@link CommandRegistry.deploy} call. */\nexport type DeployResult =\n | RESTPutAPIApplicationCommandsResult\n | RESTPutAPIApplicationGuildCommandsResult;\n\n/** Holds every slash command and routes interactions to them. */\nexport class CommandRegistry {\n private readonly commands = new Map<string, SlashCommand>();\n private errorHandler?: CommandErrorHandler;\n\n /** Register one or more commands. Later registrations override by name. */\n add(...commands: SlashCommand[]): this {\n for (const command of commands) this.commands.set(command.name, command);\n return this;\n }\n\n /** Remove a command by name. */\n remove(name: string): boolean {\n return this.commands.delete(name);\n }\n\n /** Look up a command by name. */\n get(name: string): SlashCommand | undefined {\n return this.commands.get(name);\n }\n\n /** All registered commands. */\n all(): SlashCommand[] {\n return [...this.commands.values()];\n }\n\n /** All registered command names. */\n get names(): string[] {\n return [...this.commands.keys()];\n }\n\n /** Number of registered commands. */\n get size(): number {\n return this.commands.size;\n }\n\n /** Set the handler used when a command throws. */\n onError(handler: CommandErrorHandler): this {\n this.errorHandler = handler;\n return this;\n }\n\n /** Serialise every command to discord REST payloads. */\n toJSON(): RESTPostAPIApplicationCommandsJSONBody[] {\n return this.all().map((c) => c.toJSON());\n }\n\n /** Dispatch an incoming chat-input interaction to its command. */\n async handle(interaction: ChatInputCommandInteraction): Promise<void> {\n const command = this.commands.get(interaction.commandName);\n if (command === undefined) return;\n try {\n await command.execute(interaction);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (this.errorHandler !== undefined) {\n await this.errorHandler(err, interaction);\n } else {\n await this.defaultErrorReply(err, interaction);\n }\n }\n }\n\n /** Dispatch an autocomplete interaction to its command. */\n async handleAutocomplete(interaction: AutocompleteInteraction): Promise<void> {\n const command = this.commands.get(interaction.commandName);\n if (command === undefined) return;\n try {\n await command.autocomplete(interaction);\n } catch {\n if (!interaction.responded) await interaction.respond([]).catch(() => undefined);\n }\n }\n\n /**\n * Push the registered commands to discord. Returns the API response.\n *\n * Guild deploys apply instantly and are ideal during development; global\n * deploys can take up to an hour to propagate.\n */\n async deploy(options: DeployOptions): Promise<DeployResult> {\n let rest = options.rest;\n if (rest === undefined) {\n if (options.token === undefined) {\n throw new Error(\"spearkit: deploy() requires a token or a pre-configured REST instance\");\n }\n rest = new REST().setToken(options.token);\n }\n const body = this.toJSON();\n const route =\n options.guildId !== undefined\n ? Routes.applicationGuildCommands(options.applicationId, options.guildId)\n : Routes.applicationCommands(options.applicationId);\n return (await rest.put(route, { body })) as DeployResult;\n }\n\n private async defaultErrorReply(\n error: Error,\n interaction: ChatInputCommandInteraction,\n ): Promise<void> {\n interaction.client.emit(\"error\", error);\n const content = \"Something went wrong while running that command.\";\n try {\n if (interaction.deferred) {\n await interaction.editReply({ content });\n } else if (interaction.replied) {\n await interaction.followUp({ content, flags: MessageFlags.Ephemeral });\n } else {\n await interaction.reply({ content, flags: MessageFlags.Ephemeral });\n }\n } catch {\n // Interaction likely expired; nothing actionable left to do.\n }\n }\n}\n","import type { Awaitable, Client, ClientEvents } from \"discord.js\";\n\n/** A typed handler for a discord.js client event. */\nexport type EventHandler<E extends keyof ClientEvents> = (\n ...args: ClientEvents[E]\n) => Awaitable<void>;\n\n/** Object form accepted by {@link event}. */\nexport interface EventConfig<E extends keyof ClientEvents> {\n name: E;\n /** Run the handler at most once, then auto-detach. */\n once?: boolean;\n run: EventHandler<E>;\n}\n\n/**\n * A type-erased, ready-to-attach event listener. Built by {@link event}; the\n * concrete event type is captured in the closures so binding stays type-safe.\n */\nexport interface EventDef {\n readonly name: keyof ClientEvents;\n readonly once: boolean;\n /** Attach the listener to a client. */\n attach(client: Client): void;\n /** Remove the listener from a client it was attached to. */\n detach(client: Client): void;\n}\n\nfunction toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value));\n}\n\nfunction build<E extends keyof ClientEvents>(name: E, once: boolean, run: EventHandler<E>): EventDef {\n const listeners = new WeakMap<Client, (...args: ClientEvents[E]) => void>();\n return {\n name,\n once,\n attach(client) {\n const listener = (...args: ClientEvents[E]): void => {\n try {\n const result = run(...args);\n if (result instanceof Promise) {\n result.catch((error: unknown) => client.emit(\"error\", toError(error)));\n }\n } catch (error) {\n client.emit(\"error\", toError(error));\n }\n };\n listeners.set(client, listener);\n if (once) client.once(name, listener);\n else client.on(name, listener);\n },\n detach(client) {\n const listener = listeners.get(client);\n if (listener !== undefined) {\n client.off(name, listener);\n listeners.delete(client);\n }\n },\n };\n}\n\n/**\n * Define a discord.js event listener with a fully-typed handler. Thrown errors\n * and rejected promises are routed to the client's `error` event instead of\n * crashing the process.\n *\n * @example\n * ```ts\n * export default event(\"messageCreate\", (message) => {\n * if (message.author.bot) return;\n * // message is fully typed as Message\n * });\n * ```\n */\nexport function event<E extends keyof ClientEvents>(name: E, run: EventHandler<E>): EventDef;\nexport function event<E extends keyof ClientEvents>(config: EventConfig<E>): EventDef;\nexport function event<E extends keyof ClientEvents>(\n nameOrConfig: E | EventConfig<E>,\n run?: EventHandler<E>,\n): EventDef {\n if (typeof nameOrConfig === \"object\") {\n return build(nameOrConfig.name, nameOrConfig.once ?? false, nameOrConfig.run);\n }\n if (run === undefined) {\n throw new Error(\"spearkit: event(name, run) requires a handler\");\n }\n return build(nameOrConfig, false, run);\n}\n\n/** Holds event listeners and attaches them to clients in bulk. */\nexport class EventRegistry {\n private readonly events: EventDef[] = [];\n private readonly attached = new Set<Client>();\n\n /** Register one or more event definitions. */\n add(...defs: EventDef[]): this {\n this.events.push(...defs);\n for (const client of this.attached) {\n for (const def of defs) def.attach(client);\n }\n return this;\n }\n\n /** Number of registered listeners. */\n get size(): number {\n return this.events.length;\n }\n\n /** Attach every registered listener to the client. */\n attachAll(client: Client): void {\n this.attached.add(client);\n for (const def of this.events) def.attach(client);\n }\n\n /** Detach every registered listener from the client. */\n detachAll(client: Client): void {\n this.attached.delete(client);\n for (const def of this.events) def.detach(client);\n }\n}\n","/**\n * Typed custom-id codec.\n *\n * Patterns follow the grammar `namespace(:{param})*`, e.g. `\"vote\"` or\n * `\"vote:{choice}\"` or `\"page:{id}:{dir}\"`. The `namespace` is the routing key;\n * each `{param}` becomes a positional, percent-escaped value in the encoded id.\n * Param names are recovered at the type level so handlers get a typed `params`\n * object and `build()` requires exactly the right params.\n */\n\n/** Names of the `{param}` placeholders inside a pattern. */\nexport type ParamNames<S extends string> = S extends `${string}{${infer Name}}${infer Rest}`\n ? Name | ParamNames<Rest>\n : never;\n\n/** The params object a pattern resolves to (every value is a string). */\nexport type Params<S extends string> = { [K in ParamNames<S>]: string };\n\n/** Arguments `build()` accepts: none when the pattern has no params. */\nexport type BuildArgs<S extends string> = [ParamNames<S>] extends [never]\n ? []\n : [params: Params<S>];\n\n/** The discord custom-id length limit. */\nexport const MAX_CUSTOM_ID_LENGTH = 100;\n\nconst PARAM_SEGMENT = /^\\{([A-Za-z0-9_]+)\\}$/;\n\n/** A compiled pattern: its routing namespace and ordered param names. */\nexport interface CompiledPattern {\n readonly pattern: string;\n readonly namespace: string;\n readonly paramNames: readonly string[];\n}\n\n/** Compile and validate a custom-id pattern. Throws on malformed input. */\nexport function compilePattern(pattern: string): CompiledPattern {\n const segments = pattern.split(\":\");\n const namespace = segments[0] ?? \"\";\n if (namespace.length === 0 || /[{}]/.test(namespace)) {\n throw new Error(\n `spearkit: invalid custom-id pattern \"${pattern}\". Expected \"namespace\" or \"namespace:{param}\".`,\n );\n }\n const paramNames: string[] = [];\n for (let i = 1; i < segments.length; i++) {\n const match = PARAM_SEGMENT.exec(segments[i] ?? \"\");\n if (match === null) {\n throw new Error(\n `spearkit: invalid custom-id pattern \"${pattern}\". Segment \"${segments[i]}\" must be \"{param}\".`,\n );\n }\n paramNames.push(match[1] as string);\n }\n return { pattern, namespace, paramNames };\n}\n\nfunction encodeValue(value: string): string {\n return value.replace(/%/g, \"%25\").replace(/:/g, \"%3A\");\n}\n\nfunction decodeValue(value: string): string {\n return value.replace(/%3A/g, \":\").replace(/%25/g, \"%\");\n}\n\n/** Build a concrete custom-id from a compiled pattern and its params. */\nexport function buildCustomId(\n compiled: CompiledPattern,\n params: Readonly<Record<string, string>>,\n): string {\n const parts = [compiled.namespace];\n for (const name of compiled.paramNames) {\n const value = params[name];\n if (value === undefined) {\n throw new Error(`spearkit: missing param \"${name}\" for custom-id \"${compiled.pattern}\"`);\n }\n parts.push(encodeValue(value));\n }\n const id = parts.join(\":\");\n if (id.length > MAX_CUSTOM_ID_LENGTH) {\n throw new Error(\n `spearkit: custom-id \"${id}\" exceeds the ${MAX_CUSTOM_ID_LENGTH}-character discord limit`,\n );\n }\n return id;\n}\n\n/** The namespace + raw values parsed out of an incoming custom-id. */\nexport interface ParsedCustomId {\n readonly namespace: string;\n readonly values: readonly string[];\n}\n\n/** Parse an incoming custom-id into its namespace and decoded values. */\nexport function parseCustomId(customId: string): ParsedCustomId {\n const segments = customId.split(\":\");\n const namespace = segments[0] ?? \"\";\n const values = segments.slice(1).map(decodeValue);\n return { namespace, values };\n}\n\n/** Map ordered values onto their param names. */\nexport function paramsFromValues(\n paramNames: readonly string[],\n values: readonly string[],\n): Record<string, string> {\n const params: Record<string, string> = {};\n for (let i = 0; i < paramNames.length; i++) {\n params[paramNames[i] as string] = values[i] ?? \"\";\n }\n return params;\n}\n","import type {\n APIModalInteractionResponseCallbackData,\n ButtonInteraction,\n ChannelSelectMenuInteraction,\n InteractionUpdateOptions,\n JSONEncodable,\n MentionableSelectMenuInteraction,\n ModalBuilder,\n ModalComponentData,\n ModalSubmitInteraction,\n RoleSelectMenuInteraction,\n StringSelectMenuInteraction,\n UserSelectMenuInteraction,\n} from \"discord.js\";\nimport { BaseContext } from \"../context.js\";\n\ntype UpdateInput = string | InteractionUpdateOptions;\n/** The concrete message-component interaction types (button + every select). */\nexport type AnyComponentInteraction =\n | ButtonInteraction\n | StringSelectMenuInteraction\n | UserSelectMenuInteraction\n | RoleSelectMenuInteraction\n | ChannelSelectMenuInteraction\n | MentionableSelectMenuInteraction;\n\n/**\n * Base context for message-component interactions (buttons and selects).\n * Adds the component-only `update`/`deferUpdate`/`showModal` helpers and the\n * routed, typed {@link params}.\n */\nexport class MessageComponentContext<\n P,\n I extends AnyComponentInteraction = AnyComponentInteraction,\n> extends BaseContext<I> {\n constructor(\n interaction: I,\n /** Params extracted from the custom-id pattern. */\n readonly params: P,\n ) {\n super(interaction);\n }\n\n /** The raw custom-id that triggered this interaction. */\n get customId(): string {\n return this.interaction.customId;\n }\n\n /** The message the component lives on. */\n get message() {\n return this.interaction.message;\n }\n\n /** Edit the message this component belongs to. */\n async update(input: UpdateInput): Promise<void> {\n await this.interaction.update(input);\n }\n\n /** Acknowledge the interaction without editing the message yet. */\n async deferUpdate(): Promise<void> {\n await this.interaction.deferUpdate();\n }\n\n /** Open a modal in response to this component. */\n async showModal(\n modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData | ModalBuilder,\n ): Promise<void> {\n await this.interaction.showModal(modal);\n }\n}\n\n/** Context for a button click. */\nexport class ButtonContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n ButtonInteraction\n> {}\n\n/** Context for a string select; exposes the chosen {@link values}. */\nexport class StringSelectContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n StringSelectMenuInteraction\n> {\n /** All selected values. */\n get values(): string[] {\n return this.interaction.values;\n }\n /** The first selected value, or `undefined` if none. */\n get value(): string | undefined {\n return this.interaction.values[0];\n }\n}\n\n/** Context for a user select; exposes selected ids, users and members. */\nexport class UserSelectContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n UserSelectMenuInteraction\n> {\n get values(): string[] {\n return this.interaction.values;\n }\n get users() {\n return this.interaction.users;\n }\n get members() {\n return this.interaction.members;\n }\n}\n\n/** Context for a role select. */\nexport class RoleSelectContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n RoleSelectMenuInteraction\n> {\n get values(): string[] {\n return this.interaction.values;\n }\n get roles() {\n return this.interaction.roles;\n }\n}\n\n/** Context for a channel select. */\nexport class ChannelSelectContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n ChannelSelectMenuInteraction\n> {\n get values(): string[] {\n return this.interaction.values;\n }\n get channels() {\n return this.interaction.channels;\n }\n}\n\n/** Context for a mentionable (user + role) select. */\nexport class MentionableSelectContext<P = Record<string, never>> extends MessageComponentContext<\n P,\n MentionableSelectMenuInteraction\n> {\n get values(): string[] {\n return this.interaction.values;\n }\n get users() {\n return this.interaction.users;\n }\n get roles() {\n return this.interaction.roles;\n }\n get members() {\n return this.interaction.members;\n }\n}\n\n/**\n * Context for a submitted modal. Exposes the routed {@link params} plus the\n * resolved text-input {@link fields}, keyed by the field names you declared.\n */\nexport class ModalContext<P, F extends string = string> extends BaseContext<ModalSubmitInteraction> {\n constructor(\n interaction: ModalSubmitInteraction,\n readonly params: P,\n /** Submitted values, keyed by the field names from your modal definition. */\n readonly fields: Record<F, string>,\n ) {\n super(interaction);\n }\n\n /** The raw custom-id that triggered this modal submission. */\n get customId(): string {\n return this.interaction.customId;\n }\n}\n","import type {\n ButtonInteraction,\n ChannelSelectMenuInteraction,\n Interaction,\n MentionableSelectMenuInteraction,\n ModalSubmitInteraction,\n RepliableInteraction,\n RoleSelectMenuInteraction,\n StringSelectMenuInteraction,\n UserSelectMenuInteraction,\n Awaitable,\n} from \"discord.js\";\nimport { MessageFlags } from \"discord.js\";\nimport { parseCustomId, paramsFromValues } from \"./customId.js\";\n\n/** Shared shape of every routed component. */\ninterface RouteBase {\n readonly namespace: string;\n readonly paramNames: readonly string[];\n}\n\n/** Routing entry for a button. */\nexport interface ButtonRoute extends RouteBase {\n readonly kind: \"button\";\n handle(interaction: ButtonInteraction, params: Record<string, string>): Promise<void>;\n}\n/** Routing entry for a string select. */\nexport interface StringSelectRoute extends RouteBase {\n readonly kind: \"stringSelect\";\n handle(interaction: StringSelectMenuInteraction, params: Record<string, string>): Promise<void>;\n}\n/** Routing entry for a user select. */\nexport interface UserSelectRoute extends RouteBase {\n readonly kind: \"userSelect\";\n handle(interaction: UserSelectMenuInteraction, params: Record<string, string>): Promise<void>;\n}\n/** Routing entry for a role select. */\nexport interface RoleSelectRoute extends RouteBase {\n readonly kind: \"roleSelect\";\n handle(interaction: RoleSelectMenuInteraction, params: Record<string, string>): Promise<void>;\n}\n/** Routing entry for a channel select. */\nexport interface ChannelSelectRoute extends RouteBase {\n readonly kind: \"channelSelect\";\n handle(interaction: ChannelSelectMenuInteraction, params: Record<string, string>): Promise<void>;\n}\n/** Routing entry for a mentionable select. */\nexport interface MentionableSelectRoute extends RouteBase {\n readonly kind: \"mentionableSelect\";\n handle(\n interaction: MentionableSelectMenuInteraction,\n params: Record<string, string>,\n ): Promise<void>;\n}\n/** Routing entry for a modal submission. */\nexport interface ModalRoute extends RouteBase {\n readonly kind: \"modal\";\n handle(interaction: ModalSubmitInteraction, params: Record<string, string>): Promise<void>;\n}\n\n/** Any registrable component routing entry. */\nexport type ComponentDef =\n | ButtonRoute\n | StringSelectRoute\n | UserSelectRoute\n | RoleSelectRoute\n | ChannelSelectRoute\n | MentionableSelectRoute\n | ModalRoute;\n\n/** Error hook invoked when a component handler throws. */\nexport type ComponentErrorHandler = (\n error: Error,\n interaction: RepliableInteraction,\n) => Awaitable<void>;\n\nfunction toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value));\n}\n\n/**\n * Routes button, select and modal interactions to the handlers registered for\n * their custom-id namespace. Decodes the custom-id, extracts typed params, and\n * invokes the matching handler.\n */\nexport class ComponentRegistry {\n private readonly buttons = new Map<string, ButtonRoute>();\n private readonly stringSelects = new Map<string, StringSelectRoute>();\n private readonly userSelects = new Map<string, UserSelectRoute>();\n private readonly roleSelects = new Map<string, RoleSelectRoute>();\n private readonly channelSelects = new Map<string, ChannelSelectRoute>();\n private readonly mentionableSelects = new Map<string, MentionableSelectRoute>();\n private readonly modals = new Map<string, ModalRoute>();\n private errorHandler?: ComponentErrorHandler;\n\n /** Register one or more components. Later registrations override by namespace. */\n add(...defs: ComponentDef[]): this {\n for (const def of defs) {\n switch (def.kind) {\n case \"button\":\n this.buttons.set(def.namespace, def);\n break;\n case \"stringSelect\":\n this.stringSelects.set(def.namespace, def);\n break;\n case \"userSelect\":\n this.userSelects.set(def.namespace, def);\n break;\n case \"roleSelect\":\n this.roleSelects.set(def.namespace, def);\n break;\n case \"channelSelect\":\n this.channelSelects.set(def.namespace, def);\n break;\n case \"mentionableSelect\":\n this.mentionableSelects.set(def.namespace, def);\n break;\n case \"modal\":\n this.modals.set(def.namespace, def);\n break;\n }\n }\n return this;\n }\n\n /** Set the handler used when a component throws. */\n onError(handler: ComponentErrorHandler): this {\n this.errorHandler = handler;\n return this;\n }\n\n /** Total number of registered components. */\n get size(): number {\n return (\n this.buttons.size +\n this.stringSelects.size +\n this.userSelects.size +\n this.roleSelects.size +\n this.channelSelects.size +\n this.mentionableSelects.size +\n this.modals.size\n );\n }\n\n /**\n * Dispatch an interaction to its component handler. Returns `true` if a\n * handler matched and ran, `false` otherwise.\n */\n async handle(interaction: Interaction): Promise<boolean> {\n if (interaction.isButton()) {\n return this.exec(this.buttons.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isStringSelectMenu()) {\n return this.exec(this.stringSelects.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isUserSelectMenu()) {\n return this.exec(this.userSelects.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isRoleSelectMenu()) {\n return this.exec(this.roleSelects.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isChannelSelectMenu()) {\n return this.exec(this.channelSelects.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isMentionableSelectMenu()) {\n return this.exec(this.mentionableSelects.get(namespaceOf(interaction.customId)), interaction);\n }\n if (interaction.isModalSubmit()) {\n return this.exec(this.modals.get(namespaceOf(interaction.customId)), interaction);\n }\n return false;\n }\n\n private async exec<I extends RepliableInteraction & { customId: string }>(\n route: (RouteBase & { handle(interaction: I, params: Record<string, string>): Promise<void> }) | undefined,\n interaction: I,\n ): Promise<boolean> {\n if (route === undefined) return false;\n const { values } = parseCustomId(interaction.customId);\n const params = paramsFromValues(route.paramNames, values);\n try {\n await route.handle(interaction, params);\n } catch (error) {\n const err = toError(error);\n if (this.errorHandler !== undefined) {\n await this.errorHandler(err, interaction);\n } else {\n interaction.client.emit(\"error\", err);\n if (!interaction.replied && !interaction.deferred) {\n await interaction\n .reply({ content: \"Something went wrong.\", flags: MessageFlags.Ephemeral })\n .catch(() => undefined);\n }\n }\n }\n return true;\n }\n}\n\nfunction namespaceOf(customId: string): string {\n return parseCustomId(customId).namespace;\n}\n","import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n ChannelSelectMenuBuilder,\n MentionableSelectMenuBuilder,\n ModalBuilder,\n RoleSelectMenuBuilder,\n StringSelectMenuBuilder,\n TextInputBuilder,\n TextInputStyle,\n UserSelectMenuBuilder,\n type Awaitable,\n type ChannelType,\n type ComponentEmojiResolvable,\n type SelectMenuComponentOptionData,\n} from \"discord.js\";\nimport {\n ButtonContext,\n ChannelSelectContext,\n MentionableSelectContext,\n ModalContext,\n RoleSelectContext,\n StringSelectContext,\n UserSelectContext,\n} from \"./context.js\";\nimport {\n buildCustomId,\n compilePattern,\n type BuildArgs,\n type Params,\n} from \"./customId.js\";\nimport type {\n ButtonRoute,\n ChannelSelectRoute,\n MentionableSelectRoute,\n ModalRoute,\n RoleSelectRoute,\n StringSelectRoute,\n UserSelectRoute,\n} from \"./registry.js\";\n\n// --- buttons ---------------------------------------------------------------\n\n/** Accepted button styles for an interactive (custom-id) button. */\nexport type ButtonStyleInput =\n | \"Primary\"\n | \"Secondary\"\n | \"Success\"\n | \"Danger\"\n | ButtonStyle.Primary\n | ButtonStyle.Secondary\n | ButtonStyle.Success\n | ButtonStyle.Danger;\n\nfunction resolveButtonStyle(input: ButtonStyleInput | undefined): ButtonStyle {\n if (input === undefined) return ButtonStyle.Secondary;\n return typeof input === \"number\" ? input : ButtonStyle[input];\n}\n\n/** Config for an interactive button created with {@link button}. */\nexport interface ButtonConfig<P extends string, R> {\n /** Custom-id pattern, e.g. `\"vote\"` or `\"vote:{choice}\"`. */\n id: P;\n label?: string;\n style?: ButtonStyleInput;\n emoji?: ComponentEmojiResolvable;\n disabled?: boolean;\n run: (ctx: ButtonContext<Params<P>>) => Awaitable<R>;\n}\n\n/** A registrable button with a typed {@link build}. */\nexport interface Button<P extends string> extends ButtonRoute {\n build(...args: BuildArgs<P>): ButtonBuilder;\n}\n\n/**\n * Define an interactive button: its appearance, its custom-id pattern and its\n * click handler, all in one place. Register it with `client.components.add`.\n *\n * @example\n * ```ts\n * const vote = button({\n * id: \"vote:{choice}\",\n * label: \"Yes\",\n * style: \"Success\",\n * run: (ctx) => ctx.reply(`You chose ${ctx.params.choice}`),\n * });\n * row(vote.build({ choice: \"yes\" }));\n * ```\n */\nexport function button<const P extends string, R = void>(config: ButtonConfig<P, R>): Button<P> {\n const compiled = compilePattern(config.id);\n const style = resolveButtonStyle(config.style);\n return {\n kind: \"button\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new ButtonContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): ButtonBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new ButtonBuilder()\n .setCustomId(buildCustomId(compiled, params))\n .setStyle(style);\n if (config.label !== undefined) builder.setLabel(config.label);\n if (config.emoji !== undefined) builder.setEmoji(config.emoji);\n if (config.disabled !== undefined) builder.setDisabled(config.disabled);\n return builder;\n },\n };\n}\n\n/** Config for a link button (no handler — just opens a URL). */\nexport interface LinkButtonConfig {\n url: string;\n label?: string;\n emoji?: ComponentEmojiResolvable;\n disabled?: boolean;\n}\n\n/** Build a link button. Link buttons have no custom-id and run no handler. */\nexport function linkButton(config: LinkButtonConfig): ButtonBuilder {\n const builder = new ButtonBuilder().setStyle(ButtonStyle.Link).setURL(config.url);\n if (config.label !== undefined) builder.setLabel(config.label);\n if (config.emoji !== undefined) builder.setEmoji(config.emoji);\n if (config.disabled !== undefined) builder.setDisabled(config.disabled);\n return builder;\n}\n\n// --- selects ---------------------------------------------------------------\n\ninterface SelectConfigBase {\n placeholder?: string;\n minValues?: number;\n maxValues?: number;\n disabled?: boolean;\n}\n\n/** Any of the select-menu builders that share the base configuration setters. */\ntype AnySelectBuilder =\n | StringSelectMenuBuilder\n | UserSelectMenuBuilder\n | RoleSelectMenuBuilder\n | ChannelSelectMenuBuilder\n | MentionableSelectMenuBuilder;\nfunction applySelectBase(builder: AnySelectBuilder, config: SelectConfigBase): void {\n if (config.placeholder !== undefined) builder.setPlaceholder(config.placeholder);\n if (config.minValues !== undefined) builder.setMinValues(config.minValues);\n if (config.maxValues !== undefined) builder.setMaxValues(config.maxValues);\n if (config.disabled !== undefined) builder.setDisabled(config.disabled);\n}\n\n/** Config for a string select created with {@link stringSelect}. */\nexport interface StringSelectConfig<P extends string, R> extends SelectConfigBase {\n id: P;\n options: readonly SelectMenuComponentOptionData[];\n run: (ctx: StringSelectContext<Params<P>>) => Awaitable<R>;\n}\n\n/** A registrable string select with a typed {@link build}. */\nexport interface StringSelect<P extends string> extends StringSelectRoute {\n build(...args: BuildArgs<P>): StringSelectMenuBuilder;\n}\n\n/** Define a string select menu, its custom-id pattern and its handler. */\nexport function stringSelect<const P extends string, R = void>(\n config: StringSelectConfig<P, R>,\n): StringSelect<P> {\n const compiled = compilePattern(config.id);\n return {\n kind: \"stringSelect\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new StringSelectContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): StringSelectMenuBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new StringSelectMenuBuilder()\n .setCustomId(buildCustomId(compiled, params))\n .addOptions(...config.options);\n applySelectBase(builder, config);\n return builder;\n },\n };\n}\n\n/** Config shared by the entity-select builders (user/role/channel/mentionable). */\nexport interface EntitySelectConfig<P extends string> extends SelectConfigBase {\n id: P;\n}\n\n/** A registrable user select. */\nexport interface UserSelect<P extends string> extends UserSelectRoute {\n build(...args: BuildArgs<P>): UserSelectMenuBuilder;\n}\n\n/** Define a user select menu. */\nexport function userSelect<const P extends string, R = void>(\n config: EntitySelectConfig<P> & { run: (ctx: UserSelectContext<Params<P>>) => Awaitable<R> },\n): UserSelect<P> {\n const compiled = compilePattern(config.id);\n return {\n kind: \"userSelect\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new UserSelectContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): UserSelectMenuBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new UserSelectMenuBuilder().setCustomId(buildCustomId(compiled, params));\n applySelectBase(builder, config);\n return builder;\n },\n };\n}\n\n/** A registrable role select. */\nexport interface RoleSelect<P extends string> extends RoleSelectRoute {\n build(...args: BuildArgs<P>): RoleSelectMenuBuilder;\n}\n\n/** Define a role select menu. */\nexport function roleSelect<const P extends string, R = void>(\n config: EntitySelectConfig<P> & { run: (ctx: RoleSelectContext<Params<P>>) => Awaitable<R> },\n): RoleSelect<P> {\n const compiled = compilePattern(config.id);\n return {\n kind: \"roleSelect\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new RoleSelectContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): RoleSelectMenuBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new RoleSelectMenuBuilder().setCustomId(buildCustomId(compiled, params));\n applySelectBase(builder, config);\n return builder;\n },\n };\n}\n\n/** A registrable channel select. */\nexport interface ChannelSelect<P extends string> extends ChannelSelectRoute {\n build(...args: BuildArgs<P>): ChannelSelectMenuBuilder;\n}\n\n/** Define a channel select menu, optionally restricted to channel types. */\nexport function channelSelect<const P extends string, R = void>(\n config: EntitySelectConfig<P> & {\n channelTypes?: readonly ChannelType[];\n run: (ctx: ChannelSelectContext<Params<P>>) => Awaitable<R>;\n },\n): ChannelSelect<P> {\n const compiled = compilePattern(config.id);\n return {\n kind: \"channelSelect\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new ChannelSelectContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): ChannelSelectMenuBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new ChannelSelectMenuBuilder().setCustomId(buildCustomId(compiled, params));\n if (config.channelTypes !== undefined) builder.setChannelTypes(...config.channelTypes);\n applySelectBase(builder, config);\n return builder;\n },\n };\n}\n\n/** A registrable mentionable select. */\nexport interface MentionableSelect<P extends string> extends MentionableSelectRoute {\n build(...args: BuildArgs<P>): MentionableSelectMenuBuilder;\n}\n\n/** Define a mentionable (user + role) select menu. */\nexport function mentionableSelect<const P extends string, R = void>(\n config: EntitySelectConfig<P> & {\n run: (ctx: MentionableSelectContext<Params<P>>) => Awaitable<R>;\n },\n): MentionableSelect<P> {\n const compiled = compilePattern(config.id);\n return {\n kind: \"mentionableSelect\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n await config.run(new MentionableSelectContext(interaction, params as Params<P>));\n },\n build(...args: BuildArgs<P>): MentionableSelectMenuBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new MentionableSelectMenuBuilder().setCustomId(buildCustomId(compiled, params));\n applySelectBase(builder, config);\n return builder;\n },\n };\n}\n\n// --- modals ----------------------------------------------------------------\n\n/** Accepted text-input styles. */\nexport type TextInputStyleInput = \"Short\" | \"Paragraph\" | TextInputStyle;\n\nfunction resolveTextInputStyle(input: TextInputStyleInput | undefined): TextInputStyle {\n if (input === undefined) return TextInputStyle.Short;\n return typeof input === \"number\" ? input : TextInputStyle[input];\n}\n\n/** A resolved text-input field definition. */\nexport interface TextInputDef {\n readonly label: string;\n readonly style: TextInputStyle;\n readonly placeholder?: string;\n readonly required?: boolean;\n readonly minLength?: number;\n readonly maxLength?: number;\n readonly value?: string;\n}\n\n/** Define a single modal text-input field. */\nexport function textInput(config: {\n label: string;\n style?: TextInputStyleInput;\n placeholder?: string;\n required?: boolean;\n minLength?: number;\n maxLength?: number;\n value?: string;\n}): TextInputDef {\n return {\n label: config.label,\n style: resolveTextInputStyle(config.style),\n placeholder: config.placeholder,\n required: config.required,\n minLength: config.minLength,\n maxLength: config.maxLength,\n value: config.value,\n };\n}\n\n/** Config for a modal created with {@link modal}. */\nexport interface ModalConfig<P extends string, F extends Record<string, TextInputDef>, R> {\n id: P;\n title: string;\n fields: F;\n run: (ctx: ModalContext<Params<P>, keyof F & string>) => Awaitable<R>;\n}\n\n/** A registrable modal with a typed {@link build}. */\nexport interface Modal<P extends string> extends ModalRoute {\n build(...args: BuildArgs<P>): ModalBuilder;\n}\n\nfunction buildTextInput(customId: string, def: TextInputDef): TextInputBuilder {\n const input = new TextInputBuilder()\n .setCustomId(customId)\n .setLabel(def.label)\n .setStyle(def.style);\n if (def.placeholder !== undefined) input.setPlaceholder(def.placeholder);\n if (def.required !== undefined) input.setRequired(def.required);\n if (def.minLength !== undefined) input.setMinLength(def.minLength);\n if (def.maxLength !== undefined) input.setMaxLength(def.maxLength);\n if (def.value !== undefined) input.setValue(def.value);\n return input;\n}\n\n/**\n * Define a modal: its title, its custom-id pattern, its text-input fields and\n * a submit handler. The handler receives the submitted values keyed by field\n * name in `ctx.fields`.\n *\n * @example\n * ```ts\n * const feedback = modal({\n * id: \"feedback:{ticket}\",\n * title: \"Feedback\",\n * fields: { comment: textInput({ label: \"Comment\", style: \"Paragraph\" }) },\n * run: (ctx) => ctx.reply(`Thanks! (${ctx.params.ticket}): ${ctx.fields.comment}`),\n * });\n * ```\n */\nexport function modal<const P extends string, F extends Record<string, TextInputDef>, R = void>(\n config: ModalConfig<P, F, R>,\n): Modal<P> {\n const compiled = compilePattern(config.id);\n const fieldKeys = Object.keys(config.fields);\n return {\n kind: \"modal\",\n namespace: compiled.namespace,\n paramNames: compiled.paramNames,\n async handle(interaction, params) {\n const fields: Record<string, string> = {};\n for (const key of fieldKeys) {\n try {\n fields[key] = interaction.fields.getTextInputValue(key);\n } catch {\n fields[key] = \"\";\n }\n }\n await config.run(\n new ModalContext(interaction, params as Params<P>, fields as Record<keyof F & string, string>),\n );\n },\n build(...args: BuildArgs<P>): ModalBuilder {\n const params = (args[0] ?? {}) as Record<string, string>;\n const builder = new ModalBuilder()\n .setCustomId(buildCustomId(compiled, params))\n .setTitle(config.title);\n for (const [key, def] of Object.entries(config.fields)) {\n builder.addComponents(\n new ActionRowBuilder<TextInputBuilder>().addComponents(buildTextInput(key, def)),\n );\n }\n return builder;\n },\n };\n}\n","import { ActionRowBuilder, type MessageActionRowComponentBuilder } from \"discord.js\";\n\n/**\n * Wrap one or more component builders in an action row.\n *\n * A row holds up to five buttons, or exactly one select menu.\n *\n * @example\n * ```ts\n * const components = [row(yes.build(), no.build())];\n * await channel.send({ content: \"Vote:\", components });\n * ```\n */\nexport function row<C extends MessageActionRowComponentBuilder>(\n ...components: C[]\n): ActionRowBuilder<C> {\n return new ActionRowBuilder<C>().addComponents(...components);\n}\n","import { readdir } from \"node:fs/promises\";\nimport { extname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { SlashCommand } from \"./commands/command.js\";\nimport type { Registerable, SpearClient } from \"./client.js\";\n\n/** Options for the directory loader. */\nexport interface LoadOptions {\n /** File extensions to import. Default: `.js`, `.mjs`, `.cjs`. */\n extensions?: readonly string[];\n /** Recurse into subdirectories. Default: `true`. */\n recursive?: boolean;\n}\n\nconst DEFAULT_EXTENSIONS = [\".js\", \".mjs\", \".cjs\"] as const;\n\n/** Structural guard: is this exported value something spearkit can register? */\nfunction isRegisterable(value: unknown): value is Registerable {\n if (value instanceof SlashCommand) return true;\n if (typeof value !== \"object\" || value === null) return false;\n const record = value as Record<string, unknown>;\n if (typeof record[\"attach\"] === \"function\" && typeof record[\"detach\"] === \"function\") {\n return true;\n }\n if (typeof record[\"kind\"] === \"string\" && typeof record[\"handle\"] === \"function\") {\n return true;\n }\n return false;\n}\n\n/**\n * Recursively import a directory and collect every spearkit-registrable export\n * (commands, events, components) found in default or named exports.\n */\nexport async function collectModules(\n dir: string,\n options: LoadOptions = {},\n): Promise<Registerable[]> {\n const extensions = options.extensions ?? DEFAULT_EXTENSIONS;\n const recursive = options.recursive ?? true;\n const found: Registerable[] = [];\n\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (recursive) found.push(...(await collectModules(fullPath, options)));\n continue;\n }\n if (!extensions.includes(extname(entry.name))) continue;\n\n const mod: Record<string, unknown> = await import(pathToFileURL(fullPath).href);\n for (const value of Object.values(mod)) {\n if (isRegisterable(value)) found.push(value);\n }\n }\n return found;\n}\n\n/**\n * Load a directory and register everything it exports into the client.\n * Returns the number of items registered.\n */\nexport async function loadInto(\n client: SpearClient,\n dir: string,\n options?: LoadOptions,\n): Promise<number> {\n const items = await collectModules(dir, options);\n client.register(...items);\n return items.length;\n}\n","import {\n Client,\n GatewayIntentBits,\n type ClientOptions,\n type Interaction,\n} from \"discord.js\";\nimport { SlashCommand } from \"./commands/command.js\";\nimport { CommandRegistry, type DeployResult } from \"./commands/registry.js\";\nimport { EventRegistry, type EventDef } from \"./events.js\";\nimport { ComponentRegistry, type ComponentDef } from \"./components/registry.js\";\nimport type { SpearPlugin } from \"./plugin.js\";\nimport { loadInto, type LoadOptions } from \"./loader.js\";\n\n/** Anything that can be handed to {@link SpearClient.register}. */\nexport type Registerable = SlashCommand | EventDef | ComponentDef;\n\nconst allIntents = Object.values(GatewayIntentBits).filter(\n (value): value is GatewayIntentBits => typeof value === \"number\",\n);\n\n/**\n * Ready-made intent presets. Pass one to {@link SpearClient} as `intents`.\n * `all` includes privileged intents — enable them in the developer portal.\n */\nexport const Intents = {\n /** No intents. */\n none: [] as GatewayIntentBits[],\n /** Just `Guilds` — enough for slash commands and interactions. */\n default: [GatewayIntentBits.Guilds],\n /** Guild + member gateway data. */\n guilds: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],\n /** Read message content (privileged) alongside guild messages. */\n messages: [\n GatewayIntentBits.Guilds,\n GatewayIntentBits.GuildMessages,\n GatewayIntentBits.MessageContent,\n ],\n /** Every intent, including privileged ones. */\n all: allIntents,\n} as const;\n\n/** Options for {@link SpearClient}. Identical to discord.js but `intents` may be omitted. */\nexport type SpearClientOptions = Partial<ClientOptions>;\n\n/**\n * A discord.js {@link Client} with batteries included: command, event and\n * component registries plus interaction routing wired up automatically.\n *\n * @example\n * ```ts\n * const client = new SpearClient({ intents: Intents.default });\n * client.register(ping, onReady, voteButton);\n * await client.start(process.env.TOKEN);\n * await client.deployCommands({ guildId: \"123\" });\n * ```\n */\nexport class SpearClient extends Client {\n /** Slash command registry and dispatcher. */\n readonly commands = new CommandRegistry();\n /** Event listener registry. */\n readonly events = new EventRegistry();\n /** Button / select / modal registry and router. */\n readonly components = new ComponentRegistry();\n\n constructor(options: SpearClientOptions = {}) {\n const { intents, ...rest } = options;\n super({ ...rest, intents: intents ?? Intents.default });\n this.events.attachAll(this);\n this.on(\"interactionCreate\", (interaction) => this.route(interaction));\n }\n\n /**\n * Register commands, events and components in one call. Each item is routed\n * to the matching registry based on its kind.\n */\n register(...items: Registerable[]): this {\n for (const item of items) {\n if (item instanceof SlashCommand) {\n this.commands.add(item);\n } else if (\"attach\" in item) {\n this.events.add(item);\n } else {\n this.components.add(item);\n }\n }\n return this;\n }\n\n /** Install one or more plugins, running each plugin's `setup`. */\n async use(...plugins: SpearPlugin[]): Promise<this> {\n for (const plugin of plugins) {\n await plugin.setup(this);\n }\n return this;\n }\n\n /**\n * Recursively load a directory and register every command, event and\n * component it exports. Returns the number of items registered.\n */\n load(dir: string, options?: LoadOptions): Promise<number> {\n return loadInto(this, dir, options);\n }\n\n /**\n * Log in. Falls back to the `DISCORD_TOKEN` environment variable when no\n * token is passed.\n */\n async start(token?: string): Promise<this> {\n const resolved = token ?? process.env.DISCORD_TOKEN;\n if (resolved === undefined || resolved.length === 0) {\n throw new Error(\"spearkit: start() needs a token (pass one or set DISCORD_TOKEN)\");\n }\n await this.login(resolved);\n return this;\n }\n\n /**\n * Push the registered slash commands to discord using the client's own\n * authenticated REST connection. Call after the client is ready.\n */\n async deployCommands(options: { guildId?: string } = {}): Promise<DeployResult> {\n const applicationId = this.application?.id ?? this.user?.id;\n if (applicationId == null) {\n throw new Error(\"spearkit: deployCommands() must run after the client is ready\");\n }\n return this.commands.deploy({ rest: this.rest, applicationId, guildId: options.guildId });\n }\n\n private async route(interaction: Interaction): Promise<void> {\n if (interaction.isChatInputCommand()) {\n await this.commands.handle(interaction);\n } else if (interaction.isAutocomplete()) {\n await this.commands.handleAutocomplete(interaction);\n } else {\n await this.components.handle(interaction);\n }\n }\n}\n","import type { Awaitable } from \"discord.js\";\nimport type { SpearClient } from \"./client.js\";\n\n/**\n * A spearkit plugin: a named, reusable bundle of commands, events and components.\n * Its {@link setup} runs once when added to a client via `client.use(plugin)`.\n */\nexport interface SpearPlugin {\n readonly name: string;\n setup(client: SpearClient): Awaitable<void>;\n}\n\n/** Identity helper that gives a plugin object its type and editor hints. */\nexport function definePlugin(plugin: SpearPlugin): SpearPlugin {\n return plugin;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "spearkit",
3
+ "version": "0.1.0",
4
+ "description": "discord.js++ — a developer-experience-first Discord library. Drop-in compatible with discord.js, with ergonomic events, slash commands, and interactive components.",
5
+ "type": "module",
6
+ "license": "PolyForm-Noncommercial-1.0.0",
7
+ "author": "byigitt",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/byigitt/spearkit.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/byigitt/spearkit/issues"
14
+ },
15
+ "homepage": "https://github.com/byigitt/spearkit#readme",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "keywords": [
20
+ "discord",
21
+ "discord.js",
22
+ "bot",
23
+ "slash-commands",
24
+ "interactions",
25
+ "components"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "require": "./dist/index.cjs"
32
+ }
33
+ },
34
+ "main": "./dist/index.cjs",
35
+ "module": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "dev": "tsup --watch",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "e2e": "node e2e/live.mjs",
47
+ "prepublishOnly": "npm run build"
48
+ },
49
+ "dependencies": {
50
+ "discord.js": "^14.16.3"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.10.2",
54
+ "tsup": "^8.3.5",
55
+ "typescript": "^5.7.2",
56
+ "vitest": "^2.1.8"
57
+ },
58
+ "engines": {
59
+ "node": ">=18"
60
+ },
61
+ "pnpm": {
62
+ "onlyBuiltDependencies": ["esbuild"]
63
+ }
64
+ }