Complete reference for the @theminesastudios/mini-interaction package.
Creates the main application instance. This is the entry point that wires together verification, routing, and response handling.
createApp(config: AppConfig): App
interface AppConfig {
publicKey: string;
applicationId: string;
onError?: (error: unknown) => Response | Promise<Response>;
logger?: Logger;
}
interface App {
use(...routers: Router[]): void;
handle(): (req: Request) => Promise<Response>;
}Define a single slash command with typed options and a handler.
command<T extends Record<string, unknown> = Record<string, unknown>>(
config: CommandConfig<T>
): Command<T>
interface CommandConfig<T> {
name: string;
description: string;
options?: ApplicationCommandOption[];
handler: (ctx: CommandContext<T>) => Promise<InteractionResponse> | InteractionResponse;
dmPermission?: boolean;
defaultMemberPermissions?: string;
}class CommandRouter {
add(command: Command): this;
use(middleware: Middleware): this;
remove(name: string): boolean;
commands(): Command[];
}
// Middleware signature
type Middleware = (
ctx: CommandContext,
next: (ctx: CommandContext) => Promise<InteractionResponse>,
) => Promise<InteractionResponse>;class ComponentRouter {
add(handler: ComponentHandler): this;
remove(pattern: RegExp): boolean;
}
interface ComponentHandler {
pattern: RegExp;
handler: (ctx: ComponentContext) => Promise<InteractionResponse>;
}
interface ComponentContext {
interaction: APIMessageComponentInteraction;
params: Record<string, string>;
respond(data: InteractionCallbackData): Promise<InteractionResponse>;
deferUpdate(): Promise<void>;
timestamp: Date;
}class ModalRouter {
add(handler: ModalHandler): this;
remove(customId: string): boolean;
}
interface ModalHandler {
customId: string;
handler: (ctx: ModalContext) => Promise<InteractionResponse>;
}
interface ModalContext {
interaction: APIModalSubmitInteraction;
getField(customId: string): string;
respond(data: InteractionCallbackData): Promise<InteractionResponse>;
timestamp: Date;
}class EmbedBuilder {
setTitle(title: string): this;
setDescription(desc: string): this;
setColor(color: number): this;
setTimestamp(date?: Date): this;
setFooter(footer: EmbedFooter): this;
setImage(url: string): this;
setThumbnail(url: string): this;
setAuthor(author: EmbedAuthor): this;
addFields(fields: EmbedField[]): this;
toJSON(): APIEmbed;
}class ButtonBuilder {
setCustomId(id: string): this;
setLabel(text: string): this;
setStyle(style: ButtonStyle): this;
setEmoji(emoji: PartialEmoji): this;
setUrl(url: string): this;
setDisabled(disabled: boolean): this;
toJSON(): APIButtonComponent;
}class SelectMenuBuilder {
setCustomId(id: string): this;
setPlaceholder(text: string): this;
addOptions(options: SelectOption[]): this;
setMinValues(min: number): this;
setMaxValues(max: number): this;
setDisabled(disabled: boolean): this;
toJSON(): APISelectMenuComponent;
}
interface SelectOption {
label: string;
value: string;
description?: string;
emoji?: PartialEmoji;
default?: boolean;
}class ActionRowBuilder {
addComponents(...components: ComponentBuilder[]): this;
toJSON(): APIActionRowComponent;
}createOAuth2Handler(config: OAuth2Config): OAuth2Handler;
interface OAuth2Config {
clientId: string;
clientSecret: string;
redirectUri: string;
scopes?: string[];
store?: TokenStore;
}
interface OAuth2Handler {
authorizeUrl(params: AuthorizeParams): string;
callbackHandler(fn: CallbackFn): (req: Request) => Promise<Response>;
exchangeCode(code: string): Promise<TokenSet>;
refreshToken(refresh: string): Promise<TokenSet>;
getUser(accessToken: string): Promise<DiscordUser>;
getUserGuilds(accessToken: string): Promise<GuildPreview[]>;
hasScope(tokens: TokenSet, scope: string): boolean;
validateScopes(tokens: TokenSet, scopes: string[]): boolean;
getOrRefresh(userId: string): Promise<TokenSet | null>;
}
interface TokenSet {
accessToken: string;
refreshToken: string;
expiresAt: Date;
scope: string;
tokenType: string;
}The framework re-exports key Discord API types for convenience:
// Discord API types (re-exported from discord-api-types)
ApplicationCommandOptionType
ApplicationCommandType
ButtonStyle
ComponentType
InteractionType
InteractionResponseType
MessageFlags
MessageComponentType
// Framework types
type InteractionResponse
type CommandContext
type ComponentContext
type ModalContext
type InteractionCallbackData
// Logger interface
interface Logger {
info(msg: string, meta?: Record<string, unknown>): void;
warn(msg: string, meta?: Record<string, unknown>): void;
error(msg: string, meta?: Record<string, unknown>): void;
debug(msg: string, meta?: Record<string, unknown>): void;
}The framework provides typed errors for common failure modes:
class VerificationError extends Error {
readonly code: "INVALID_SIGNATURE" | "MISSING_HEADERS";
constructor(code: string, message: string);
}
class RouterError extends Error {
readonly code: "NOT_FOUND" | "AMBIGUOUS_MATCH";
constructor(code: string, message: string);
}
class OAuthError extends Error {
readonly code: "INVALID_STATE" | "TOKEN_EXPIRED" | "INVALID_SCOPE";
constructor(code: string, message: string, status?: number);
}