spearkit 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/spearkit/SKILL.md +247 -0
- package/.claude/skills/spearkit/reference/cheatsheet.md +329 -0
- package/AGENTS.md +261 -0
- package/README.md +23 -3
- package/dist/index.cjs +599 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +524 -2
- package/dist/index.d.ts +524 -2
- package/dist/index.js +576 -19
- package/dist/index.js.map +1 -1
- package/docs/README.md +72 -0
- package/docs/api-reference.md +777 -0
- package/docs/auto-defer.md +74 -0
- package/docs/client.md +245 -0
- package/docs/collectors.md +65 -0
- package/docs/commands.md +203 -0
- package/docs/components.md +281 -0
- package/docs/context-menus.md +121 -0
- package/docs/context.md +293 -0
- package/docs/cooldown.md +125 -0
- package/docs/env.md +130 -0
- package/docs/errors.md +73 -0
- package/docs/events.md +152 -0
- package/docs/getting-started.md +147 -0
- package/docs/guards.md +146 -0
- package/docs/loading.md +144 -0
- package/docs/logging.md +195 -0
- package/docs/messages.md +35 -0
- package/docs/migration.md +160 -0
- package/docs/options.md +163 -0
- package/docs/permissions.md +68 -0
- package/docs/plugins.md +116 -0
- package/docs/prefix.md +234 -0
- package/docs/scheduler.md +111 -0
- package/docs/shutdown.md +42 -0
- package/docs/store.md +90 -0
- package/docs/usage.md +188 -0
- package/llms-full.txt +4619 -0
- package/llms.txt +127 -0
- package/package.json +9 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as discord_js from 'discord.js';
|
|
2
|
-
import { APIEmbedField, APIEmbedFooter, APIEmbedAuthor, EmbedBuilder, Client, Channel, Guild, GuildMember, MessageManager, Message, Role, User, APIInteractionGuildMember, Awaitable, PermissionResolvable,
|
|
2
|
+
import { APIEmbedField, APIEmbedFooter, APIEmbedAuthor, EmbedBuilder, Client, Channel, Guild, GuildMember, MessageManager, Message, Role, User, APIInteractionGuildMember, Awaitable, PermissionResolvable, GuildBasedChannel, PermissionsString, RESTJSONErrorCodes, DiscordAPIError, HTTPError, MessageComponentInteraction, ComponentType, ModalSubmitInteraction, JSONEncodable, APIModalInteractionResponseCallbackData, ModalComponentData, ModalBuilder, TextBasedChannel, PartialGroupDMChannel, ChatInputCommandInteraction, UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, RepliableInteraction, InteractionReplyOptions, InteractionResponse, PermissionsBitField, APIApplicationCommandChannelOption, CommandInteractionOption, Attachment, ApplicationCommandOptionType, LocalizationMap, APIApplicationCommandBasicOption, AutocompleteInteraction, RESTPostAPIChatInputApplicationCommandsJSONBody, RESTPostAPIApplicationCommandsJSONBody, REST, RESTPutAPIApplicationCommandsResult, RESTPutAPIApplicationGuildCommandsResult, ClientEvents, ButtonInteraction, ChannelSelectMenuInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, RoleSelectMenuInteraction, MentionableSelectMenuInteraction, Interaction, MessagePayload, MessageReplyOptions, MessageCreateOptions, GatewayIntentBits, ClientOptions, RESTPostAPIContextMenuApplicationCommandsJSONBody, BaseMessageOptions, InteractionUpdateOptions, ButtonBuilder, ButtonStyle, ComponentEmojiResolvable, ChannelSelectMenuBuilder, MentionableSelectMenuBuilder, TextInputStyle, RoleSelectMenuBuilder, StringSelectMenuBuilder, SelectMenuComponentOptionData, UserSelectMenuBuilder, ChannelType, MessageActionRowComponentBuilder, ActionRowBuilder } from 'discord.js';
|
|
3
3
|
export * from 'discord.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -255,6 +255,34 @@ declare function parseDuration(input: string): number | null;
|
|
|
255
255
|
declare function discordTimestamp(date: Date | number, style?: DiscordTimestampStyle): string;
|
|
256
256
|
/** Short-hand for the relative Discord timestamp (`R` style). */
|
|
257
257
|
declare function relativeTimestamp(date: Date | number): string;
|
|
258
|
+
/** The hard cap Discord enforces on a single message's `content`. */
|
|
259
|
+
declare const MESSAGE_CHARACTER_LIMIT = 2000;
|
|
260
|
+
/**
|
|
261
|
+
* Truncate `text` to at most `max` characters, appending `suffix` (default `…`)
|
|
262
|
+
* when it had to cut. The result — suffix included — never exceeds `max`.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* truncate("a very long reason", 10); // → "a very lo…"
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
declare function truncate(text: string, max: number, suffix?: string): string;
|
|
270
|
+
/** Options for {@link chunkMessage}. */
|
|
271
|
+
interface ChunkOptions {
|
|
272
|
+
/** Maximum characters per chunk. Default {@link MESSAGE_CHARACTER_LIMIT} (2000). */
|
|
273
|
+
max?: number;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Split `text` into chunks that each fit within Discord's per-message limit,
|
|
277
|
+
* breaking on line boundaries (and word boundaries for over-long lines) so you
|
|
278
|
+
* never silently lose the tail of a long reply.
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts
|
|
282
|
+
* for (const part of chunkMessage(hugeLog)) await ctx.followUp(part);
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
declare function chunkMessage(text: string, options?: ChunkOptions): string[];
|
|
258
286
|
|
|
259
287
|
/**
|
|
260
288
|
* Pluggable cache abstraction with TTL, counters and rate-limit primitives.
|
|
@@ -348,6 +376,96 @@ declare function lookup<K extends string, V>(table: Readonly<Record<K, V>>, reso
|
|
|
348
376
|
/** Build a non-throwing lookup that returns `undefined` for missing keys. */
|
|
349
377
|
declare function lookupOptional<K extends string, V>(table: Readonly<Record<K, V>>): (key: K) => V | undefined;
|
|
350
378
|
|
|
379
|
+
/**
|
|
380
|
+
* A minimal async key-value store. Values must be JSON-serialisable. All
|
|
381
|
+
* backends share these semantics so you can develop against {@link MemoryStore}
|
|
382
|
+
* and ship with {@link JsonStore} (or your own) without code changes.
|
|
383
|
+
*/
|
|
384
|
+
interface KeyValueStore {
|
|
385
|
+
/** Resolve the value for `key`, or `undefined` if absent. */
|
|
386
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
387
|
+
/** Store `value` under `key`, overwriting any previous value. */
|
|
388
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
389
|
+
/** Whether `key` currently has a value. */
|
|
390
|
+
has(key: string): Promise<boolean>;
|
|
391
|
+
/** Remove `key`. Resolves `true` if it existed. */
|
|
392
|
+
delete(key: string): Promise<boolean>;
|
|
393
|
+
/** Every key currently stored. */
|
|
394
|
+
keys(): Promise<string[]>;
|
|
395
|
+
/** Remove every key. */
|
|
396
|
+
clear(): Promise<void>;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* In-memory {@link KeyValueStore}. Values are deep-cloned on read and write so
|
|
400
|
+
* callers can't accidentally mutate stored state — matching what a persistent
|
|
401
|
+
* backend would do. Ideal for tests and ephemeral data.
|
|
402
|
+
*/
|
|
403
|
+
declare class MemoryStore implements KeyValueStore {
|
|
404
|
+
private readonly map;
|
|
405
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
406
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
407
|
+
has(key: string): Promise<boolean>;
|
|
408
|
+
delete(key: string): Promise<boolean>;
|
|
409
|
+
keys(): Promise<string[]>;
|
|
410
|
+
clear(): Promise<void>;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* File-backed {@link KeyValueStore} persisting the whole map as one JSON object.
|
|
414
|
+
* Reads are served from an in-memory cache (loaded once, lazily); writes are
|
|
415
|
+
* serialised through a queue and committed atomically (temp file + rename) so a
|
|
416
|
+
* crash mid-write can never corrupt the file.
|
|
417
|
+
*/
|
|
418
|
+
declare class JsonStore implements KeyValueStore {
|
|
419
|
+
private readonly path;
|
|
420
|
+
private readonly cache;
|
|
421
|
+
private loading?;
|
|
422
|
+
private writeChain;
|
|
423
|
+
constructor(path: string);
|
|
424
|
+
private ensureLoaded;
|
|
425
|
+
private load;
|
|
426
|
+
/** Queue an atomic write of the current cache; serialised against prior writes. */
|
|
427
|
+
private persist;
|
|
428
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
429
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
430
|
+
has(key: string): Promise<boolean>;
|
|
431
|
+
delete(key: string): Promise<boolean>;
|
|
432
|
+
keys(): Promise<string[]>;
|
|
433
|
+
clear(): Promise<void>;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Wrap a store so every key is transparently prefixed with `${prefix}:`. Lets
|
|
437
|
+
* several features share one backing file without key collisions.
|
|
438
|
+
*/
|
|
439
|
+
declare function namespaced(store: KeyValueStore, prefix: string): KeyValueStore;
|
|
440
|
+
/** A typed settings accessor returned by {@link createSettings}. */
|
|
441
|
+
interface SettingsManager<T extends Record<string, unknown>> {
|
|
442
|
+
/** The defaults merged into every {@link get}. */
|
|
443
|
+
readonly defaults: T;
|
|
444
|
+
/** The underlying store. */
|
|
445
|
+
readonly store: KeyValueStore;
|
|
446
|
+
/** Read `id`'s settings, always fully populated from {@link defaults}. */
|
|
447
|
+
get(id: string): Promise<T>;
|
|
448
|
+
/** Shallow-merge `patch` into `id`'s stored settings and persist; returns the merged result. */
|
|
449
|
+
set(id: string, patch: Partial<T>): Promise<T>;
|
|
450
|
+
/** Restore `id` to defaults by removing its stored overrides. */
|
|
451
|
+
reset(id: string): Promise<void>;
|
|
452
|
+
}
|
|
453
|
+
/** Options for {@link createSettings}. */
|
|
454
|
+
interface CreateSettingsOptions<T extends Record<string, unknown>> {
|
|
455
|
+
/** Backing store (e.g. `new JsonStore(path)`). */
|
|
456
|
+
store: KeyValueStore;
|
|
457
|
+
/** Default values applied to ids with no (or partial) stored settings. */
|
|
458
|
+
defaults: T;
|
|
459
|
+
/** Key prefix; lets one store hold several settings groups. Default `"settings"`. */
|
|
460
|
+
namespace?: string;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Build a typed, defaults-merged settings accessor over a {@link KeyValueStore}.
|
|
464
|
+
* `get` always returns a complete object (stored overrides on top of defaults),
|
|
465
|
+
* and `set` only persists the overrides — so widening `defaults` later is safe.
|
|
466
|
+
*/
|
|
467
|
+
declare function createSettings<T extends Record<string, unknown>>(options: CreateSettingsOptions<T>): SettingsManager<T>;
|
|
468
|
+
|
|
351
469
|
/**
|
|
352
470
|
* Declarative preconditions ("guards") that run before a command, component
|
|
353
471
|
* or prefix-command handler. Replaces the role/permission/guild-only/owner
|
|
@@ -408,6 +526,345 @@ declare function requireBotPermissions(permission: PermissionResolvable, reason?
|
|
|
408
526
|
/** Inline custom predicate; sugar so a one-off check still types as a Guard. */
|
|
409
527
|
declare function guard<TCtx extends GuardContext = GuardContext>(predicate: Guard<TCtx>): Guard<TCtx>;
|
|
410
528
|
|
|
529
|
+
/**
|
|
530
|
+
* Permission and role-hierarchy preflight helpers for moderation-style actions.
|
|
531
|
+
*
|
|
532
|
+
* Two failures dominate moderation bots: doing work and *then* hitting a
|
|
533
|
+
* `Missing Permissions` (50013) error, and trying to ban/kick/timeout a member
|
|
534
|
+
* who is above the bot (or above the moderator) in the role list. Both are
|
|
535
|
+
* checkable up front. These helpers compute exactly what's missing so you can
|
|
536
|
+
* bail out with a clear message before touching the API.
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* const missing = botMissingPermissions(ctx.channel, [PermissionFlagsBits.ManageMessages]);
|
|
541
|
+
* if (missing.length) return ctx.error(`I need: ${formatPermissions(missing)}`);
|
|
542
|
+
*
|
|
543
|
+
* const check = moderationCheck({ moderator: ctx.member, target, action: "ban" });
|
|
544
|
+
* if (!check.ok) return ctx.error(check.reason);
|
|
545
|
+
* await target.ban();
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
|
|
549
|
+
/** A member or role whose permissions are being resolved in a channel. */
|
|
550
|
+
type PermissionHolder = GuildMember | Role;
|
|
551
|
+
/**
|
|
552
|
+
* Return the names of the `required` permissions that `who` does NOT have in
|
|
553
|
+
* `channel` (taking channel overwrites and Administrator into account). An empty
|
|
554
|
+
* array means every required permission is granted. When permissions can't be
|
|
555
|
+
* resolved (e.g. the member isn't cached) every required permission is reported
|
|
556
|
+
* missing.
|
|
557
|
+
*/
|
|
558
|
+
declare function missingPermissions(channel: GuildBasedChannel, who: PermissionHolder, required: PermissionResolvable): PermissionsString[];
|
|
559
|
+
/**
|
|
560
|
+
* Like {@link missingPermissions} but for the bot's own member in `channel`.
|
|
561
|
+
* Resolves `channel.guild.members.me`; if that isn't available, every required
|
|
562
|
+
* permission is reported missing.
|
|
563
|
+
*/
|
|
564
|
+
declare function botMissingPermissions(channel: GuildBasedChannel, required: PermissionResolvable): PermissionsString[];
|
|
565
|
+
/** Whether `who` has all of `required` in `channel`. */
|
|
566
|
+
declare function hasPermissions(channel: GuildBasedChannel, who: PermissionHolder, required: PermissionResolvable): boolean;
|
|
567
|
+
/**
|
|
568
|
+
* Compare two members by their highest role position. Returns a positive number
|
|
569
|
+
* when `a` is above `b`, negative when below, `0` when equal. This is the raw
|
|
570
|
+
* comparison Discord enforces for moderation actions.
|
|
571
|
+
*/
|
|
572
|
+
declare function compareRoles(a: GuildMember, b: GuildMember): number;
|
|
573
|
+
/**
|
|
574
|
+
* Whether `actor` outranks `target` enough to act on them: not the same member,
|
|
575
|
+
* `target` isn't the guild owner, and `actor` is either the owner or holds a
|
|
576
|
+
* higher top role.
|
|
577
|
+
*/
|
|
578
|
+
declare function canActOn(actor: GuildMember, target: GuildMember): boolean;
|
|
579
|
+
/** The result of a {@link moderationCheck}: pass, or fail with a reason. */
|
|
580
|
+
type ModerationCheckResult = {
|
|
581
|
+
ok: true;
|
|
582
|
+
} | {
|
|
583
|
+
ok: false;
|
|
584
|
+
reason: string;
|
|
585
|
+
};
|
|
586
|
+
/** Options for {@link moderationCheck}. */
|
|
587
|
+
interface ModerationCheckOptions {
|
|
588
|
+
/** The member attempting the action. */
|
|
589
|
+
moderator: GuildMember;
|
|
590
|
+
/** The member the action targets. */
|
|
591
|
+
target: GuildMember;
|
|
592
|
+
/**
|
|
593
|
+
* The bot's own member. Defaults to `target.guild.members.me`. Pass `null` to
|
|
594
|
+
* skip the bot-hierarchy check (e.g. when the action doesn't need it).
|
|
595
|
+
*/
|
|
596
|
+
me?: GuildMember | null;
|
|
597
|
+
/** Verb used in the failure messages, e.g. `"ban"`. Default `"moderate"`. */
|
|
598
|
+
action?: string;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Validate that both the moderator and the bot may act on `target`, returning a
|
|
602
|
+
* ready-to-show reason on the first failing rule. Checks, in order: acting on
|
|
603
|
+
* self, acting on the server owner, moderator role hierarchy, and bot role
|
|
604
|
+
* hierarchy.
|
|
605
|
+
*/
|
|
606
|
+
declare function moderationCheck(options: ModerationCheckOptions): ModerationCheckResult;
|
|
607
|
+
/**
|
|
608
|
+
* Render permission flag names into a human, comma-separated string. Accepts a
|
|
609
|
+
* {@link PermissionsString} array (the output of {@link missingPermissions}) or
|
|
610
|
+
* anything {@link PermissionResolvable}.
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* formatPermissions(botMissingPermissions(ctx.channel, [PermissionFlagsBits.BanMembers]));
|
|
615
|
+
* // → "Ban Members"
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
declare function formatPermissions(permissions: PermissionResolvable): string;
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Discord API error helpers — turn opaque `DiscordAPIError` throws into
|
|
622
|
+
* something you can branch on and show to users.
|
|
623
|
+
*
|
|
624
|
+
* discord.js surfaces REST failures as {@link DiscordAPIError} with a numeric
|
|
625
|
+
* `code` (e.g. `10062` "Unknown interaction", `50013` "Missing permissions").
|
|
626
|
+
* Memorising those numbers is a chore, and `try/catch` blocks that re-throw
|
|
627
|
+
* everything turn small, recoverable failures (a deleted message, a closed DM)
|
|
628
|
+
* into crashes or scary stack traces. This module gives you named codes, a
|
|
629
|
+
* type-narrowing predicate, and a friendly, end-user-appropriate explanation.
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```ts
|
|
633
|
+
* try {
|
|
634
|
+
* await message.delete();
|
|
635
|
+
* } catch (err) {
|
|
636
|
+
* if (isDiscordError(err, DiscordErrorCode.UnknownMessage)) return; // already gone
|
|
637
|
+
* throw err;
|
|
638
|
+
* }
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* The Discord JSON error codes spearkit cares about most, by readable name.
|
|
644
|
+
* This is a curated subset of discord.js' {@link RESTJSONErrorCodes} covering
|
|
645
|
+
* the failures bots actually hit and can recover from. Values are the numeric
|
|
646
|
+
* codes Discord returns on `DiscordAPIError.code`.
|
|
647
|
+
*/
|
|
648
|
+
declare const DiscordErrorCode: {
|
|
649
|
+
/** A referenced channel no longer exists or is invisible to the bot. */
|
|
650
|
+
readonly UnknownChannel: RESTJSONErrorCodes.UnknownChannel;
|
|
651
|
+
/** The targeted guild is gone or the bot was removed from it. */
|
|
652
|
+
readonly UnknownGuild: RESTJSONErrorCodes.UnknownGuild;
|
|
653
|
+
/** The referenced member is not in the guild. */
|
|
654
|
+
readonly UnknownMember: RESTJSONErrorCodes.UnknownMember;
|
|
655
|
+
/** The message was deleted (or never existed) before the action ran. */
|
|
656
|
+
readonly UnknownMessage: RESTJSONErrorCodes.UnknownMessage;
|
|
657
|
+
/** The user could not be resolved. */
|
|
658
|
+
readonly UnknownUser: RESTJSONErrorCodes.UnknownUser;
|
|
659
|
+
/** The interaction token expired (the classic 3-second-window failure). */
|
|
660
|
+
readonly UnknownInteraction: RESTJSONErrorCodes.UnknownInteraction;
|
|
661
|
+
/** The bot lacks access to the resource entirely (not just one permission). */
|
|
662
|
+
readonly MissingAccess: RESTJSONErrorCodes.MissingAccess;
|
|
663
|
+
/** Action attempted on a DM channel that does not support it. */
|
|
664
|
+
readonly CannotExecuteActionOnDMChannel: RESTJSONErrorCodes.CannotExecuteActionOnDMChannel;
|
|
665
|
+
/** The target user has DMs closed or blocked the bot. */
|
|
666
|
+
readonly CannotSendMessagesToThisUser: RESTJSONErrorCodes.CannotSendMessagesToThisUser;
|
|
667
|
+
/** The bot is missing one or more permissions required for the action. */
|
|
668
|
+
readonly MissingPermissions: RESTJSONErrorCodes.MissingPermissions;
|
|
669
|
+
/** The request body failed Discord's validation. */
|
|
670
|
+
readonly InvalidFormBodyOrContentType: RESTJSONErrorCodes.InvalidFormBodyOrContentType;
|
|
671
|
+
/** The interaction was already acknowledged elsewhere. */
|
|
672
|
+
readonly InteractionHasAlreadyBeenAcknowledged: RESTJSONErrorCodes.InteractionHasAlreadyBeenAcknowledged;
|
|
673
|
+
/** The bot reached the maximum number of guilds it may join. */
|
|
674
|
+
readonly MaximumNumberOfGuildsReached: RESTJSONErrorCodes.MaximumNumberOfGuildsReached;
|
|
675
|
+
/** Too many active reactions / pins / etc. of this kind. */
|
|
676
|
+
readonly MaximumNumberOfReactionsReached: RESTJSONErrorCodes.MaximumNumberOfReactionsReached;
|
|
677
|
+
};
|
|
678
|
+
/** A numeric Discord JSON error code value. */
|
|
679
|
+
type DiscordErrorCodeValue = (typeof DiscordErrorCode)[keyof typeof DiscordErrorCode];
|
|
680
|
+
/**
|
|
681
|
+
* Narrow an unknown thrown value to a {@link DiscordAPIError}. Pass a `code`
|
|
682
|
+
* (or several) to also assert the specific failure — ideal for "ignore this
|
|
683
|
+
* one error, re-throw the rest" recovery.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* if (isDiscordError(err, [DiscordErrorCode.UnknownMessage, DiscordErrorCode.UnknownChannel])) return;
|
|
688
|
+
* ```
|
|
689
|
+
*/
|
|
690
|
+
declare function isDiscordError(error: unknown, code?: number | string | readonly (number | string)[]): error is DiscordAPIError;
|
|
691
|
+
/**
|
|
692
|
+
* Narrow to a transport-level {@link HTTPError} (timeouts, 5xx, aborted
|
|
693
|
+
* requests) — failures with an HTTP status but no Discord JSON code.
|
|
694
|
+
*/
|
|
695
|
+
declare function isHTTPError(error: unknown): error is HTTPError;
|
|
696
|
+
/** Whether the thrown value is a Discord rate-limit (HTTP 429) response. */
|
|
697
|
+
declare function isRateLimitError(error: unknown): boolean;
|
|
698
|
+
/**
|
|
699
|
+
* Render an end-user-appropriate sentence for a Discord error, or `null` if the
|
|
700
|
+
* error isn't a recognised, explainable Discord failure (in which case you
|
|
701
|
+
* should fall back to a generic "something went wrong" message and log it).
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```ts
|
|
705
|
+
* catch (err) { await ctx.error(explainDiscordError(err) ?? "Something went wrong."); }
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
declare function explainDiscordError(error: unknown): string | null;
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Graceful shutdown — close the bot cleanly on `SIGINT`/`SIGTERM`.
|
|
712
|
+
*
|
|
713
|
+
* A `Ctrl-C` or a container stop sends a signal; if you don't handle it the
|
|
714
|
+
* process dies mid-flight, leaving the gateway connection, scheduler timers and
|
|
715
|
+
* any open handles to be reaped abruptly. {@link gracefulShutdown} runs an
|
|
716
|
+
* optional hook, calls `client.destroy()` (which also stops spearkit's
|
|
717
|
+
* scheduler), and exits — with a hard timeout so a wedged shutdown can't hang
|
|
718
|
+
* forever.
|
|
719
|
+
*
|
|
720
|
+
* @example
|
|
721
|
+
* ```ts
|
|
722
|
+
* gracefulShutdown(client, { onShutdown: () => db.close() });
|
|
723
|
+
* // or, on a SpearClient:
|
|
724
|
+
* client.enableGracefulShutdown({ onShutdown: () => db.close() });
|
|
725
|
+
* ```
|
|
726
|
+
*/
|
|
727
|
+
|
|
728
|
+
/** Anything with an async-or-sync `destroy()` — a discord.js `Client` qualifies. */
|
|
729
|
+
interface Destroyable {
|
|
730
|
+
destroy(): Awaitable<void>;
|
|
731
|
+
}
|
|
732
|
+
/** Minimal logger shape used for shutdown progress (your `client.logger` fits). */
|
|
733
|
+
interface ShutdownLogger {
|
|
734
|
+
info?(message: string): void;
|
|
735
|
+
error?(message: string, meta?: unknown): void;
|
|
736
|
+
}
|
|
737
|
+
/** Options for {@link gracefulShutdown}. */
|
|
738
|
+
interface GracefulShutdownOptions {
|
|
739
|
+
/** Signals to listen for. Default `["SIGINT", "SIGTERM"]`. */
|
|
740
|
+
signals?: readonly NodeJS.Signals[];
|
|
741
|
+
/** Force-exit if shutdown takes longer than this many ms. Default `10000`. */
|
|
742
|
+
timeoutMs?: number;
|
|
743
|
+
/** Call `process.exit()` when done. Default `true`. Set `false` in tests. */
|
|
744
|
+
exit?: boolean;
|
|
745
|
+
/** Runs before `client.destroy()` — flush databases, close connections, etc. */
|
|
746
|
+
onShutdown?: (signal: NodeJS.Signals) => Awaitable<void>;
|
|
747
|
+
/** Optional progress logger. */
|
|
748
|
+
logger?: ShutdownLogger;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Wire signal handlers that gracefully tear `client` down once, then exit.
|
|
752
|
+
* Returns a disposer that removes the handlers (handy for tests/hot-reload).
|
|
753
|
+
*/
|
|
754
|
+
declare function gracefulShutdown(client: Destroyable, options?: GracefulShutdownOptions): () => void;
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Collector ergonomics — wait for a reply, a click, or a modal without the
|
|
758
|
+
* boilerplate (and footguns) of raw discord.js collectors.
|
|
759
|
+
*
|
|
760
|
+
* discord.js collectors are powerful but fiddly: you wire an event emitter, set
|
|
761
|
+
* a `time`, write a `filter`, remember that modal submissions can be dismissed
|
|
762
|
+
* (so they need their own timeout), and translate the "timed out" rejection into
|
|
763
|
+
* something your code can branch on. These helpers collapse the common cases to
|
|
764
|
+
* a single `await` that resolves to the result — or `null` on timeout.
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* ```ts
|
|
768
|
+
* await ctx.reply("What's your favourite colour?");
|
|
769
|
+
* const reply = await ctx.awaitMessageFrom(); // same user, same channel
|
|
770
|
+
* if (reply === null) return ctx.followUp("Timed out.");
|
|
771
|
+
* await ctx.followUp(`Nice — ${reply.content}!`);
|
|
772
|
+
* ```
|
|
773
|
+
*/
|
|
774
|
+
|
|
775
|
+
/** Options for {@link awaitMessage}. */
|
|
776
|
+
interface AwaitMessageOptions {
|
|
777
|
+
/** Only accept messages passing this predicate. */
|
|
778
|
+
filter?: (message: Message) => boolean;
|
|
779
|
+
/** How long to wait, in ms. Default `60000`. */
|
|
780
|
+
time?: number;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* A text-based channel that can collect messages — every {@link TextBasedChannel}
|
|
784
|
+
* except `PartialGroupDMChannel` (which has no message manager).
|
|
785
|
+
*/
|
|
786
|
+
type CollectableChannel = Exclude<TextBasedChannel, PartialGroupDMChannel>;
|
|
787
|
+
/**
|
|
788
|
+
* Wait for the next message in `channel` that matches `filter`, resolving to the
|
|
789
|
+
* `Message` or `null` if none arrives before `time` elapses.
|
|
790
|
+
*/
|
|
791
|
+
declare function awaitMessage(channel: CollectableChannel, options?: AwaitMessageOptions): Promise<Message | null>;
|
|
792
|
+
/** Options for {@link awaitComponent}. */
|
|
793
|
+
interface AwaitComponentOptions {
|
|
794
|
+
/** Only accept interactions passing this predicate. */
|
|
795
|
+
filter?: (interaction: MessageComponentInteraction) => boolean;
|
|
796
|
+
/** How long to wait, in ms. Default `60000`. */
|
|
797
|
+
time?: number;
|
|
798
|
+
/** Restrict to one component kind (e.g. `ComponentType.Button`). */
|
|
799
|
+
componentType?: ComponentType;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Wait for the next component interaction (button/select click) on `message`,
|
|
803
|
+
* resolving to it or `null` on timeout. Note: you must still acknowledge the
|
|
804
|
+
* returned interaction (`update`/`deferUpdate`/`reply`).
|
|
805
|
+
*/
|
|
806
|
+
declare function awaitComponent(message: Message, options?: AwaitComponentOptions): Promise<MessageComponentInteraction | null>;
|
|
807
|
+
/** A modal in any of the forms discord.js' `showModal` accepts. */
|
|
808
|
+
type ModalLike = JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData | ModalBuilder;
|
|
809
|
+
/** Interactions that can open a modal and await its submission. */
|
|
810
|
+
type ModalShowingInteraction = ChatInputCommandInteraction | MessageComponentInteraction | UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction;
|
|
811
|
+
/** Options for {@link showAndAwaitModal}. */
|
|
812
|
+
interface AwaitModalOptions {
|
|
813
|
+
/** How long to wait for submission, in ms. Default `120000`. */
|
|
814
|
+
time?: number;
|
|
815
|
+
/** Extra predicate on the submitted modal (already scoped to this user + modal). */
|
|
816
|
+
filter?: (interaction: ModalSubmitInteraction) => boolean;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Show `modal` on `interaction`, then wait for its submission — scoped to the
|
|
820
|
+
* same user and the modal's own custom-id — resolving to the
|
|
821
|
+
* {@link ModalSubmitInteraction} or `null` if the user dismisses it / it times
|
|
822
|
+
* out. Sidesteps the "Unknown interaction after cancelling a modal" trap by
|
|
823
|
+
* always bounding the wait.
|
|
824
|
+
*/
|
|
825
|
+
declare function showAndAwaitModal(interaction: ModalShowingInteraction, modal: ModalLike, options?: AwaitModalOptions): Promise<ModalSubmitInteraction | null>;
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Auto-defer — the antidote to `DiscordAPIError[10062]: Unknown interaction`.
|
|
829
|
+
*
|
|
830
|
+
* An interaction token is only valid for 3 seconds before the *first* response.
|
|
831
|
+
* Any handler that awaits a database query, an HTTP call, or anything else slow
|
|
832
|
+
* blows past that window and the interaction dies. The fix is always the same:
|
|
833
|
+
* `deferReply()` early. Auto-defer does it for you — it arms a timer when the
|
|
834
|
+
* handler starts and, if the handler hasn't responded in time, defers
|
|
835
|
+
* automatically. Cancelled the instant your handler replies/defers itself.
|
|
836
|
+
*
|
|
837
|
+
* Enable per command (`command({ autoDefer: true })`) or globally
|
|
838
|
+
* (`new SpearClient({ autoDefer: true })`). With it on, respond via
|
|
839
|
+
* `ctx.send(...)` / `ctx.editReply(...)` rather than `ctx.reply(...)`, since the
|
|
840
|
+
* reply slot may already be taken by the auto-defer.
|
|
841
|
+
*/
|
|
842
|
+
|
|
843
|
+
/** How a handler opts into auto-defer: `true` for defaults, or fine-tuning. */
|
|
844
|
+
type AutoDeferInput = boolean | {
|
|
845
|
+
ephemeral?: boolean;
|
|
846
|
+
delayMs?: number;
|
|
847
|
+
};
|
|
848
|
+
/** Resolved auto-defer settings. */
|
|
849
|
+
interface AutoDeferConfig {
|
|
850
|
+
/** Defer as an ephemeral ("thinking…" hidden) response. */
|
|
851
|
+
ephemeral: boolean;
|
|
852
|
+
/** Delay before the safety defer fires, in ms. Kept under Discord's 3s window. */
|
|
853
|
+
delayMs: number;
|
|
854
|
+
}
|
|
855
|
+
/** Default safety margin: defer at 2s, leaving headroom before the 3s cutoff. */
|
|
856
|
+
declare const DEFAULT_AUTO_DEFER_DELAY_MS = 2000;
|
|
857
|
+
/** Normalise an {@link AutoDeferInput} (or `undefined`) into a config, or `undefined` when disabled. */
|
|
858
|
+
declare function normalizeAutoDefer(input: AutoDeferInput | undefined): AutoDeferConfig | undefined;
|
|
859
|
+
/** Interactions auto-defer supports (those answered with `deferReply`). */
|
|
860
|
+
type AutoDeferrableInteraction = ChatInputCommandInteraction | UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction;
|
|
861
|
+
/**
|
|
862
|
+
* Arm a one-shot timer that calls `deferReply()` if the interaction is still
|
|
863
|
+
* un-acknowledged when it fires. Returns a cancel function — always call it
|
|
864
|
+
* once your handler settles (e.g. in a `finally`) to disarm the timer.
|
|
865
|
+
*/
|
|
866
|
+
declare function armAutoDefer(interaction: AutoDeferrableInteraction, config: AutoDeferConfig): () => void;
|
|
867
|
+
|
|
411
868
|
/** Reply options with an ergonomic `ephemeral` shortcut (mapped to flags). */
|
|
412
869
|
type ReplyData = InteractionReplyOptions & {
|
|
413
870
|
ephemeral?: boolean;
|
|
@@ -456,6 +913,22 @@ declare abstract class BaseContext<I extends RepliableInteraction = RepliableInt
|
|
|
456
913
|
* most handlers ever need.
|
|
457
914
|
*/
|
|
458
915
|
send(input: ReplyInput): Promise<void>;
|
|
916
|
+
/** The bot's resolved permissions in the current channel. */
|
|
917
|
+
get botPermissions(): Readonly<PermissionsBitField>;
|
|
918
|
+
/**
|
|
919
|
+
* Permission flag names the BOT is missing in the current channel — empty when
|
|
920
|
+
* it has them all. Zero-fetch: reads the permissions Discord attached to the
|
|
921
|
+
* interaction. Use before an action that needs elevated permissions.
|
|
922
|
+
*/
|
|
923
|
+
botMissing(required: PermissionResolvable): PermissionsString[];
|
|
924
|
+
/** Permission flag names the invoking USER is missing in the current channel. */
|
|
925
|
+
userMissing(required: PermissionResolvable): PermissionsString[];
|
|
926
|
+
/**
|
|
927
|
+
* Wait for the next message in this channel from `userId` (defaults to the
|
|
928
|
+
* invoking user), resolving to it or `null` on timeout. The "type your answer"
|
|
929
|
+
* flow without hand-rolling a collector.
|
|
930
|
+
*/
|
|
931
|
+
awaitMessageFrom(userId?: string, options?: AwaitMessageOptions): Promise<Message | null>;
|
|
459
932
|
/** Get the configured {@link Embeds} factory — `client.embeds` or the default. */
|
|
460
933
|
protected getEmbeds(): Embeds;
|
|
461
934
|
/** State-aware send of a red error embed. Defaults to ephemeral. */
|
|
@@ -801,6 +1274,11 @@ declare class CommandContext<O extends OptionMap = OptionMap> extends BaseContex
|
|
|
801
1274
|
get subcommand(): string | null;
|
|
802
1275
|
/** Present a modal to the user in response to this command. */
|
|
803
1276
|
showModal(modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData | ModalBuilder): Promise<void>;
|
|
1277
|
+
/**
|
|
1278
|
+
* Show a modal and wait for the user to submit it, resolving to the submission
|
|
1279
|
+
* or `null` if they dismiss it / it times out. Scoped to this user and modal.
|
|
1280
|
+
*/
|
|
1281
|
+
awaitModal(modal: ModalLike, options?: AwaitModalOptions): Promise<ModalSubmitInteraction | null>;
|
|
804
1282
|
}
|
|
805
1283
|
/**
|
|
806
1284
|
* The handler argument for autocomplete requests. Provides the focused value
|
|
@@ -836,6 +1314,12 @@ interface CommonMeta {
|
|
|
836
1314
|
cooldown?: CooldownInput;
|
|
837
1315
|
/** Preconditions evaluated before the handler runs. */
|
|
838
1316
|
guards?: readonly Guard[];
|
|
1317
|
+
/**
|
|
1318
|
+
* Auto-`deferReply()` if the handler hasn't responded within ~2s, preventing
|
|
1319
|
+
* `Unknown interaction` (10062) on slow work. `true` for defaults, or
|
|
1320
|
+
* `{ ephemeral, delayMs }`. With it on, respond via `ctx.send`/`ctx.editReply`.
|
|
1321
|
+
*/
|
|
1322
|
+
autoDefer?: AutoDeferInput;
|
|
839
1323
|
}
|
|
840
1324
|
/** Configuration for a leaf (non-subcommand) slash command. */
|
|
841
1325
|
interface CommandConfig<O extends OptionMap, R> extends CommonMeta {
|
|
@@ -890,6 +1374,7 @@ interface SlashCommandSpec {
|
|
|
890
1374
|
autocompleter: (interaction: AutocompleteInteraction) => Promise<void>;
|
|
891
1375
|
cooldown?: CooldownConfig;
|
|
892
1376
|
guards?: readonly Guard[];
|
|
1377
|
+
autoDefer?: AutoDeferConfig;
|
|
893
1378
|
}
|
|
894
1379
|
/**
|
|
895
1380
|
* A registered slash command. Serialises itself for the discord REST API and
|
|
@@ -908,6 +1393,8 @@ declare class SlashCommand {
|
|
|
908
1393
|
readonly cooldown?: CooldownConfig;
|
|
909
1394
|
/** Resolved guard list for this command, if any. */
|
|
910
1395
|
readonly guards?: readonly Guard[];
|
|
1396
|
+
/** Resolved auto-defer configuration for this command, if any. */
|
|
1397
|
+
readonly autoDefer?: AutoDeferConfig;
|
|
911
1398
|
/** @internal */
|
|
912
1399
|
constructor(spec: SlashCommandSpec);
|
|
913
1400
|
/** Serialise to the discord REST chat-input command payload. */
|
|
@@ -962,6 +1449,7 @@ declare class CommandRegistry {
|
|
|
962
1449
|
private defaultCooldown?;
|
|
963
1450
|
private defaultGuards;
|
|
964
1451
|
private onUsage?;
|
|
1452
|
+
private defaultAutoDefer?;
|
|
965
1453
|
/** Register one or more commands. Later registrations override by name. */
|
|
966
1454
|
add(...commands: SlashCommand[]): this;
|
|
967
1455
|
/** Remove a command by name. */
|
|
@@ -982,6 +1470,8 @@ declare class CommandRegistry {
|
|
|
982
1470
|
setCooldowns(manager: CooldownManager, defaultCooldown?: CooldownConfig): this;
|
|
983
1471
|
/** Guards that run before every command's own guards. */
|
|
984
1472
|
setDefaultGuards(guards: readonly Guard[]): this;
|
|
1473
|
+
/** Default auto-defer applied to commands that don't set their own. */
|
|
1474
|
+
setAutoDefer(config?: AutoDeferConfig): this;
|
|
985
1475
|
/** Attach a hook called after each successful command execution. */
|
|
986
1476
|
setUsageHook(hook: (event: UsageEvent) => void): this;
|
|
987
1477
|
/** Serialise every command to discord REST payloads. */
|
|
@@ -1440,6 +1930,13 @@ interface PrefixOptions {
|
|
|
1440
1930
|
ignoreBots?: boolean;
|
|
1441
1931
|
/** Match command names case-insensitively. Default `true`. */
|
|
1442
1932
|
caseInsensitive?: boolean;
|
|
1933
|
+
/**
|
|
1934
|
+
* Resolve extra prefix(es) per message — e.g. a custom per-guild prefix from a
|
|
1935
|
+
* database or {@link createSettings}. Returned prefixes are tried in addition
|
|
1936
|
+
* to any static `prefix`. Return `null`/`undefined` for none. Keep it fast
|
|
1937
|
+
* (and cached): it runs on every candidate message.
|
|
1938
|
+
*/
|
|
1939
|
+
dynamic?: (message: Message) => Awaitable<string | readonly string[] | null | undefined>;
|
|
1443
1940
|
}
|
|
1444
1941
|
/** Configuration for a prefix command. */
|
|
1445
1942
|
interface PrefixCommandConfig<TArgs extends Record<string, unknown> = Record<string, never>, R = void> {
|
|
@@ -1542,6 +2039,8 @@ declare class PrefixRegistry {
|
|
|
1542
2039
|
list(): PrefixCommand[];
|
|
1543
2040
|
/** Strip a matching prefix (or bot mention) from `content`, or return `null`. */
|
|
1544
2041
|
private stripPrefix;
|
|
2042
|
+
/** Resolve the effective prefixes for a message: static plus any dynamic ones. */
|
|
2043
|
+
private resolvePrefixes;
|
|
1545
2044
|
/**
|
|
1546
2045
|
* Parse and dispatch a message. Returns `true` when a command ran (or was
|
|
1547
2046
|
* blocked by a cooldown), `false` when the message was not a prefix command.
|
|
@@ -1587,6 +2086,12 @@ interface SpearOptions {
|
|
|
1587
2086
|
embeds?: Embeds | EmbedsOptions;
|
|
1588
2087
|
/** Default guards (preconditions) applied before every command/component/prefix handler. */
|
|
1589
2088
|
guards?: readonly Guard[];
|
|
2089
|
+
/**
|
|
2090
|
+
* Default auto-defer for every slash command and context menu (each handler
|
|
2091
|
+
* may override). Prevents `Unknown interaction` (10062) on slow handlers by
|
|
2092
|
+
* deferring automatically just before Discord's 3-second window closes.
|
|
2093
|
+
*/
|
|
2094
|
+
autoDefer?: AutoDeferInput;
|
|
1590
2095
|
}
|
|
1591
2096
|
/** Options for {@link SpearClient}: discord.js options plus {@link SpearOptions}. `intents` may be omitted. */
|
|
1592
2097
|
type SpearClientOptions = Partial<ClientOptions> & SpearOptions;
|
|
@@ -1679,6 +2184,12 @@ declare class SpearClient extends Client {
|
|
|
1679
2184
|
schedule(config: TaskConfig): ScheduledTask;
|
|
1680
2185
|
/** Stop the scheduler, then tear down the discord.js client. */
|
|
1681
2186
|
destroy(): Promise<void>;
|
|
2187
|
+
/**
|
|
2188
|
+
* Close the bot cleanly on `SIGINT`/`SIGTERM`: run an optional hook, then
|
|
2189
|
+
* `destroy()` (stopping the scheduler and gateway), then exit. Returns a
|
|
2190
|
+
* disposer that removes the signal handlers. Logs progress via `client.logger`.
|
|
2191
|
+
*/
|
|
2192
|
+
enableGracefulShutdown(options?: GracefulShutdownOptions): () => void;
|
|
1682
2193
|
private route;
|
|
1683
2194
|
}
|
|
1684
2195
|
|
|
@@ -1784,6 +2295,8 @@ interface ContextMenuMeta {
|
|
|
1784
2295
|
nameLocalizations?: LocalizationMap;
|
|
1785
2296
|
cooldown?: CooldownInput;
|
|
1786
2297
|
guards?: readonly Guard[];
|
|
2298
|
+
/** Auto-`deferReply()` if the handler is slow, preventing `Unknown interaction`. */
|
|
2299
|
+
autoDefer?: AutoDeferInput;
|
|
1787
2300
|
}
|
|
1788
2301
|
/** Configuration for {@link userCommand}. */
|
|
1789
2302
|
interface UserCommandConfig<R = void> extends ContextMenuMeta {
|
|
@@ -1800,6 +2313,7 @@ interface BaseContextMenuCommand {
|
|
|
1800
2313
|
readonly name: string;
|
|
1801
2314
|
readonly cooldown?: CooldownConfig;
|
|
1802
2315
|
readonly guards?: readonly Guard[];
|
|
2316
|
+
readonly autoDefer?: AutoDeferConfig;
|
|
1803
2317
|
toJSON(): RESTPostAPIContextMenuApplicationCommandsJSONBody;
|
|
1804
2318
|
}
|
|
1805
2319
|
/** A user-target context-menu command. */
|
|
@@ -1839,6 +2353,7 @@ declare class ContextMenuRegistry {
|
|
|
1839
2353
|
private defaultCooldown?;
|
|
1840
2354
|
private defaultGuards;
|
|
1841
2355
|
private onUsage?;
|
|
2356
|
+
private defaultAutoDefer?;
|
|
1842
2357
|
/** Register one or more context-menu commands. */
|
|
1843
2358
|
add(...commands: readonly ContextMenuCommand[]): this;
|
|
1844
2359
|
/** Total number of registered context-menu commands. */
|
|
@@ -1850,6 +2365,8 @@ declare class ContextMenuRegistry {
|
|
|
1850
2365
|
setLogger(logger: Logger): this;
|
|
1851
2366
|
setCooldowns(manager: CooldownManager, defaultCooldown?: CooldownConfig): this;
|
|
1852
2367
|
setDefaultGuards(guards: readonly Guard[]): this;
|
|
2368
|
+
/** Default auto-defer applied to menus that don't set their own. */
|
|
2369
|
+
setAutoDefer(config?: AutoDeferConfig): this;
|
|
1853
2370
|
setUsageHook(hook: (event: UsageEvent) => void): this;
|
|
1854
2371
|
/** Dispatch a user-target interaction. */
|
|
1855
2372
|
handleUser(interaction: UserContextMenuCommandInteraction): Promise<void>;
|
|
@@ -2041,6 +2558,11 @@ declare class MessageComponentContext<P, I extends AnyComponentInteraction = Any
|
|
|
2041
2558
|
deferUpdate(): Promise<void>;
|
|
2042
2559
|
/** Open a modal in response to this component. */
|
|
2043
2560
|
showModal(modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData | ModalBuilder): Promise<void>;
|
|
2561
|
+
/**
|
|
2562
|
+
* Show a modal and wait for the user to submit it, resolving to the submission
|
|
2563
|
+
* or `null` if they dismiss it / it times out. Scoped to this user and modal.
|
|
2564
|
+
*/
|
|
2565
|
+
awaitModal(modal: ModalLike, options?: AwaitModalOptions): Promise<ModalSubmitInteraction | null>;
|
|
2044
2566
|
}
|
|
2045
2567
|
/** Context for a button click. */
|
|
2046
2568
|
declare class ButtonContext<P = Record<string, never>> extends MessageComponentContext<P, ButtonInteraction> {
|
|
@@ -2255,4 +2777,4 @@ declare function modal<const P extends string, F extends Record<string, TextInpu
|
|
|
2255
2777
|
*/
|
|
2256
2778
|
declare function row<C extends MessageActionRowComponentBuilder>(...components: C[]): ActionRowBuilder<C>;
|
|
2257
2779
|
|
|
2258
|
-
export { type AllowedChannelType, type AnyComponentInteraction, type AnyOptionDef, AutocompleteContext, type AutocompleteHandler, BaseContext, type BaseContextMenuCommand, type BuildArgs, type Button, type ButtonConfig, ButtonContext, type ButtonRoute, type ButtonStyleInput, type CacheSetOptions, type CacheStore, type ChannelSelect, ChannelSelectContext, type ChannelSelectRoute, type CommandConfig, CommandContext, type CommandErrorHandler, type CommandGroupConfig, CommandRegistry, type CompiledPattern, type ComponentDef, type ComponentErrorHandler, ComponentRegistry, type ConfirmButtonOptions, type ConfirmButtonStyle, type ConfirmOptions, type ConfirmResult, type ContextMenuCommand, ContextMenuRegistry, type CooldownActor, type CooldownConfig, type CooldownExemptions, type CooldownInput, CooldownManager, type CooldownOverrides, type CooldownResult, type CooldownScope, CronExpression, DEFAULT_EMBED_COLORS, DEFAULT_EMBED_ICONS, type DeployOptions, type DeployResult, type DiscordTimestampStyle, type EmbedColors, type EmbedIcons, type EmbedLevel, type EmbedPresetInput, Embeds, type EmbedsOptions, type EntitySelectConfig, type EnvReader, type EventConfig, type EventDef, type EventHandler, EventRegistry, type FormatDurationOptions, type Guard, type GuardContext, type GuardResult, Intents, JsonFileUsageStore, KeyedLock, type KeyedLockOptions, type LinkButtonConfig, type LoadConfigOptions, type LoadEnvOptions, type LoadOptions, type LockRelease, type LogEntry, type LogLevel, type LogOptions, type LogSink, type LogThreshold, type LogValue, Logger, type LoggerOptions, MAX_CUSTOM_ID_LENGTH, MemoryCache, MemoryUsageStore, type MentionableSelect, MentionableSelectContext, type MentionableSelectRoute, type MessageCommandConfig, MessageComponentContext, type MessageContextMenu, MessageContextMenuContext, type Modal, type ModalConfig, ModalContext, type ModalRoute, type OptionChoice, type OptionDef, type OptionMap, type OptionValue, type PaginateOptions, type PaginateRender, type ParamNames, type Params, type ParsedCustomId, type ParsedEnv, type PrefixArgError, type PrefixArgSpec, PrefixArgsBuilder, type PrefixArgsOk, type PrefixArgsParser, type PrefixCommand, type PrefixCommandConfig, PrefixContext, type PrefixErrorHandler, type PrefixOptions, PrefixRegistry, type RateLimitResult, type Registerable, type ReplyData, type ReplyInput, type ResolvedOption, type ResolvedOptions, type RoleSelect, RoleSelectContext, type RoleSelectRoute, type RunGuardsResult, type SafeFetchOptions, type ScheduledTask, SlashCommand, SpearClient, type SpearClientOptions, type SpearOptions, type SpearPlugin, type StringSelect, type StringSelectConfig, StringSelectContext, type StringSelectRoute, type Subcommand, type SubcommandConfig, type SubcommandGroup, type SubcommandGroupConfig, type TaskConfig, TaskScheduler, type TextInputDef, type TextInputStyleInput, type UsageEvent, type UsageMetaValue, type UsageOptions, type UsageOutcome, type UsageStore, UsageTracker, type UsageType, type UserCommandConfig, type UserContextMenu, UserContextMenuContext, type UserSelect, UserSelectContext, type UserSelectRoute, asEphemeral, buildCustomId, buildPaginatorPage, button, channelSelect, collectModules, command, commandGroup, compilePattern, confirm, consoleSink, createCache, cron, defaultEmbeds, definePlugin, denied, discordTimestamp, dmOnly, effectiveDuration, env, event, fetchChannel, fetchGuild, fetchMember, fetchMessage, fetchRole, fetchUser, formatCooldownMessage, formatDuration, formatUsage, guard, guildOnly, jsonlSink, linkButton, loadConfig, loadConfigAsync, loadEnv, loadInto, lookup, lookupOptional, mentionableSelect, messageCommand, modal, normalizeCooldown, normalizeReply, option, optionsHaveAutocomplete, paginate, paramsFromValues, parseCustomId, parseDuration, parseEnv, prefixArgs, prefixCommand, readOption, relativeTimestamp, requireAllRoles, requireAnyRole, requireBotPermissions, requireOwner, requireUserPermissions, roleSelect, row, runGuards, safeFetch, safeTry, stringSelect, subcommand, subcommandGroup, task, textInput, toAPIOption, toError, userCommand, userSelect, webhookSink, withSafeTimeout };
|
|
2780
|
+
export { type AllowedChannelType, type AnyComponentInteraction, type AnyOptionDef, type AutoDeferConfig, type AutoDeferInput, type AutoDeferrableInteraction, AutocompleteContext, type AutocompleteHandler, type AwaitComponentOptions, type AwaitMessageOptions, type AwaitModalOptions, BaseContext, type BaseContextMenuCommand, type BuildArgs, type Button, type ButtonConfig, ButtonContext, type ButtonRoute, type ButtonStyleInput, type CacheSetOptions, type CacheStore, type ChannelSelect, ChannelSelectContext, type ChannelSelectRoute, type ChunkOptions, type CollectableChannel, type CommandConfig, CommandContext, type CommandErrorHandler, type CommandGroupConfig, CommandRegistry, type CompiledPattern, type ComponentDef, type ComponentErrorHandler, ComponentRegistry, type ConfirmButtonOptions, type ConfirmButtonStyle, type ConfirmOptions, type ConfirmResult, type ContextMenuCommand, ContextMenuRegistry, type CooldownActor, type CooldownConfig, type CooldownExemptions, type CooldownInput, CooldownManager, type CooldownOverrides, type CooldownResult, type CooldownScope, type CreateSettingsOptions, CronExpression, DEFAULT_AUTO_DEFER_DELAY_MS, DEFAULT_EMBED_COLORS, DEFAULT_EMBED_ICONS, type DeployOptions, type DeployResult, type Destroyable, DiscordErrorCode, type DiscordErrorCodeValue, type DiscordTimestampStyle, type EmbedColors, type EmbedIcons, type EmbedLevel, type EmbedPresetInput, Embeds, type EmbedsOptions, type EntitySelectConfig, type EnvReader, type EventConfig, type EventDef, type EventHandler, EventRegistry, type FormatDurationOptions, type GracefulShutdownOptions, type Guard, type GuardContext, type GuardResult, Intents, JsonFileUsageStore, JsonStore, type KeyValueStore, KeyedLock, type KeyedLockOptions, type LinkButtonConfig, type LoadConfigOptions, type LoadEnvOptions, type LoadOptions, type LockRelease, type LogEntry, type LogLevel, type LogOptions, type LogSink, type LogThreshold, type LogValue, Logger, type LoggerOptions, MAX_CUSTOM_ID_LENGTH, MESSAGE_CHARACTER_LIMIT, MemoryCache, MemoryStore, MemoryUsageStore, type MentionableSelect, MentionableSelectContext, type MentionableSelectRoute, type MessageCommandConfig, MessageComponentContext, type MessageContextMenu, MessageContextMenuContext, type Modal, type ModalConfig, ModalContext, type ModalLike, type ModalRoute, type ModalShowingInteraction, type ModerationCheckOptions, type ModerationCheckResult, type OptionChoice, type OptionDef, type OptionMap, type OptionValue, type PaginateOptions, type PaginateRender, type ParamNames, type Params, type ParsedCustomId, type ParsedEnv, type PermissionHolder, type PrefixArgError, type PrefixArgSpec, PrefixArgsBuilder, type PrefixArgsOk, type PrefixArgsParser, type PrefixCommand, type PrefixCommandConfig, PrefixContext, type PrefixErrorHandler, type PrefixOptions, PrefixRegistry, type RateLimitResult, type Registerable, type ReplyData, type ReplyInput, type ResolvedOption, type ResolvedOptions, type RoleSelect, RoleSelectContext, type RoleSelectRoute, type RunGuardsResult, type SafeFetchOptions, type ScheduledTask, type SettingsManager, type ShutdownLogger, SlashCommand, SpearClient, type SpearClientOptions, type SpearOptions, type SpearPlugin, type StringSelect, type StringSelectConfig, StringSelectContext, type StringSelectRoute, type Subcommand, type SubcommandConfig, type SubcommandGroup, type SubcommandGroupConfig, type TaskConfig, TaskScheduler, type TextInputDef, type TextInputStyleInput, type UsageEvent, type UsageMetaValue, type UsageOptions, type UsageOutcome, type UsageStore, UsageTracker, type UsageType, type UserCommandConfig, type UserContextMenu, UserContextMenuContext, type UserSelect, UserSelectContext, type UserSelectRoute, armAutoDefer, asEphemeral, awaitComponent, awaitMessage, botMissingPermissions, buildCustomId, buildPaginatorPage, button, canActOn, channelSelect, chunkMessage, collectModules, command, commandGroup, compareRoles, compilePattern, confirm, consoleSink, createCache, createSettings, cron, defaultEmbeds, definePlugin, denied, discordTimestamp, dmOnly, effectiveDuration, env, event, explainDiscordError, fetchChannel, fetchGuild, fetchMember, fetchMessage, fetchRole, fetchUser, formatCooldownMessage, formatDuration, formatPermissions, formatUsage, gracefulShutdown, guard, guildOnly, hasPermissions, isDiscordError, isHTTPError, isRateLimitError, jsonlSink, linkButton, loadConfig, loadConfigAsync, loadEnv, loadInto, lookup, lookupOptional, mentionableSelect, messageCommand, missingPermissions, modal, moderationCheck, namespaced, normalizeAutoDefer, normalizeCooldown, normalizeReply, option, optionsHaveAutocomplete, paginate, paramsFromValues, parseCustomId, parseDuration, parseEnv, prefixArgs, prefixCommand, readOption, relativeTimestamp, requireAllRoles, requireAnyRole, requireBotPermissions, requireOwner, requireUserPermissions, roleSelect, row, runGuards, safeFetch, safeTry, showAndAwaitModal, stringSelect, subcommand, subcommandGroup, task, textInput, toAPIOption, toError, truncate, userCommand, userSelect, webhookSink, withSafeTimeout };
|