novaapp-sdk 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1001 -14
- package/dist/index.d.ts +1001 -14
- package/dist/index.js +1121 -13
- package/dist/index.mjs +1112 -13
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -60,6 +60,59 @@ interface Member {
|
|
|
60
60
|
isBot: boolean;
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
+
type ChannelType = 'TEXT' | 'VOICE' | 'ANNOUNCEMENT' | 'FORUM' | 'STAGE';
|
|
64
|
+
interface Channel {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
type: ChannelType;
|
|
68
|
+
serverId: string | null;
|
|
69
|
+
topic: string | null;
|
|
70
|
+
position: number;
|
|
71
|
+
isNsfw: boolean;
|
|
72
|
+
slowMode: number | null;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
}
|
|
75
|
+
interface Role {
|
|
76
|
+
id: string;
|
|
77
|
+
name: string;
|
|
78
|
+
color: string | null;
|
|
79
|
+
position: number;
|
|
80
|
+
serverId: string;
|
|
81
|
+
hoist: boolean;
|
|
82
|
+
permissions: Record<string, boolean>;
|
|
83
|
+
createdAt: string;
|
|
84
|
+
}
|
|
85
|
+
interface BanEntry {
|
|
86
|
+
userId: string;
|
|
87
|
+
username: string;
|
|
88
|
+
displayName: string;
|
|
89
|
+
avatar: string | null;
|
|
90
|
+
reason: string | null;
|
|
91
|
+
bannedAt: string;
|
|
92
|
+
moderatorId: string | null;
|
|
93
|
+
}
|
|
94
|
+
interface Invite {
|
|
95
|
+
code: string;
|
|
96
|
+
serverId: string;
|
|
97
|
+
creatorId: string;
|
|
98
|
+
uses: number;
|
|
99
|
+
maxUses: number | null;
|
|
100
|
+
expiresAt: string | null;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
}
|
|
103
|
+
/** A message with all reaction data fetched. */
|
|
104
|
+
interface ReactionDetail {
|
|
105
|
+
emoji: string;
|
|
106
|
+
count: number;
|
|
107
|
+
users: Array<{
|
|
108
|
+
id: string;
|
|
109
|
+
username: string;
|
|
110
|
+
displayName: string;
|
|
111
|
+
avatar: string | null;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
114
|
+
/** Bot status that can be set via `client.setStatus()`. */
|
|
115
|
+
type BotStatus = 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
|
|
63
116
|
interface Attachment {
|
|
64
117
|
id: string;
|
|
65
118
|
url: string;
|
|
@@ -278,6 +331,24 @@ interface PollInteractionsOptions {
|
|
|
278
331
|
limit?: number;
|
|
279
332
|
since?: string;
|
|
280
333
|
}
|
|
334
|
+
interface CreateChannelOptions {
|
|
335
|
+
name: string;
|
|
336
|
+
type?: ChannelType;
|
|
337
|
+
topic?: string;
|
|
338
|
+
position?: number;
|
|
339
|
+
isNsfw?: boolean;
|
|
340
|
+
slowMode?: number;
|
|
341
|
+
}
|
|
342
|
+
interface EditChannelOptions {
|
|
343
|
+
name?: string;
|
|
344
|
+
topic?: string;
|
|
345
|
+
position?: number;
|
|
346
|
+
isNsfw?: boolean;
|
|
347
|
+
slowMode?: number;
|
|
348
|
+
}
|
|
349
|
+
interface FetchChannelsOptions {
|
|
350
|
+
type?: ChannelType;
|
|
351
|
+
}
|
|
281
352
|
/** A raw permission record stored for a specific scope (server, role, or channel). */
|
|
282
353
|
interface BotPermissionRecord {
|
|
283
354
|
id: string;
|
|
@@ -354,6 +425,64 @@ declare class MessagesAPI {
|
|
|
354
425
|
typing(channelId: string): Promise<{
|
|
355
426
|
ok: true;
|
|
356
427
|
}>;
|
|
428
|
+
/**
|
|
429
|
+
* Fetch a single message by ID.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* const msg = await client.messages.fetchOne('message-id')
|
|
433
|
+
*/
|
|
434
|
+
fetchOne(messageId: string): Promise<Message>;
|
|
435
|
+
/**
|
|
436
|
+
* Pin a message in its channel.
|
|
437
|
+
* The bot must have the `messages.manage` scope.
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* await client.messages.pin('message-id')
|
|
441
|
+
*/
|
|
442
|
+
pin(messageId: string): Promise<{
|
|
443
|
+
ok: true;
|
|
444
|
+
}>;
|
|
445
|
+
/**
|
|
446
|
+
* Unpin a message.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* await client.messages.unpin('message-id')
|
|
450
|
+
*/
|
|
451
|
+
unpin(messageId: string): Promise<{
|
|
452
|
+
ok: true;
|
|
453
|
+
}>;
|
|
454
|
+
/**
|
|
455
|
+
* Fetch all pinned messages in a channel.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* const pins = await client.messages.fetchPinned('channel-id')
|
|
459
|
+
*/
|
|
460
|
+
fetchPinned(channelId: string): Promise<Message[]>;
|
|
461
|
+
/**
|
|
462
|
+
* Add a reaction to a message.
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* await client.messages.addReaction('message-id', '👍')
|
|
466
|
+
*/
|
|
467
|
+
addReaction(messageId: string, emoji: string): Promise<{
|
|
468
|
+
ok: true;
|
|
469
|
+
}>;
|
|
470
|
+
/**
|
|
471
|
+
* Remove the bot's reaction from a message.
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* await client.messages.removeReaction('message-id', '👍')
|
|
475
|
+
*/
|
|
476
|
+
removeReaction(messageId: string, emoji: string): Promise<{
|
|
477
|
+
ok: true;
|
|
478
|
+
}>;
|
|
479
|
+
/**
|
|
480
|
+
* Fetch all reactions on a message.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* const reactions = await client.messages.fetchReactions('message-id')
|
|
484
|
+
*/
|
|
485
|
+
fetchReactions(messageId: string): Promise<ReactionDetail[]>;
|
|
357
486
|
}
|
|
358
487
|
|
|
359
488
|
declare class CommandsAPI {
|
|
@@ -460,6 +589,56 @@ declare class MembersAPI {
|
|
|
460
589
|
ban(serverId: string, userId: string, reason?: string): Promise<{
|
|
461
590
|
ok: true;
|
|
462
591
|
}>;
|
|
592
|
+
/**
|
|
593
|
+
* Unban a previously banned user.
|
|
594
|
+
* Requires the `members.ban` scope.
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* await client.members.unban('server-id', 'user-id')
|
|
598
|
+
*/
|
|
599
|
+
unban(serverId: string, userId: string): Promise<{
|
|
600
|
+
ok: true;
|
|
601
|
+
}>;
|
|
602
|
+
/**
|
|
603
|
+
* Fetch the ban list for a server.
|
|
604
|
+
* Requires the `members.ban` scope.
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* const bans = await client.members.listBans('server-id')
|
|
608
|
+
* for (const ban of bans) {
|
|
609
|
+
* console.log(`${ban.username} — ${ban.reason ?? 'No reason'}`)
|
|
610
|
+
* }
|
|
611
|
+
*/
|
|
612
|
+
listBans(serverId: string): Promise<BanEntry[]>;
|
|
613
|
+
/**
|
|
614
|
+
* Send a direct message to a user (DM).
|
|
615
|
+
* Requires the `messages.write` scope.
|
|
616
|
+
*
|
|
617
|
+
* @example
|
|
618
|
+
* await client.members.dm('user-id', { content: 'Hello!' })
|
|
619
|
+
* await client.members.dm('user-id', 'Hello from the bot!')
|
|
620
|
+
*/
|
|
621
|
+
dm(userId: string, options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<Message>;
|
|
622
|
+
/**
|
|
623
|
+
* Add a role to a member.
|
|
624
|
+
* Requires the `members.roles` scope.
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* await client.members.addRole('server-id', 'user-id', 'role-id')
|
|
628
|
+
*/
|
|
629
|
+
addRole(serverId: string, userId: string, roleId: string): Promise<{
|
|
630
|
+
ok: true;
|
|
631
|
+
}>;
|
|
632
|
+
/**
|
|
633
|
+
* Remove a role from a member.
|
|
634
|
+
* Requires the `members.roles` scope.
|
|
635
|
+
*
|
|
636
|
+
* @example
|
|
637
|
+
* await client.members.removeRole('server-id', 'user-id', 'role-id')
|
|
638
|
+
*/
|
|
639
|
+
removeRole(serverId: string, userId: string, roleId: string): Promise<{
|
|
640
|
+
ok: true;
|
|
641
|
+
}>;
|
|
463
642
|
}
|
|
464
643
|
|
|
465
644
|
declare class ServersAPI {
|
|
@@ -473,6 +652,15 @@ declare class ServersAPI {
|
|
|
473
652
|
* console.log(`Bot is in ${servers.length} servers`)
|
|
474
653
|
*/
|
|
475
654
|
list(): Promise<NovaServer[]>;
|
|
655
|
+
/**
|
|
656
|
+
* Fetch all roles in a server.
|
|
657
|
+
* Results are sorted by position (lowest first).
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* const roles = await client.servers.listRoles('server-id')
|
|
661
|
+
* const adminRole = roles.find(r => r.name === 'Admin')
|
|
662
|
+
*/
|
|
663
|
+
listRoles(serverId: string): Promise<Role[]>;
|
|
476
664
|
}
|
|
477
665
|
|
|
478
666
|
declare class InteractionsAPI {
|
|
@@ -598,6 +786,144 @@ declare class PermissionsAPI {
|
|
|
598
786
|
get(options: PermissionsQueryOptions): Promise<PermissionsResult>;
|
|
599
787
|
}
|
|
600
788
|
|
|
789
|
+
declare class ChannelsAPI {
|
|
790
|
+
private readonly http;
|
|
791
|
+
constructor(http: HttpClient);
|
|
792
|
+
/**
|
|
793
|
+
* Fetch all channels in a server the bot is a member of.
|
|
794
|
+
*
|
|
795
|
+
* @example
|
|
796
|
+
* const channels = await client.channels.list('server-id')
|
|
797
|
+
* const textChannels = channels.filter(c => c.type === 'TEXT')
|
|
798
|
+
*/
|
|
799
|
+
list(serverId: string): Promise<Channel[]>;
|
|
800
|
+
/**
|
|
801
|
+
* Fetch a single channel by ID.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* const channel = await client.channels.fetch('channel-id')
|
|
805
|
+
* console.log(channel.name, channel.type)
|
|
806
|
+
*/
|
|
807
|
+
fetch(channelId: string): Promise<Channel>;
|
|
808
|
+
/**
|
|
809
|
+
* Create a new channel in a server.
|
|
810
|
+
* Requires the `channels.manage` scope.
|
|
811
|
+
*
|
|
812
|
+
* @example
|
|
813
|
+
* const channel = await client.channels.create('server-id', {
|
|
814
|
+
* name: 'announcements',
|
|
815
|
+
* type: 'ANNOUNCEMENT',
|
|
816
|
+
* topic: 'Official announcements only',
|
|
817
|
+
* })
|
|
818
|
+
*/
|
|
819
|
+
create(serverId: string, options: CreateChannelOptions): Promise<Channel>;
|
|
820
|
+
/**
|
|
821
|
+
* Edit an existing channel.
|
|
822
|
+
* Requires the `channels.manage` scope.
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* await client.channels.edit('channel-id', { topic: 'New topic!' })
|
|
826
|
+
*/
|
|
827
|
+
edit(channelId: string, options: EditChannelOptions): Promise<Channel>;
|
|
828
|
+
/**
|
|
829
|
+
* Delete a channel.
|
|
830
|
+
* Requires the `channels.manage` scope.
|
|
831
|
+
*
|
|
832
|
+
* @example
|
|
833
|
+
* await client.channels.delete('channel-id')
|
|
834
|
+
*/
|
|
835
|
+
delete(channelId: string): Promise<{
|
|
836
|
+
ok: true;
|
|
837
|
+
}>;
|
|
838
|
+
/**
|
|
839
|
+
* Fetch messages from a channel.
|
|
840
|
+
*
|
|
841
|
+
* @example
|
|
842
|
+
* const messages = await client.channels.fetchMessages('channel-id', { limit: 50 })
|
|
843
|
+
*/
|
|
844
|
+
fetchMessages(channelId: string, options?: FetchMessagesOptions): Promise<Message[]>;
|
|
845
|
+
/**
|
|
846
|
+
* Fetch all pinned messages in a channel.
|
|
847
|
+
*
|
|
848
|
+
* @example
|
|
849
|
+
* const pins = await client.channels.fetchPins('channel-id')
|
|
850
|
+
*/
|
|
851
|
+
fetchPins(channelId: string): Promise<Message[]>;
|
|
852
|
+
/**
|
|
853
|
+
* Send a typing indicator in a channel.
|
|
854
|
+
* Displayed to users for ~5 seconds.
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* await client.channels.startTyping('channel-id')
|
|
858
|
+
*/
|
|
859
|
+
startTyping(channelId: string): Promise<{
|
|
860
|
+
ok: true;
|
|
861
|
+
}>;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
declare class ReactionsAPI {
|
|
865
|
+
private readonly http;
|
|
866
|
+
constructor(http: HttpClient);
|
|
867
|
+
/**
|
|
868
|
+
* Add a reaction to a message.
|
|
869
|
+
* Use a plain emoji character or a custom emoji ID.
|
|
870
|
+
*
|
|
871
|
+
* @example
|
|
872
|
+
* await client.reactions.add('message-id', '👍')
|
|
873
|
+
* await client.reactions.add('message-id', '🎉')
|
|
874
|
+
*/
|
|
875
|
+
add(messageId: string, emoji: string): Promise<{
|
|
876
|
+
ok: true;
|
|
877
|
+
}>;
|
|
878
|
+
/**
|
|
879
|
+
* Remove the bot's reaction from a message.
|
|
880
|
+
*
|
|
881
|
+
* @example
|
|
882
|
+
* await client.reactions.remove('message-id', '👍')
|
|
883
|
+
*/
|
|
884
|
+
remove(messageId: string, emoji: string): Promise<{
|
|
885
|
+
ok: true;
|
|
886
|
+
}>;
|
|
887
|
+
/**
|
|
888
|
+
* Remove all reactions from a message.
|
|
889
|
+
* Requires the `messages.manage` scope.
|
|
890
|
+
*
|
|
891
|
+
* @example
|
|
892
|
+
* await client.reactions.removeAll('message-id')
|
|
893
|
+
*/
|
|
894
|
+
removeAll(messageId: string): Promise<{
|
|
895
|
+
ok: true;
|
|
896
|
+
}>;
|
|
897
|
+
/**
|
|
898
|
+
* Remove all reactions of a specific emoji from a message.
|
|
899
|
+
* Requires the `messages.manage` scope.
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* await client.reactions.removeEmoji('message-id', '👍')
|
|
903
|
+
*/
|
|
904
|
+
removeEmoji(messageId: string, emoji: string): Promise<{
|
|
905
|
+
ok: true;
|
|
906
|
+
}>;
|
|
907
|
+
/**
|
|
908
|
+
* Fetch all reactions on a message, broken down by emoji.
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* const reactions = await client.reactions.fetch('message-id')
|
|
912
|
+
* for (const r of reactions) {
|
|
913
|
+
* console.log(`${r.emoji} — ${r.count} reactions from ${r.users.map(u => u.username).join(', ')}`)
|
|
914
|
+
* }
|
|
915
|
+
*/
|
|
916
|
+
fetch(messageId: string): Promise<ReactionDetail[]>;
|
|
917
|
+
/**
|
|
918
|
+
* Fetch reactions for a specific emoji on a message.
|
|
919
|
+
*
|
|
920
|
+
* @example
|
|
921
|
+
* const detail = await client.reactions.fetchEmoji('message-id', '👍')
|
|
922
|
+
* console.log(`${detail.count} thumbs ups`)
|
|
923
|
+
*/
|
|
924
|
+
fetchEmoji(messageId: string, emoji: string): Promise<ReactionDetail>;
|
|
925
|
+
}
|
|
926
|
+
|
|
601
927
|
type TextInputStyle = 'short' | 'paragraph';
|
|
602
928
|
/**
|
|
603
929
|
* Fluent builder for a single text-input field inside a modal.
|
|
@@ -878,6 +1204,135 @@ declare class NovaInteraction {
|
|
|
878
1204
|
toJSON(): Interaction;
|
|
879
1205
|
}
|
|
880
1206
|
|
|
1207
|
+
/**
|
|
1208
|
+
* A rich wrapper around a raw `Message` with convenience methods.
|
|
1209
|
+
*
|
|
1210
|
+
* Returned by `client.on('messageCreate', ...)` and from message fetch calls.
|
|
1211
|
+
*
|
|
1212
|
+
* @example
|
|
1213
|
+
* client.on('messageCreate', async (msg) => {
|
|
1214
|
+
* if (msg.content.toLowerCase() === '!ping') {
|
|
1215
|
+
* await msg.reply('Pong! 🏓')
|
|
1216
|
+
* await msg.react('🏓')
|
|
1217
|
+
* }
|
|
1218
|
+
* })
|
|
1219
|
+
*/
|
|
1220
|
+
declare class NovaMessage {
|
|
1221
|
+
/** The raw message ID. */
|
|
1222
|
+
readonly id: string;
|
|
1223
|
+
/** The message text content. */
|
|
1224
|
+
readonly content: string;
|
|
1225
|
+
/** The channel this message was sent in. */
|
|
1226
|
+
readonly channelId: string;
|
|
1227
|
+
/** The author of the message. */
|
|
1228
|
+
readonly author: Message['author'];
|
|
1229
|
+
/** Embed attached to this message, if any. */
|
|
1230
|
+
readonly embed: Embed | null;
|
|
1231
|
+
/** Interactive components (buttons, selects) attached to this message. */
|
|
1232
|
+
readonly components: MessageComponent[];
|
|
1233
|
+
/** The message this is replying to, if any. */
|
|
1234
|
+
readonly replyToId: string | null;
|
|
1235
|
+
/** Uploaded file attachments. */
|
|
1236
|
+
readonly attachments: Attachment[];
|
|
1237
|
+
/** Reactions on this message. */
|
|
1238
|
+
readonly reactions: Reaction[];
|
|
1239
|
+
/** When the message was sent. */
|
|
1240
|
+
readonly createdAt: Date;
|
|
1241
|
+
/** When the message was last edited, or `null`. */
|
|
1242
|
+
readonly editedAt: Date | null;
|
|
1243
|
+
private readonly _messages;
|
|
1244
|
+
private readonly _reactions;
|
|
1245
|
+
constructor(raw: Message, messages: MessagesAPI, reactions: ReactionsAPI);
|
|
1246
|
+
/** Returns true if the message was sent by a bot. */
|
|
1247
|
+
isFromBot(): boolean;
|
|
1248
|
+
/** Returns true if the message has an embed. */
|
|
1249
|
+
hasEmbed(): boolean;
|
|
1250
|
+
/** Returns true if the message has interactive components. */
|
|
1251
|
+
hasComponents(): boolean;
|
|
1252
|
+
/** Returns true if the message has been edited. */
|
|
1253
|
+
isEdited(): boolean;
|
|
1254
|
+
/**
|
|
1255
|
+
* Add a reaction to this message.
|
|
1256
|
+
*
|
|
1257
|
+
* @example
|
|
1258
|
+
* await msg.react('👍')
|
|
1259
|
+
* await msg.react('🎉')
|
|
1260
|
+
*/
|
|
1261
|
+
react(emoji: string): Promise<{
|
|
1262
|
+
ok: true;
|
|
1263
|
+
}>;
|
|
1264
|
+
/**
|
|
1265
|
+
* Remove the bot's reaction from this message.
|
|
1266
|
+
*
|
|
1267
|
+
* @example
|
|
1268
|
+
* await msg.removeReaction('👍')
|
|
1269
|
+
*/
|
|
1270
|
+
removeReaction(emoji: string): Promise<{
|
|
1271
|
+
ok: true;
|
|
1272
|
+
}>;
|
|
1273
|
+
/**
|
|
1274
|
+
* Reply to this message.
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* await msg.reply('Got it!')
|
|
1278
|
+
* await msg.reply({ embed: new EmbedBuilder().setTitle('Result').toJSON() })
|
|
1279
|
+
*/
|
|
1280
|
+
reply(options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<NovaMessage>;
|
|
1281
|
+
/**
|
|
1282
|
+
* Edit this message.
|
|
1283
|
+
* Only works if the bot is the author.
|
|
1284
|
+
*
|
|
1285
|
+
* @example
|
|
1286
|
+
* await msg.edit('Updated content')
|
|
1287
|
+
* await msg.edit({ content: 'Updated', embed: { title: 'New embed' } })
|
|
1288
|
+
*/
|
|
1289
|
+
edit(options: string | EditMessageOptions): Promise<NovaMessage>;
|
|
1290
|
+
/**
|
|
1291
|
+
* Delete this message.
|
|
1292
|
+
* Only works if the bot is the author.
|
|
1293
|
+
*
|
|
1294
|
+
* @example
|
|
1295
|
+
* await msg.delete()
|
|
1296
|
+
*/
|
|
1297
|
+
delete(): Promise<{
|
|
1298
|
+
ok: true;
|
|
1299
|
+
}>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Pin this message in its channel.
|
|
1302
|
+
*
|
|
1303
|
+
* @example
|
|
1304
|
+
* await msg.pin()
|
|
1305
|
+
*/
|
|
1306
|
+
pin(): Promise<{
|
|
1307
|
+
ok: true;
|
|
1308
|
+
}>;
|
|
1309
|
+
/**
|
|
1310
|
+
* Unpin this message.
|
|
1311
|
+
*
|
|
1312
|
+
* @example
|
|
1313
|
+
* await msg.unpin()
|
|
1314
|
+
*/
|
|
1315
|
+
unpin(): Promise<{
|
|
1316
|
+
ok: true;
|
|
1317
|
+
}>;
|
|
1318
|
+
/**
|
|
1319
|
+
* Re-fetch the latest version of this message from the server.
|
|
1320
|
+
*
|
|
1321
|
+
* @example
|
|
1322
|
+
* const fresh = await msg.fetch()
|
|
1323
|
+
*/
|
|
1324
|
+
fetch(): Promise<NovaMessage>;
|
|
1325
|
+
/**
|
|
1326
|
+
* Get a URL to this message (deep link).
|
|
1327
|
+
*/
|
|
1328
|
+
get url(): string;
|
|
1329
|
+
/**
|
|
1330
|
+
* Return the raw message object.
|
|
1331
|
+
*/
|
|
1332
|
+
toJSON(): Message;
|
|
1333
|
+
toString(): string;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
881
1336
|
interface NovaClientEvents {
|
|
882
1337
|
/** Fired when the bot connects and is identified by the gateway. */
|
|
883
1338
|
ready: (bot: BotApplication) => void;
|
|
@@ -897,21 +1352,50 @@ interface NovaClientEvents {
|
|
|
897
1352
|
message: string;
|
|
898
1353
|
}) => void;
|
|
899
1354
|
/** A new message was sent in a channel the bot can see. */
|
|
900
|
-
messageCreate: (
|
|
901
|
-
/** A message was edited. */
|
|
902
|
-
messageUpdate: (
|
|
903
|
-
/** A message was deleted. */
|
|
904
|
-
messageDelete: (data:
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
1355
|
+
messageCreate: (message: NovaMessage) => void;
|
|
1356
|
+
/** A message was edited. Returns the updated message. */
|
|
1357
|
+
messageUpdate: (message: NovaMessage) => void;
|
|
1358
|
+
/** A message was deleted. Returns partial data. */
|
|
1359
|
+
messageDelete: (data: {
|
|
1360
|
+
id: string;
|
|
1361
|
+
channelId: string;
|
|
1362
|
+
}) => void;
|
|
1363
|
+
/** A reaction was added to a message. */
|
|
1364
|
+
reactionAdd: (data: {
|
|
1365
|
+
messageId: string;
|
|
1366
|
+
channelId: string;
|
|
1367
|
+
userId: string;
|
|
1368
|
+
emoji: string;
|
|
1369
|
+
}) => void;
|
|
1370
|
+
/** A reaction was removed from a message. */
|
|
1371
|
+
reactionRemove: (data: {
|
|
1372
|
+
messageId: string;
|
|
1373
|
+
channelId: string;
|
|
1374
|
+
userId: string;
|
|
1375
|
+
emoji: string;
|
|
1376
|
+
}) => void;
|
|
909
1377
|
/** A member joined a server the bot is in. */
|
|
910
|
-
memberAdd: (data:
|
|
1378
|
+
memberAdd: (data: {
|
|
1379
|
+
serverId: string;
|
|
1380
|
+
userId: string;
|
|
1381
|
+
username: string;
|
|
1382
|
+
}) => void;
|
|
911
1383
|
/** A member left a server the bot is in. */
|
|
912
|
-
memberRemove: (data:
|
|
913
|
-
|
|
914
|
-
|
|
1384
|
+
memberRemove: (data: {
|
|
1385
|
+
serverId: string;
|
|
1386
|
+
userId: string;
|
|
1387
|
+
}) => void;
|
|
1388
|
+
/** A user started typing in a channel. */
|
|
1389
|
+
typingStart: (data: {
|
|
1390
|
+
channelId: string;
|
|
1391
|
+
userId: string;
|
|
1392
|
+
}) => void;
|
|
1393
|
+
/** A message was pinned. */
|
|
1394
|
+
messagePinned: (data: {
|
|
1395
|
+
messageId: string;
|
|
1396
|
+
channelId: string;
|
|
1397
|
+
pinnedBy: string;
|
|
1398
|
+
}) => void;
|
|
915
1399
|
}
|
|
916
1400
|
/**
|
|
917
1401
|
* The main Nova bot client.
|
|
@@ -948,9 +1432,14 @@ declare class NovaClient extends EventEmitter {
|
|
|
948
1432
|
readonly interactions: InteractionsAPI;
|
|
949
1433
|
/** Query the bot's effective permissions within a server, channel, or role scope. */
|
|
950
1434
|
readonly permissions: PermissionsAPI;
|
|
1435
|
+
/** Create, edit, and delete channels; fetch pins and messages. */
|
|
1436
|
+
readonly channels: ChannelsAPI;
|
|
1437
|
+
/** Add, remove and fetch reactions on messages. */
|
|
1438
|
+
readonly reactions: ReactionsAPI;
|
|
951
1439
|
private socket;
|
|
952
1440
|
private readonly http;
|
|
953
1441
|
private readonly options;
|
|
1442
|
+
private _cronTimers;
|
|
954
1443
|
private readonly _commandHandlers;
|
|
955
1444
|
private readonly _buttonHandlers;
|
|
956
1445
|
private readonly _selectHandlers;
|
|
@@ -992,6 +1481,33 @@ declare class NovaClient extends EventEmitter {
|
|
|
992
1481
|
* await client.connect()
|
|
993
1482
|
*/
|
|
994
1483
|
connect(): Promise<void>;
|
|
1484
|
+
/**
|
|
1485
|
+
* Register a recurring task that fires at a set interval.
|
|
1486
|
+
* All cron tasks are automatically cancelled on `disconnect()`.
|
|
1487
|
+
*
|
|
1488
|
+
* @param intervalMs - How often to run the task (in milliseconds).
|
|
1489
|
+
* @param fn - Async or sync function to call on each tick.
|
|
1490
|
+
* @returns A cancel function — call it to stop this specific task.
|
|
1491
|
+
*
|
|
1492
|
+
* @example
|
|
1493
|
+
* // Check for new announcements every 30 seconds
|
|
1494
|
+
* client.cron(30_000, async () => {
|
|
1495
|
+
* const messages = await client.messages.fetch(channelId, { limit: 5 })
|
|
1496
|
+
* // do something...
|
|
1497
|
+
* })
|
|
1498
|
+
*/
|
|
1499
|
+
cron(intervalMs: number, fn: () => unknown): () => void;
|
|
1500
|
+
/**
|
|
1501
|
+
* Set the bot's presence status.
|
|
1502
|
+
* Broadcasts to all servers the bot is in via WebSocket.
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* client.setStatus('DND') // Do Not Disturb
|
|
1506
|
+
* client.setStatus('IDLE') // Away
|
|
1507
|
+
* client.setStatus('OFFLINE') // Appear offline
|
|
1508
|
+
* client.setStatus('ONLINE') // Back online
|
|
1509
|
+
*/
|
|
1510
|
+
setStatus(status: BotStatus): void;
|
|
995
1511
|
/**
|
|
996
1512
|
* Disconnect from the gateway and clean up.
|
|
997
1513
|
*/
|
|
@@ -1261,4 +1777,475 @@ declare class SlashCommandBuilder {
|
|
|
1261
1777
|
toJSON(): SlashCommandDefinition;
|
|
1262
1778
|
}
|
|
1263
1779
|
|
|
1264
|
-
|
|
1780
|
+
interface PollOption {
|
|
1781
|
+
label: string;
|
|
1782
|
+
emoji?: string;
|
|
1783
|
+
value?: string;
|
|
1784
|
+
}
|
|
1785
|
+
interface PollDefinition {
|
|
1786
|
+
question: string;
|
|
1787
|
+
options: PollOption[];
|
|
1788
|
+
allowMultiple?: boolean;
|
|
1789
|
+
duration?: number | null;
|
|
1790
|
+
anonymous?: boolean;
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Fluent builder for creating polls.
|
|
1794
|
+
*
|
|
1795
|
+
* @example
|
|
1796
|
+
* const poll = new PollBuilder()
|
|
1797
|
+
* .setQuestion('What is your favourite colour?')
|
|
1798
|
+
* .addOption({ label: 'Red', emoji: '🔴' })
|
|
1799
|
+
* .addOption({ label: 'Green', emoji: '🟢' })
|
|
1800
|
+
* .addOption({ label: 'Blue', emoji: '🔵' })
|
|
1801
|
+
* .setDuration(60 * 60 * 24) // 24 hours in seconds
|
|
1802
|
+
* .toJSON()
|
|
1803
|
+
*
|
|
1804
|
+
* await client.messages.send(channelId, { poll })
|
|
1805
|
+
*/
|
|
1806
|
+
declare class PollBuilder {
|
|
1807
|
+
private _question;
|
|
1808
|
+
private _options;
|
|
1809
|
+
private _allowMultiple;
|
|
1810
|
+
private _duration;
|
|
1811
|
+
private _anonymous;
|
|
1812
|
+
/**
|
|
1813
|
+
* Set the poll question.
|
|
1814
|
+
*
|
|
1815
|
+
* @example
|
|
1816
|
+
* builder.setQuestion('Best programming language?')
|
|
1817
|
+
*/
|
|
1818
|
+
setQuestion(question: string): this;
|
|
1819
|
+
/**
|
|
1820
|
+
* Add a single answer option.
|
|
1821
|
+
*
|
|
1822
|
+
* @example
|
|
1823
|
+
* builder.addOption({ label: 'TypeScript', emoji: '🔷' })
|
|
1824
|
+
*/
|
|
1825
|
+
addOption(option: PollOption): this;
|
|
1826
|
+
/**
|
|
1827
|
+
* Add multiple answer options at once.
|
|
1828
|
+
*
|
|
1829
|
+
* @example
|
|
1830
|
+
* builder.addOptions([
|
|
1831
|
+
* { label: 'Yes', emoji: '✅' },
|
|
1832
|
+
* { label: 'No', emoji: '❌' },
|
|
1833
|
+
* ])
|
|
1834
|
+
*/
|
|
1835
|
+
addOptions(options: PollOption[]): this;
|
|
1836
|
+
/**
|
|
1837
|
+
* Allow users to select more than one option.
|
|
1838
|
+
* Default: `false` (single choice).
|
|
1839
|
+
*/
|
|
1840
|
+
setAllowMultiple(yes?: boolean): this;
|
|
1841
|
+
/**
|
|
1842
|
+
* Set the poll duration in **seconds**. Pass `null` to make it permanent.
|
|
1843
|
+
*
|
|
1844
|
+
* @example
|
|
1845
|
+
* builder.setDuration(60 * 60 * 24) // expires in 24 hours
|
|
1846
|
+
* builder.setDuration(null) // no expiry
|
|
1847
|
+
*/
|
|
1848
|
+
setDuration(seconds: number | null): this;
|
|
1849
|
+
/**
|
|
1850
|
+
* Hide which users voted for which option.
|
|
1851
|
+
* Default: `false` (votes are public).
|
|
1852
|
+
*/
|
|
1853
|
+
setAnonymous(yes?: boolean): this;
|
|
1854
|
+
/** Build the poll definition object. */
|
|
1855
|
+
toJSON(): PollDefinition;
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
/**
|
|
1859
|
+
* Fluent builder for composing messages.
|
|
1860
|
+
* Replaces passing raw option objects everywhere.
|
|
1861
|
+
*
|
|
1862
|
+
* @example
|
|
1863
|
+
* const msg = new MessageBuilder()
|
|
1864
|
+
* .setContent('Here are your stats:')
|
|
1865
|
+
* .setEmbed(
|
|
1866
|
+
* new EmbedBuilder()
|
|
1867
|
+
* .setTitle('📊 Stats')
|
|
1868
|
+
* .addField('Messages', '1 234', true)
|
|
1869
|
+
* .addField('Reactions', '567', true)
|
|
1870
|
+
* .setColor('#5865F2')
|
|
1871
|
+
* )
|
|
1872
|
+
* .addRow(
|
|
1873
|
+
* new ActionRowBuilder()
|
|
1874
|
+
* .addComponent(new ButtonBuilder().setLabel('Refresh').setCustomId('refresh').setStyle('primary'))
|
|
1875
|
+
* )
|
|
1876
|
+
* .toJSON()
|
|
1877
|
+
*
|
|
1878
|
+
* await client.messages.send(channelId, msg)
|
|
1879
|
+
*/
|
|
1880
|
+
declare class MessageBuilder {
|
|
1881
|
+
private _content;
|
|
1882
|
+
private _embed;
|
|
1883
|
+
private _components;
|
|
1884
|
+
private _replyToId;
|
|
1885
|
+
private _poll;
|
|
1886
|
+
/**
|
|
1887
|
+
* Set the text content of the message.
|
|
1888
|
+
*
|
|
1889
|
+
* @example
|
|
1890
|
+
* builder.setContent('Hello world!')
|
|
1891
|
+
*/
|
|
1892
|
+
setContent(content: string): this;
|
|
1893
|
+
/**
|
|
1894
|
+
* Attach an embed. Accepts an `EmbedBuilder` or raw `Embed` object.
|
|
1895
|
+
*
|
|
1896
|
+
* @example
|
|
1897
|
+
* builder.setEmbed(new EmbedBuilder().setTitle('Result'))
|
|
1898
|
+
* builder.setEmbed({ title: 'Result', color: '#57F287' })
|
|
1899
|
+
*/
|
|
1900
|
+
setEmbed(embed: EmbedBuilder | Embed): this;
|
|
1901
|
+
/**
|
|
1902
|
+
* Remove any embed from this message.
|
|
1903
|
+
*/
|
|
1904
|
+
clearEmbed(): this;
|
|
1905
|
+
/**
|
|
1906
|
+
* Add an `ActionRowBuilder` (or raw component array) as a component row.
|
|
1907
|
+
*
|
|
1908
|
+
* @example
|
|
1909
|
+
* builder.addRow(
|
|
1910
|
+
* new ActionRowBuilder().addComponent(btn1).addComponent(btn2)
|
|
1911
|
+
* )
|
|
1912
|
+
*/
|
|
1913
|
+
addRow(row: ActionRowBuilder | MessageComponent[]): this;
|
|
1914
|
+
/**
|
|
1915
|
+
* Replace all existing component rows.
|
|
1916
|
+
*/
|
|
1917
|
+
setComponents(components: MessageComponent[]): this;
|
|
1918
|
+
/**
|
|
1919
|
+
* Set the message this is replying to.
|
|
1920
|
+
*
|
|
1921
|
+
* @example
|
|
1922
|
+
* builder.setReplyTo(message.id)
|
|
1923
|
+
*/
|
|
1924
|
+
setReplyTo(messageId: string): this;
|
|
1925
|
+
/**
|
|
1926
|
+
* Attach a poll to the message.
|
|
1927
|
+
* Accepts a `PollBuilder` or raw `PollDefinition`.
|
|
1928
|
+
*
|
|
1929
|
+
* @example
|
|
1930
|
+
* builder.setPoll(
|
|
1931
|
+
* new PollBuilder()
|
|
1932
|
+
* .setQuestion('Favourite language?')
|
|
1933
|
+
* .addOptions([{ label: 'TypeScript' }, { label: 'Python' }])
|
|
1934
|
+
* )
|
|
1935
|
+
*/
|
|
1936
|
+
setPoll(poll: {
|
|
1937
|
+
toJSON: () => PollDefinition;
|
|
1938
|
+
} | PollDefinition): this;
|
|
1939
|
+
/**
|
|
1940
|
+
* Build the message options object, ready to pass to `client.messages.send()`.
|
|
1941
|
+
*
|
|
1942
|
+
* @throws if neither `content` nor `embed` nor `poll` is set.
|
|
1943
|
+
*/
|
|
1944
|
+
toJSON(): SendMessageOptions & {
|
|
1945
|
+
poll?: PollDefinition;
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
/**
|
|
1950
|
+
* A supercharged Map with extra utility methods.
|
|
1951
|
+
* Used throughout the SDK for caches (messages, channels, members, etc.)
|
|
1952
|
+
*
|
|
1953
|
+
* Inspired by discord.js Collection — but with proper generics and async support.
|
|
1954
|
+
*
|
|
1955
|
+
* @example
|
|
1956
|
+
* const col = new Collection<string, User>()
|
|
1957
|
+
* col.set('u1', { id: 'u1', name: 'Alice' })
|
|
1958
|
+
* col.set('u2', { id: 'u2', name: 'Bob' })
|
|
1959
|
+
*
|
|
1960
|
+
* col.first() // { id: 'u1', name: 'Alice' }
|
|
1961
|
+
* col.find(u => u.name === 'Bob') // { id: 'u2', name: 'Bob' }
|
|
1962
|
+
* col.map(u => u.name) // ['Alice', 'Bob']
|
|
1963
|
+
*/
|
|
1964
|
+
declare class Collection<K, V> extends Map<K, V> {
|
|
1965
|
+
/**
|
|
1966
|
+
* The first value stored (insertion order), or `undefined` if empty.
|
|
1967
|
+
*/
|
|
1968
|
+
first(): V | undefined;
|
|
1969
|
+
/**
|
|
1970
|
+
* The first `n` values stored (insertion order).
|
|
1971
|
+
*/
|
|
1972
|
+
firstN(n: number): V[];
|
|
1973
|
+
/**
|
|
1974
|
+
* The last value stored, or `undefined` if empty.
|
|
1975
|
+
*/
|
|
1976
|
+
last(): V | undefined;
|
|
1977
|
+
/**
|
|
1978
|
+
* The last `n` values stored (insertion order).
|
|
1979
|
+
*/
|
|
1980
|
+
lastN(n: number): V[];
|
|
1981
|
+
/**
|
|
1982
|
+
* Returns a random value from the collection, or `undefined` if empty.
|
|
1983
|
+
*/
|
|
1984
|
+
random(): V | undefined;
|
|
1985
|
+
/**
|
|
1986
|
+
* Find the first value that passes the predicate.
|
|
1987
|
+
*
|
|
1988
|
+
* @example
|
|
1989
|
+
* const bot = members.find(m => m.user.isBot)
|
|
1990
|
+
*/
|
|
1991
|
+
find(fn: (value: V, key: K, col: this) => boolean): V | undefined;
|
|
1992
|
+
/**
|
|
1993
|
+
* Find the key of the first value that passes the predicate.
|
|
1994
|
+
*/
|
|
1995
|
+
findKey(fn: (value: V, key: K, col: this) => boolean): K | undefined;
|
|
1996
|
+
/**
|
|
1997
|
+
* Returns `true` if at least one value satisfies the predicate.
|
|
1998
|
+
*/
|
|
1999
|
+
some(fn: (value: V, key: K, col: this) => boolean): boolean;
|
|
2000
|
+
/**
|
|
2001
|
+
* Returns `true` if every value satisfies the predicate.
|
|
2002
|
+
*/
|
|
2003
|
+
every(fn: (value: V, key: K, col: this) => boolean): boolean;
|
|
2004
|
+
/**
|
|
2005
|
+
* Filter to a new Collection containing only values that pass the predicate.
|
|
2006
|
+
*
|
|
2007
|
+
* @example
|
|
2008
|
+
* const admins = members.filter(m => m.role === 'ADMIN')
|
|
2009
|
+
*/
|
|
2010
|
+
filter(fn: (value: V, key: K, col: this) => boolean): Collection<K, V>;
|
|
2011
|
+
/**
|
|
2012
|
+
* Map each value to a new array.
|
|
2013
|
+
*
|
|
2014
|
+
* @example
|
|
2015
|
+
* const names = members.map(m => m.user.username)
|
|
2016
|
+
*/
|
|
2017
|
+
map<T>(fn: (value: V, key: K, col: this) => T): T[];
|
|
2018
|
+
/**
|
|
2019
|
+
* Map to a new Collection with transformed values.
|
|
2020
|
+
*
|
|
2021
|
+
* @example
|
|
2022
|
+
* const names = channels.mapValues(c => c.name.toUpperCase())
|
|
2023
|
+
*/
|
|
2024
|
+
mapValues<T>(fn: (value: V, key: K, col: this) => T): Collection<K, T>;
|
|
2025
|
+
/**
|
|
2026
|
+
* Reduce the collection to a single value.
|
|
2027
|
+
*
|
|
2028
|
+
* @example
|
|
2029
|
+
* const totalReactions = messages.reduce((sum, m) => sum + m.reactions.length, 0)
|
|
2030
|
+
*/
|
|
2031
|
+
reduce<T>(fn: (accumulator: T, value: V, key: K, col: this) => T, initial: T): T;
|
|
2032
|
+
/**
|
|
2033
|
+
* Returns values as an array (insertion order).
|
|
2034
|
+
*/
|
|
2035
|
+
toArray(): V[];
|
|
2036
|
+
/**
|
|
2037
|
+
* Returns keys as an array (insertion order).
|
|
2038
|
+
*/
|
|
2039
|
+
keyArray(): K[];
|
|
2040
|
+
/**
|
|
2041
|
+
* Sort and return a new Collection.
|
|
2042
|
+
* Callback works like `Array.prototype.sort`.
|
|
2043
|
+
*
|
|
2044
|
+
* @example
|
|
2045
|
+
* const sorted = channels.sort((a, b) => a.position - b.position)
|
|
2046
|
+
*/
|
|
2047
|
+
sort(fn?: (a: V, b: V, ak: K, bk: K) => number): Collection<K, V>;
|
|
2048
|
+
/**
|
|
2049
|
+
* Split into two Collections based on a predicate.
|
|
2050
|
+
* Returns `[passing, failing]`.
|
|
2051
|
+
*
|
|
2052
|
+
* @example
|
|
2053
|
+
* const [bots, humans] = members.partition(m => m.user.isBot)
|
|
2054
|
+
*/
|
|
2055
|
+
partition(fn: (value: V, key: K, col: this) => boolean): [Collection<K, V>, Collection<K, V>];
|
|
2056
|
+
/**
|
|
2057
|
+
* Merge this collection with one or more others.
|
|
2058
|
+
* Later collections overwrite duplicate keys.
|
|
2059
|
+
*/
|
|
2060
|
+
merge(...others: ReadonlyMap<K, V>[]): Collection<K, V>;
|
|
2061
|
+
/**
|
|
2062
|
+
* Serialize to a plain `Record` (requires string keys).
|
|
2063
|
+
*/
|
|
2064
|
+
toJSON(): Record<string, V>;
|
|
2065
|
+
toString(): string;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
/**
|
|
2069
|
+
* Per-user cooldown manager.
|
|
2070
|
+
* Prevents commands from being spammed by individual users.
|
|
2071
|
+
*
|
|
2072
|
+
* @example
|
|
2073
|
+
* // Create once per command
|
|
2074
|
+
* const cooldown = new Cooldown(5_000) // 5 second cooldown
|
|
2075
|
+
*
|
|
2076
|
+
* client.command('daily', async (interaction) => {
|
|
2077
|
+
* const remaining = cooldown.check(interaction.userId)
|
|
2078
|
+
* if (remaining > 0) {
|
|
2079
|
+
* return interaction.replyEphemeral(
|
|
2080
|
+
* `⏳ Wait **${Cooldown.format(remaining)}** before using this command again.`
|
|
2081
|
+
* )
|
|
2082
|
+
* }
|
|
2083
|
+
* cooldown.use(interaction.userId)
|
|
2084
|
+
* await interaction.reply('🎁 Daily reward collected!')
|
|
2085
|
+
* })
|
|
2086
|
+
*/
|
|
2087
|
+
declare class Cooldown {
|
|
2088
|
+
private readonly _durations;
|
|
2089
|
+
private readonly _last;
|
|
2090
|
+
private readonly _defaultMs;
|
|
2091
|
+
/**
|
|
2092
|
+
* @param durationMs - Default cooldown duration in milliseconds.
|
|
2093
|
+
*/
|
|
2094
|
+
constructor(durationMs: number);
|
|
2095
|
+
/**
|
|
2096
|
+
* Check remaining cooldown for a user.
|
|
2097
|
+
* Returns `0` if they are not on cooldown (free to proceed),
|
|
2098
|
+
* or the **milliseconds remaining** if they are on cooldown.
|
|
2099
|
+
*
|
|
2100
|
+
* @example
|
|
2101
|
+
* const ms = cooldown.check(userId)
|
|
2102
|
+
* if (ms > 0) return interaction.replyEphemeral(`Wait ${Cooldown.format(ms)}!`)
|
|
2103
|
+
*/
|
|
2104
|
+
check(userId: string): number;
|
|
2105
|
+
/**
|
|
2106
|
+
* Mark a user as having just used the command, starting their cooldown.
|
|
2107
|
+
* Optionally override the cooldown duration for this specific user.
|
|
2108
|
+
*
|
|
2109
|
+
* @example
|
|
2110
|
+
* cooldown.use(userId) // uses default duration
|
|
2111
|
+
* cooldown.use(userId, 10_000) // 10 second cooldown for this use
|
|
2112
|
+
*/
|
|
2113
|
+
use(userId: string, durationMs?: number): void;
|
|
2114
|
+
/**
|
|
2115
|
+
* Immediately reset (clear) the cooldown for a user.
|
|
2116
|
+
*
|
|
2117
|
+
* @example
|
|
2118
|
+
* cooldown.reset(userId) // user can use the command again immediately
|
|
2119
|
+
*/
|
|
2120
|
+
reset(userId: string): void;
|
|
2121
|
+
/**
|
|
2122
|
+
* Reset all active cooldowns.
|
|
2123
|
+
*/
|
|
2124
|
+
resetAll(): void;
|
|
2125
|
+
/**
|
|
2126
|
+
* Returns a list of all users currently on cooldown.
|
|
2127
|
+
*
|
|
2128
|
+
* @example
|
|
2129
|
+
* const active = cooldown.activeCooldowns()
|
|
2130
|
+
* // [{ userId: 'abc', remainingMs: 3200 }, ...]
|
|
2131
|
+
*/
|
|
2132
|
+
activeCooldowns(): Array<{
|
|
2133
|
+
userId: string;
|
|
2134
|
+
remainingMs: number;
|
|
2135
|
+
}>;
|
|
2136
|
+
/**
|
|
2137
|
+
* Format milliseconds into a human-readable string.
|
|
2138
|
+
*
|
|
2139
|
+
* @example
|
|
2140
|
+
* Cooldown.format(3_600_000) // '1h 0m 0s'
|
|
2141
|
+
* Cooldown.format(90_000) // '1m 30s'
|
|
2142
|
+
* Cooldown.format(4_000) // '4s'
|
|
2143
|
+
*/
|
|
2144
|
+
static format(ms: number): string;
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Manages multiple named cooldowns in one place.
|
|
2148
|
+
* Ideal when you have many commands each with their own cooldown.
|
|
2149
|
+
*
|
|
2150
|
+
* @example
|
|
2151
|
+
* const cooldowns = new CooldownManager()
|
|
2152
|
+
*
|
|
2153
|
+
* client.command('ping', async (interaction) => {
|
|
2154
|
+
* const remaining = cooldowns.check('ping', interaction.userId, 3_000)
|
|
2155
|
+
* if (remaining > 0) return interaction.replyEphemeral(`Wait ${Cooldown.format(remaining)}!`)
|
|
2156
|
+
* await interaction.reply('Pong!')
|
|
2157
|
+
* })
|
|
2158
|
+
*/
|
|
2159
|
+
declare class CooldownManager {
|
|
2160
|
+
private readonly _map;
|
|
2161
|
+
/**
|
|
2162
|
+
* Get or create a named cooldown.
|
|
2163
|
+
*/
|
|
2164
|
+
get(name: string, durationMs?: number): Cooldown;
|
|
2165
|
+
/**
|
|
2166
|
+
* Check a named cooldown for a user.
|
|
2167
|
+
* Creates the cooldown if it doesn't exist yet.
|
|
2168
|
+
* Returns `0` if free, or remaining ms if on cooldown.
|
|
2169
|
+
*
|
|
2170
|
+
* @example
|
|
2171
|
+
* const ms = cooldowns.check('ban', userId, 30_000)
|
|
2172
|
+
*/
|
|
2173
|
+
check(name: string, userId: string, durationMs?: number): number;
|
|
2174
|
+
/**
|
|
2175
|
+
* Mark a user as having used a named command.
|
|
2176
|
+
*
|
|
2177
|
+
* @example
|
|
2178
|
+
* cooldowns.use('ban', userId, 30_000)
|
|
2179
|
+
*/
|
|
2180
|
+
use(name: string, userId: string, durationMs?: number): void;
|
|
2181
|
+
/**
|
|
2182
|
+
* Reset a user's cooldown on a named command.
|
|
2183
|
+
*/
|
|
2184
|
+
reset(name: string, userId: string): void;
|
|
2185
|
+
/**
|
|
2186
|
+
* Reset all cooldowns for all commands.
|
|
2187
|
+
*/
|
|
2188
|
+
resetAll(): void;
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
/**
|
|
2192
|
+
* Coloured, timestamped logger for Nova bots.
|
|
2193
|
+
* Prefix every log with a consistent `[BotName]` tag.
|
|
2194
|
+
*
|
|
2195
|
+
* @example
|
|
2196
|
+
* const log = new Logger('MyBot')
|
|
2197
|
+
* log.info('Ready!') // [MyBot] [INFO] Ready!
|
|
2198
|
+
* log.warn('Rate limited') // [MyBot] [WARN] Rate limited
|
|
2199
|
+
* log.error('DB timed out') // [MyBot] [ERROR] DB timed out
|
|
2200
|
+
* log.debug('Payload:', data) // [MyBot] [DEBUG] Payload: { ... }
|
|
2201
|
+
* log.success('Command registered') // [MyBot] [OK] Command registered
|
|
2202
|
+
* log.command('ping', userId) // [MyBot] [CMD] ping ← userId
|
|
2203
|
+
* log.event('messageCreate') // [MyBot] [EVT] messageCreate
|
|
2204
|
+
*/
|
|
2205
|
+
declare class Logger {
|
|
2206
|
+
private readonly _prefix;
|
|
2207
|
+
private _debug;
|
|
2208
|
+
/**
|
|
2209
|
+
* @param name - Name shown in square brackets before every message.
|
|
2210
|
+
* @param enableDebug - When `false` (default), `.debug()` calls are silent.
|
|
2211
|
+
*/
|
|
2212
|
+
constructor(name: string, enableDebug?: boolean);
|
|
2213
|
+
/** Enable or disable debug output at runtime. */
|
|
2214
|
+
setDebug(enabled: boolean): this;
|
|
2215
|
+
private _timestamp;
|
|
2216
|
+
private _fmt;
|
|
2217
|
+
/** General info message. */
|
|
2218
|
+
info(...args: unknown[]): void;
|
|
2219
|
+
/** Warning — something unexpected but non-fatal. */
|
|
2220
|
+
warn(...args: unknown[]): void;
|
|
2221
|
+
/** Error — something went wrong. */
|
|
2222
|
+
error(...args: unknown[]): void;
|
|
2223
|
+
/** Success / positive confirmation. */
|
|
2224
|
+
success(...args: unknown[]): void;
|
|
2225
|
+
/** Debug — only printed when `enableDebug` is true. */
|
|
2226
|
+
debug(...args: unknown[]): void;
|
|
2227
|
+
/**
|
|
2228
|
+
* Log an incoming command interaction.
|
|
2229
|
+
*
|
|
2230
|
+
* @example
|
|
2231
|
+
* log.command('ping', interaction.userId)
|
|
2232
|
+
* // [MyBot] [CMD] /ping ← user:abc123
|
|
2233
|
+
*/
|
|
2234
|
+
command(name: string, userId: string): void;
|
|
2235
|
+
/**
|
|
2236
|
+
* Log a gateway event.
|
|
2237
|
+
*
|
|
2238
|
+
* @example
|
|
2239
|
+
* log.event('messageCreate')
|
|
2240
|
+
*/
|
|
2241
|
+
event(type: string, extra?: string): void;
|
|
2242
|
+
/**
|
|
2243
|
+
* Log that a command handler threw an error.
|
|
2244
|
+
*
|
|
2245
|
+
* @example
|
|
2246
|
+
* log.commandError('ban', err)
|
|
2247
|
+
*/
|
|
2248
|
+
commandError(name: string, err: unknown): void;
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
export { ActionRowBuilder, type Attachment, type BanEntry, type BotApplication, type BotEvent, type BotEventType, type BotModalDefinition, type BotModalField, type BotPermissionRecord, type BotStatus, type BotUser, ButtonBuilder, type ButtonStyle, type Channel, type ChannelType, ChannelsAPI, Collection, CommandsAPI, type ContextCommandDefinition, Cooldown, CooldownManager, type CreateChannelOptions, type EditChannelOptions, type EditMessageOptions, type Embed, EmbedBuilder, type EmbedField, type FetchChannelsOptions, type FetchMembersOptions, type FetchMessagesOptions, HttpClient, type Interaction, InteractionOptions, type InteractionType, InteractionsAPI, type Invite, Logger, type Member, MembersAPI, type Message, MessageBuilder, type MessageComponent, MessagesAPI, ModalBuilder, NovaClient, type NovaClientEvents, type NovaClientOptions, NovaInteraction, NovaMessage, type NovaServer, PermissionsAPI, type PermissionsQueryOptions, type PermissionsResult, PollBuilder, type PollDefinition, type PollInteractionsOptions, type PollOption, type PrefixCommandDefinition, type Reaction, type ReactionDetail, ReactionsAPI, type RegisteredContextCommand, type RegisteredPrefixCommand, type RegisteredSlashCommand, type RespondInteractionOptions, type Role, SelectMenuBuilder, type SelectMenuOption, type SendMessageOptions, ServersAPI, SlashCommandBuilder, type SlashCommandDefinition, type SlashCommandOption, SlashCommandOptionBuilder, TextInputBuilder, type TextInputStyle };
|