novaapp-sdk 1.2.0 → 1.3.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 CHANGED
@@ -68,8 +68,8 @@ interface Channel {
68
68
  serverId: string | null;
69
69
  topic: string | null;
70
70
  position: number;
71
- isNsfw: boolean;
72
- slowMode: number | null;
71
+ /** Slow-mode interval in seconds. `0` means disabled. */
72
+ slowMode: number;
73
73
  createdAt: string;
74
74
  }
75
75
  interface Role {
@@ -336,14 +336,12 @@ interface CreateChannelOptions {
336
336
  type?: ChannelType;
337
337
  topic?: string;
338
338
  position?: number;
339
- isNsfw?: boolean;
340
339
  slowMode?: number;
341
340
  }
342
341
  interface EditChannelOptions {
343
342
  name?: string;
344
343
  topic?: string;
345
344
  position?: number;
346
- isNsfw?: boolean;
347
345
  slowMode?: number;
348
346
  }
349
347
  interface FetchChannelsOptions {
@@ -382,6 +380,29 @@ interface PermissionsQueryOptions {
382
380
  /** Narrow the scope to a specific role. */
383
381
  roleId?: string;
384
382
  }
383
+ /** A direct message sent between the bot and a user. */
384
+ interface DirectMessage {
385
+ id: string;
386
+ content: string;
387
+ /** The sender's user ID. */
388
+ fromId: string;
389
+ /** The recipient's user ID. */
390
+ toId: string;
391
+ editedAt: string | null;
392
+ createdAt: string;
393
+ }
394
+ /** Snapshot of a user's voice channel presence. */
395
+ interface VoiceState {
396
+ userId: string;
397
+ channelId: string;
398
+ serverId: string;
399
+ /** Whether the user's microphone is muted. */
400
+ muted: boolean;
401
+ /** Whether the user's audio output is deafened. */
402
+ deafened: boolean;
403
+ /** ISO timestamp when the user joined the voice channel. */
404
+ joinedAt: string;
405
+ }
385
406
  interface NovaClientOptions {
386
407
  /** Your bot token — starts with "nova_bot_" */
387
408
  token: string;
@@ -1333,6 +1354,214 @@ declare class NovaMessage {
1333
1354
  toString(): string;
1334
1355
  }
1335
1356
 
1357
+ /**
1358
+ * A rich wrapper around a raw `Channel` with convenience methods.
1359
+ *
1360
+ * Returned by `client.fetchChannel()` and `client.fetchChannels()`.
1361
+ *
1362
+ * @example
1363
+ * const channel = await client.fetchChannel('channel-id')
1364
+ *
1365
+ * await channel.send('Hello from the bot!')
1366
+ * await channel.edit({ topic: 'New topic' })
1367
+ * const messages = await channel.fetchMessages({ limit: 20 })
1368
+ */
1369
+ declare class NovaChannel {
1370
+ /** The channel's unique ID. */
1371
+ readonly id: string;
1372
+ /** The channel's name (without #). */
1373
+ readonly name: string;
1374
+ /** The channel type — `'TEXT'`, `'VOICE'`, `'ANNOUNCEMENT'`, `'FORUM'`, or `'STAGE'`. */
1375
+ readonly type: ChannelType;
1376
+ /** The ID of the server this channel belongs to. */
1377
+ readonly serverId: string | null;
1378
+ /** Optional topic / description text. */
1379
+ readonly topic: string | null;
1380
+ /** Sorting position (lower = higher in the list). */
1381
+ readonly position: number;
1382
+ /** Slow-mode interval in seconds (`0` = disabled). */
1383
+ readonly slowMode: number;
1384
+ /** When the channel was created. */
1385
+ readonly createdAt: Date;
1386
+ private readonly _channels;
1387
+ private readonly _messages;
1388
+ constructor(raw: Channel, channels: ChannelsAPI, messages: MessagesAPI);
1389
+ /** `true` for text channels. */
1390
+ isText(): boolean;
1391
+ /** `true` for voice channels. */
1392
+ isVoice(): boolean;
1393
+ /** `true` for announcement channels. */
1394
+ isAnnouncement(): boolean;
1395
+ /** `true` for forum channels. */
1396
+ isForum(): boolean;
1397
+ /** `true` for stage channels. */
1398
+ isStage(): boolean;
1399
+ /** `true` if slow-mode is enabled on this channel. */
1400
+ hasSlowMode(): boolean;
1401
+ /**
1402
+ * Send a message to this channel.
1403
+ * Accepts a plain string or a full options object.
1404
+ *
1405
+ * @example
1406
+ * await channel.send('Hello!')
1407
+ * await channel.send({ content: 'Hi', embed: { title: 'Stats' } })
1408
+ */
1409
+ send(options: string | SendMessageOptions): Promise<Message>;
1410
+ /**
1411
+ * Fetch recent messages from this channel.
1412
+ *
1413
+ * @example
1414
+ * const messages = await channel.fetchMessages({ limit: 50 })
1415
+ */
1416
+ fetchMessages(options?: FetchMessagesOptions): Promise<Message[]>;
1417
+ /**
1418
+ * Fetch all pinned messages in this channel.
1419
+ *
1420
+ * @example
1421
+ * const pins = await channel.fetchPins()
1422
+ */
1423
+ fetchPins(): Promise<Message[]>;
1424
+ /**
1425
+ * Start a typing indicator (shows "Bot is typing…" for ~5 seconds).
1426
+ *
1427
+ * @example
1428
+ * await channel.startTyping()
1429
+ */
1430
+ startTyping(): Promise<{
1431
+ ok: true;
1432
+ }>;
1433
+ /**
1434
+ * Edit this channel's properties.
1435
+ * Requires the `channels.manage` scope.
1436
+ *
1437
+ * @example
1438
+ * await channel.edit({ name: 'general-2', topic: 'The second general channel' })
1439
+ */
1440
+ edit(options: EditChannelOptions): Promise<NovaChannel>;
1441
+ /**
1442
+ * Delete this channel.
1443
+ * Requires the `channels.manage` scope.
1444
+ *
1445
+ * @example
1446
+ * await channel.delete()
1447
+ */
1448
+ delete(): Promise<{
1449
+ ok: true;
1450
+ }>;
1451
+ /**
1452
+ * Returns the channel as a mention-style string: `#name`.
1453
+ */
1454
+ toString(): string;
1455
+ /** Returns the raw channel data. */
1456
+ toJSON(): Channel;
1457
+ }
1458
+
1459
+ /**
1460
+ * A rich wrapper around a raw `Member` with convenience methods.
1461
+ *
1462
+ * Returned by `client.fetchMember()` and `client.fetchMembers()`.
1463
+ *
1464
+ * @example
1465
+ * const member = await client.fetchMember('server-id', 'user-id')
1466
+ *
1467
+ * if (member.isAdmin()) {
1468
+ * await member.dm('You have admin access.')
1469
+ * } else {
1470
+ * await member.kick()
1471
+ * }
1472
+ */
1473
+ declare class NovaMember {
1474
+ /** The user's unique ID. */
1475
+ readonly userId: string;
1476
+ /** The server this membership belongs to. */
1477
+ readonly serverId: string;
1478
+ /** The user's username (login handle). */
1479
+ readonly username: string;
1480
+ /** The user's display name. */
1481
+ readonly displayName: string;
1482
+ /** URL of the user's avatar, or `null`. */
1483
+ readonly avatar: string | null;
1484
+ /** The member's server role — `'OWNER'`, `'ADMIN'`, or `'MEMBER'`. */
1485
+ readonly role: 'OWNER' | 'ADMIN' | 'MEMBER';
1486
+ /** The user's current presence status. */
1487
+ readonly status: 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
1488
+ /** `true` if this member is a bot account. */
1489
+ readonly isBot: boolean;
1490
+ /** When this user joined the server. */
1491
+ readonly joinedAt: Date;
1492
+ private readonly _members;
1493
+ constructor(raw: Member, serverId: string, members: MembersAPI);
1494
+ /** `true` if this member is the server owner. */
1495
+ isOwner(): boolean;
1496
+ /** `true` if this member is an admin or the server owner. */
1497
+ isAdmin(): boolean;
1498
+ /** `true` if this member is a regular (non-privileged) member. */
1499
+ isRegularMember(): boolean;
1500
+ /** `true` if the user is currently online. */
1501
+ isOnline(): boolean;
1502
+ /** `true` if the user is idle / away. */
1503
+ isIdle(): boolean;
1504
+ /** `true` if the user is set to Do Not Disturb. */
1505
+ isDND(): boolean;
1506
+ /** `true` if the user appears offline. */
1507
+ isOffline(): boolean;
1508
+ /**
1509
+ * Kick this member from the server.
1510
+ * Bots cannot kick owners or admins (throws 403).
1511
+ *
1512
+ * @example
1513
+ * await member.kick()
1514
+ */
1515
+ kick(): Promise<{
1516
+ ok: true;
1517
+ }>;
1518
+ /**
1519
+ * Ban this member from the server with an optional reason.
1520
+ * Bots cannot ban owners or admins (throws 403).
1521
+ *
1522
+ * @example
1523
+ * await member.ban('Repeated rule violations')
1524
+ */
1525
+ ban(reason?: string): Promise<{
1526
+ ok: true;
1527
+ }>;
1528
+ /**
1529
+ * Send this user a direct message.
1530
+ * Requires the `messages.write` scope.
1531
+ *
1532
+ * @example
1533
+ * await member.dm('Welcome to the server!')
1534
+ * await member.dm({ content: 'Hello', embed: { title: 'Rules' } })
1535
+ */
1536
+ dm(options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<Message>;
1537
+ /**
1538
+ * Assign a custom role to this member.
1539
+ * Requires the `members.roles` scope.
1540
+ *
1541
+ * @example
1542
+ * await member.addRole('role-id')
1543
+ */
1544
+ addRole(roleId: string): Promise<{
1545
+ ok: true;
1546
+ }>;
1547
+ /**
1548
+ * Remove a custom role from this member.
1549
+ * Requires the `members.roles` scope.
1550
+ *
1551
+ * @example
1552
+ * await member.removeRole('role-id')
1553
+ */
1554
+ removeRole(roleId: string): Promise<{
1555
+ ok: true;
1556
+ }>;
1557
+ /**
1558
+ * Returns a mention-style string: `@displayName`.
1559
+ */
1560
+ toString(): string;
1561
+ /** Returns the raw member data. */
1562
+ toJSON(): Member;
1563
+ }
1564
+
1336
1565
  interface NovaClientEvents {
1337
1566
  /** Fired when the bot connects and is identified by the gateway. */
1338
1567
  ready: (bot: BotApplication) => void;
@@ -1396,6 +1625,59 @@ interface NovaClientEvents {
1396
1625
  channelId: string;
1397
1626
  pinnedBy: string;
1398
1627
  }) => void;
1628
+ /** A channel was created in a server. */
1629
+ channelCreate: (channel: Channel) => void;
1630
+ /** A channel was updated. */
1631
+ channelUpdate: (channel: Channel) => void;
1632
+ /** A channel was deleted. */
1633
+ channelDelete: (data: {
1634
+ id: string;
1635
+ serverId: string;
1636
+ }) => void;
1637
+ /** A role was created in a server. */
1638
+ roleCreate: (data: {
1639
+ id: string;
1640
+ name: string;
1641
+ color: string | null;
1642
+ serverId: string;
1643
+ position: number;
1644
+ hoist: boolean;
1645
+ createdAt: string;
1646
+ }) => void;
1647
+ /** A role was deleted. */
1648
+ roleDelete: (data: {
1649
+ id: string;
1650
+ serverId: string;
1651
+ }) => void;
1652
+ /** A user joined a voice channel. */
1653
+ voiceJoin: (data: {
1654
+ userId: string;
1655
+ channelId: string;
1656
+ serverId: string;
1657
+ }) => void;
1658
+ /** A user left a voice channel. */
1659
+ voiceLeave: (data: {
1660
+ userId: string;
1661
+ channelId: string;
1662
+ serverId: string;
1663
+ }) => void;
1664
+ /** A member was banned from a server. */
1665
+ memberBanned: (data: {
1666
+ userId: string;
1667
+ serverId: string;
1668
+ moderatorId: string | null;
1669
+ reason: string | null;
1670
+ }) => void;
1671
+ /** A member was unbanned. */
1672
+ memberUnbanned: (data: {
1673
+ userId: string;
1674
+ serverId: string;
1675
+ }) => void;
1676
+ /** A member's profile data was updated. */
1677
+ memberUpdate: (data: {
1678
+ userId: string;
1679
+ serverId: string;
1680
+ }) => void;
1399
1681
  }
1400
1682
  /**
1401
1683
  * The main Nova bot client.
@@ -1443,6 +1725,7 @@ declare class NovaClient extends EventEmitter {
1443
1725
  private readonly _commandHandlers;
1444
1726
  private readonly _buttonHandlers;
1445
1727
  private readonly _selectHandlers;
1728
+ private readonly _modalHandlers;
1446
1729
  constructor(options: NovaClientOptions);
1447
1730
  /**
1448
1731
  * Register a handler for a slash or prefix command by name.
@@ -1473,6 +1756,17 @@ declare class NovaClient extends EventEmitter {
1473
1756
  * })
1474
1757
  */
1475
1758
  selectMenu(customId: string, handler: (interaction: NovaInteraction) => unknown): this;
1759
+ /**
1760
+ * Register a handler for a modal submission by its `customId`.
1761
+ * Called automatically when the user submits a modal with that `customId`.
1762
+ *
1763
+ * @example
1764
+ * client.modal('report_modal', async (interaction) => {
1765
+ * const reason = interaction.modalData.reason
1766
+ * await interaction.replyEphemeral(`Report received: ${reason}`)
1767
+ * })
1768
+ */
1769
+ modal(customId: string, handler: (interaction: NovaInteraction) => unknown): this;
1476
1770
  /**
1477
1771
  * Connect to the Nova WebSocket gateway.
1478
1772
  * Resolves when the `ready` event is received.
@@ -1508,6 +1802,51 @@ declare class NovaClient extends EventEmitter {
1508
1802
  * client.setStatus('ONLINE') // Back online
1509
1803
  */
1510
1804
  setStatus(status: BotStatus): void;
1805
+ /**
1806
+ * Fetch a single channel and return it as a rich `NovaChannel` wrapper.
1807
+ *
1808
+ * @example
1809
+ * const channel = await client.fetchChannel('channel-id')
1810
+ * await channel.send('Hello!')
1811
+ */
1812
+ fetchChannel(channelId: string): Promise<NovaChannel>;
1813
+ /**
1814
+ * Fetch all channels in a server and return them as `NovaChannel` wrappers.
1815
+ *
1816
+ * @example
1817
+ * const channels = await client.fetchChannels('server-id')
1818
+ * const textChannels = channels.filter(c => c.isText())
1819
+ */
1820
+ fetchChannels(serverId: string): Promise<NovaChannel[]>;
1821
+ /**
1822
+ * Fetch all members in a server and return them as `NovaMember` wrappers.
1823
+ *
1824
+ * @example
1825
+ * const members = await client.fetchMembers('server-id')
1826
+ * const bots = members.filter(m => m.isBot)
1827
+ */
1828
+ fetchMembers(serverId: string): Promise<NovaMember[]>;
1829
+ /**
1830
+ * Fetch a single member from a server and return them as a `NovaMember` wrapper.
1831
+ * Throws if the user is not found in the server.
1832
+ *
1833
+ * @example
1834
+ * const member = await client.fetchMember('server-id', 'user-id')
1835
+ * await member.dm('Welcome!')
1836
+ */
1837
+ fetchMember(serverId: string, userId: string): Promise<NovaMember>;
1838
+ /**
1839
+ * Wait for a specific event to be emitted, optionally filtered.
1840
+ * Rejects after `timeoutMs` (default 30 s) if the condition never fires.
1841
+ *
1842
+ * @example
1843
+ * // Wait for any message in a specific channel
1844
+ * const msg = await client.waitFor('messageCreate', m => m.channelId === channelId)
1845
+ *
1846
+ * // Wait for a button click with a timeout
1847
+ * const i = await client.waitFor('interactionCreate', i => i.isButton(), 60_000)
1848
+ */
1849
+ waitFor<K extends keyof NovaClientEvents>(event: K, filter?: (...args: Parameters<NovaClientEvents[K]>) => boolean, timeoutMs?: number): Promise<Parameters<NovaClientEvents[K]>[0]>;
1511
1850
  /**
1512
1851
  * Disconnect from the gateway and clean up.
1513
1852
  */
@@ -2248,4 +2587,270 @@ declare class Logger {
2248
2587
  commandError(name: string, err: unknown): void;
2249
2588
  }
2250
2589
 
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 };
2590
+ /**
2591
+ * Async cursor-based paginator for any list API.
2592
+ *
2593
+ * Pass a `fetchFn` that takes the current cursor and returns the next
2594
+ * page of items plus the cursor to use for the next page (`null` = done).
2595
+ *
2596
+ * @example
2597
+ * // Paginate all messages in a channel
2598
+ * const paginator = new Paginator(async (cursor) => {
2599
+ * const messages = await client.messages.fetch(channelId, { limit: 50, before: cursor ?? undefined })
2600
+ * return { items: messages, cursor: messages.at(-1)?.id ?? null }
2601
+ * })
2602
+ *
2603
+ * // Lazy async iteration
2604
+ * for await (const message of paginator) {
2605
+ * console.log(message.content)
2606
+ * }
2607
+ *
2608
+ * // Or collect everything at once
2609
+ * const all = await paginator.fetchAll()
2610
+ */
2611
+ declare class Paginator<T> {
2612
+ private readonly fetchFn;
2613
+ private _cursor;
2614
+ private _done;
2615
+ private _totalFetched;
2616
+ constructor(fetchFn: (cursor: string | null) => Promise<{
2617
+ items: T[];
2618
+ cursor: string | null;
2619
+ }>);
2620
+ /** Whether all pages have been consumed. */
2621
+ get done(): boolean;
2622
+ /** Total number of items fetched so far (across all pages). */
2623
+ get totalFetched(): number;
2624
+ /**
2625
+ * Fetch the next page of results.
2626
+ * Returns an empty array when there are no more pages.
2627
+ *
2628
+ * @example
2629
+ * const page1 = await paginator.fetchPage()
2630
+ * const page2 = await paginator.fetchPage()
2631
+ */
2632
+ fetchPage(): Promise<T[]>;
2633
+ /**
2634
+ * Fetch **all** remaining pages and return a flat array.
2635
+ *
2636
+ * ⚠️ Use with caution on very large collections.
2637
+ *
2638
+ * @example
2639
+ * const allMembers = await paginator.fetchAll()
2640
+ */
2641
+ fetchAll(): Promise<T[]>;
2642
+ /**
2643
+ * Fetch up to `n` items total (across however many pages are needed).
2644
+ *
2645
+ * @example
2646
+ * const first100 = await paginator.fetchN(100)
2647
+ */
2648
+ fetchN(n: number): Promise<T[]>;
2649
+ /**
2650
+ * Async-iterate over every item, one page at a time.
2651
+ *
2652
+ * @example
2653
+ * for await (const msg of paginator) {
2654
+ * process(msg)
2655
+ * }
2656
+ */
2657
+ [Symbol.asyncIterator](): AsyncGenerator<T>;
2658
+ /**
2659
+ * Reset the paginator so you can iterate from the beginning again.
2660
+ *
2661
+ * @example
2662
+ * await paginator.fetchAll()
2663
+ * paginator.reset()
2664
+ * const againFirst = await paginator.fetchPage()
2665
+ */
2666
+ reset(): void;
2667
+ }
2668
+
2669
+ /**
2670
+ * All known Nova bot permission keys.
2671
+ * Use these as string constants when calling `has()`, `grant()`, etc.
2672
+ */
2673
+ declare const Permissions: {
2674
+ /** Read messages in channels. */
2675
+ readonly MESSAGES_READ: "messages.read";
2676
+ /** Send messages in channels. */
2677
+ readonly MESSAGES_WRITE: "messages.write";
2678
+ /** Edit / delete any message (not just the bot's own). */
2679
+ readonly MESSAGES_MANAGE: "messages.manage";
2680
+ /** Create, edit and delete channels. */
2681
+ readonly CHANNELS_MANAGE: "channels.manage";
2682
+ /** Kick members from the server. */
2683
+ readonly MEMBERS_KICK: "members.kick";
2684
+ /** Ban and unban members from the server. */
2685
+ readonly MEMBERS_BAN: "members.ban";
2686
+ /** Assign and remove roles on members. */
2687
+ readonly MEMBERS_ROLES: "members.roles";
2688
+ /** Edit server settings. */
2689
+ readonly SERVERS_MANAGE: "servers.manage";
2690
+ };
2691
+ type PermissionKey = (typeof Permissions)[keyof typeof Permissions];
2692
+ /**
2693
+ * Utility class for working with Nova bot permission records.
2694
+ *
2695
+ * Unlike a Discord-style bitfield, Nova permissions are stored as a
2696
+ * `Record<string, boolean>` map. `PermissionsBitfield` wraps that
2697
+ * map with readable helpers for checking, merging, and diffing.
2698
+ *
2699
+ * @example
2700
+ * const perms = new PermissionsBitfield({
2701
+ * 'messages.read': true,
2702
+ * 'messages.write': true,
2703
+ * })
2704
+ *
2705
+ * perms.has('messages.read') // true
2706
+ * perms.has('channels.manage') // false
2707
+ * perms.hasAll('messages.read', 'messages.write') // true
2708
+ * perms.missing('messages.manage', 'members.kick') // ['messages.manage', 'members.kick']
2709
+ * perms.toArray() // ['messages.read', 'messages.write']
2710
+ */
2711
+ declare class PermissionsBitfield {
2712
+ private readonly _perms;
2713
+ constructor(perms?: Record<string, boolean>);
2714
+ /**
2715
+ * Returns `true` if the given permission is explicitly granted.
2716
+ *
2717
+ * @example
2718
+ * if (!perms.has(Permissions.MESSAGES_WRITE)) {
2719
+ * throw new Error('Bot cannot write messages here.')
2720
+ * }
2721
+ */
2722
+ has(permission: string): boolean;
2723
+ /**
2724
+ * Returns `true` if **all** listed permissions are granted.
2725
+ *
2726
+ * @example
2727
+ * perms.hasAll('messages.read', 'messages.write') // true
2728
+ */
2729
+ hasAll(...permissions: string[]): boolean;
2730
+ /**
2731
+ * Returns `true` if **at least one** of the listed permissions is granted.
2732
+ *
2733
+ * @example
2734
+ * perms.hasAny('channels.manage', 'servers.manage') // true if either is set
2735
+ */
2736
+ hasAny(...permissions: string[]): boolean;
2737
+ /**
2738
+ * Returns the list of permissions that are **not** granted.
2739
+ *
2740
+ * @example
2741
+ * const missing = perms.missing('messages.write', 'members.kick')
2742
+ * if (missing.length) throw new Error(`Missing: ${missing.join(', ')}`)
2743
+ */
2744
+ missing(...permissions: string[]): string[];
2745
+ /**
2746
+ * Return a **new** `PermissionsBitfield` with the given permission granted.
2747
+ *
2748
+ * @example
2749
+ * const updated = perms.grant('channels.manage')
2750
+ */
2751
+ grant(...permissions: string[]): PermissionsBitfield;
2752
+ /**
2753
+ * Return a **new** `PermissionsBitfield` with the given permission denied.
2754
+ *
2755
+ * @example
2756
+ * const restricted = perms.deny('members.kick')
2757
+ */
2758
+ deny(...permissions: string[]): PermissionsBitfield;
2759
+ /**
2760
+ * Merge another record or `PermissionsBitfield` on top of this one.
2761
+ * The incoming values **override** any existing ones.
2762
+ *
2763
+ * @example
2764
+ * const merged = serverPerms.merge(channelOverrides)
2765
+ */
2766
+ merge(other: Record<string, boolean> | PermissionsBitfield): PermissionsBitfield;
2767
+ /**
2768
+ * Returns an array of the permission keys that are **currently granted**.
2769
+ *
2770
+ * @example
2771
+ * perms.toArray() // ['messages.read', 'messages.write']
2772
+ */
2773
+ toArray(): string[];
2774
+ /**
2775
+ * Returns the raw `Record<string, boolean>` map.
2776
+ */
2777
+ toRecord(): Record<string, boolean>;
2778
+ /**
2779
+ * Pretty-print the granted permissions.
2780
+ *
2781
+ * @example
2782
+ * console.log(String(perms)) // 'PermissionsBitfield[messages.read, messages.write]'
2783
+ */
2784
+ toString(): string;
2785
+ /** Create a `PermissionsBitfield` from an existing record. */
2786
+ static from(perms: Record<string, boolean>): PermissionsBitfield;
2787
+ /** A `PermissionsBitfield` with all known permissions granted. */
2788
+ static readonly ALL: PermissionsBitfield;
2789
+ /** A `PermissionsBitfield` with no permissions granted. */
2790
+ static readonly NONE: PermissionsBitfield;
2791
+ }
2792
+
2793
+ /**
2794
+ * Returns a promise that resolves after `ms` milliseconds.
2795
+ * Useful in retry loops, cron tasks, and staged sends.
2796
+ *
2797
+ * @example
2798
+ * await sleep(2_000) // wait 2 seconds
2799
+ */
2800
+ declare function sleep(ms: number): Promise<void>;
2801
+ /**
2802
+ * Wraps a promise with a timeout — rejects with an error if the original
2803
+ * promise does not resolve within `ms` milliseconds.
2804
+ *
2805
+ * @example
2806
+ * const result = await withTimeout(fetchData(), 5_000, 'fetchData took too long')
2807
+ */
2808
+ declare function withTimeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T>;
2809
+ /**
2810
+ * Format a duration in milliseconds to a compact human-readable string.
2811
+ *
2812
+ * @example
2813
+ * formatDuration(0) // '0s'
2814
+ * formatDuration(90_000) // '1m 30s'
2815
+ * formatDuration(3_661_000) // '1h 1m 1s'
2816
+ * formatDuration(604_800_000) // '1w'
2817
+ */
2818
+ declare function formatDuration(ms: number): string;
2819
+ /**
2820
+ * Format a timestamp as a relative human-readable string from now.
2821
+ * Accepts a `Date`, a Unix timestamp (ms), or an ISO date string.
2822
+ *
2823
+ * @example
2824
+ * formatRelative(Date.now() - 5_000) // 'just now'
2825
+ * formatRelative(Date.now() - 90_000) // '1 minute ago'
2826
+ * formatRelative(Date.now() + 60_000) // 'in 1 minute'
2827
+ * formatRelative(Date.now() - 86_400_000) // 'yesterday'
2828
+ */
2829
+ declare function formatRelative(timestamp: Date | number | string): string;
2830
+ /**
2831
+ * Safely parse any timestamp (ISO string, Unix ms, or Date) to a `Date`.
2832
+ * Returns `null` if the input is nullish or not parseable.
2833
+ *
2834
+ * @example
2835
+ * parseTimestamp('2026-01-01T00:00:00.000Z') // Date
2836
+ * parseTimestamp(null) // null
2837
+ */
2838
+ declare function parseTimestamp(value: string | number | Date | null | undefined): Date | null;
2839
+ /**
2840
+ * Returns the remaining time until a target date as an object with components.
2841
+ * All values are `0` if the target is in the past.
2842
+ *
2843
+ * @example
2844
+ * const { days, hours, minutes, seconds } = countdown(new Date('2027-01-01'))
2845
+ * console.log(`${days}d ${hours}h ${minutes}m ${seconds}s remaining`)
2846
+ */
2847
+ declare function countdown(target: Date | number | string): {
2848
+ weeks: number;
2849
+ days: number;
2850
+ hours: number;
2851
+ minutes: number;
2852
+ seconds: number;
2853
+ total: number;
2854
+ };
2855
+
2856
+ 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 DirectMessage, 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, NovaChannel, NovaClient, type NovaClientEvents, type NovaClientOptions, NovaInteraction, NovaMember, NovaMessage, type NovaServer, Paginator, type PermissionKey, Permissions, PermissionsAPI, PermissionsBitfield, 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, type VoiceState, countdown, formatDuration, formatRelative, parseTimestamp, sleep, withTimeout };