From 95032d3b9a81b03f47fd5d1c8cfae68a7093f0e8 Mon Sep 17 00:00:00 2001 From: Alina Sireneva Date: Fri, 29 Sep 2023 21:45:11 +0300 Subject: [PATCH] feat: added ArrayPaginated --- packages/client/src/client.ts | 13 +++++++++--- packages/client/src/methods/_imports.ts | 1 + .../src/methods/chats/get-chat-members.ts | 10 +++++++-- .../invite-links/get-invite-link-members.ts | 21 ++++++++++++------- .../methods/invite-links/get-invite-links.ts | 21 ++++++++++++------- .../invite-links/iter-invite-link-members.ts | 10 ++++----- packages/client/src/types/utils.ts | 1 + packages/client/src/utils/misc-utils.ts | 10 ++++++++- 8 files changed, 62 insertions(+), 25 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index ffa80053..15bf77d5 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -194,6 +194,7 @@ import { unblockUser } from './methods/users/unblock-user' import { updateProfile } from './methods/users/update-profile' import { updateUsername } from './methods/users/update-username' import { + ArrayPaginated, ArrayWithTotal, BotChatJoinRequestUpdate, BotCommands, @@ -1225,7 +1226,13 @@ export interface TelegramClient extends BaseTelegramClient { offset?: number /** - * Maximum number of members to be retrieved. Defaults to `200` + * Maximum number of members to be retrieved. + * + * > **Note**: Telegram currently only allows you to ever retrieve at most + * > 200 members, regardless of offset/limit. I.e. when passing + * > `offset=201` nothing will ever be returned. + * + * @default 200 */ limit?: number @@ -2005,7 +2012,7 @@ export interface TelegramClient extends BaseTelegramClient { */ requestedSearch?: string }, - ): Promise> + ): Promise> /** * Get detailed information about an invite link * @@ -2056,7 +2063,7 @@ export interface TelegramClient extends BaseTelegramClient { */ offsetLink?: string }, - ): Promise> + ): Promise> /** * Get primary invite link of a chat * diff --git a/packages/client/src/methods/_imports.ts b/packages/client/src/methods/_imports.ts index 5434b0a4..1bd68c42 100644 --- a/packages/client/src/methods/_imports.ts +++ b/packages/client/src/methods/_imports.ts @@ -11,6 +11,7 @@ import { tdFileId } from '@mtcute/file-id' // @copy import { + ArrayPaginated, ArrayWithTotal, BotChatJoinRequestUpdate, BotCommands, diff --git a/packages/client/src/methods/chats/get-chat-members.ts b/packages/client/src/methods/chats/get-chat-members.ts index 1d0c9789..ba573e93 100644 --- a/packages/client/src/methods/chats/get-chat-members.ts +++ b/packages/client/src/methods/chats/get-chat-members.ts @@ -26,7 +26,7 @@ export async function getChatMembers( * Defaults to `''` (empty string) * * > **Note**: Only used for these values of `filter`: - * > `all`, `banned`, `restricted`, `contacts` + * > `all, banned, restricted, mention, contacts` */ query?: string @@ -36,7 +36,13 @@ export async function getChatMembers( offset?: number /** - * Maximum number of members to be retrieved. Defaults to `200` + * Maximum number of members to be retrieved. + * + * > **Note**: Telegram currently only allows you to ever retrieve at most + * > 200 members, regardless of offset/limit. I.e. when passing + * > `offset=201` nothing will ever be returned. + * + * @default 200 */ limit?: number diff --git a/packages/client/src/methods/invite-links/get-invite-link-members.ts b/packages/client/src/methods/invite-links/get-invite-link-members.ts index 0e1c545f..26f32af6 100644 --- a/packages/client/src/methods/invite-links/get-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/get-invite-link-members.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' import { TelegramClient } from '../../client' -import { ArrayWithTotal, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types' -import { makeArrayWithTotal, normalizeDate } from '../../utils' +import { ArrayPaginated, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types' +import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../utils' /** * Iterate over users who have joined @@ -52,7 +52,7 @@ export async function getInviteLinkMembers( */ requestedSearch?: string }, -): Promise> { +): Promise> { const peer = await this.resolvePeer(chatId) const { limit = 100, link, requestedSearch, requested = Boolean(requestedSearch) } = params @@ -74,8 +74,15 @@ export async function getInviteLinkMembers( const peers = PeersIndex.from(res) - return makeArrayWithTotal( - res.importers.map((it) => new ChatInviteLinkMember(this, it, peers)), - res.count, - ) + const members = res.importers.map((it) => new ChatInviteLinkMember(this, it, peers)) + + const last = members[members.length - 1] + const nextOffset = last ? + { + date: last.raw.date, + user: normalizeToInputUser(last.user.inputPeer), + } : + undefined + + return makeArrayPaginated(members, res.count, nextOffset) } diff --git a/packages/client/src/methods/invite-links/get-invite-links.ts b/packages/client/src/methods/invite-links/get-invite-links.ts index 9db2b815..cf6f5054 100644 --- a/packages/client/src/methods/invite-links/get-invite-links.ts +++ b/packages/client/src/methods/invite-links/get-invite-links.ts @@ -1,6 +1,6 @@ import { TelegramClient } from '../../client' -import { ArrayWithTotal, ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { makeArrayWithTotal, normalizeDate } from '../../utils' +import { ArrayPaginated, ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' +import { makeArrayPaginated, normalizeDate } from '../../utils' import { normalizeToInputUser } from '../../utils/peer-utils' /** @@ -48,7 +48,7 @@ export async function getInviteLinks( */ offsetLink?: string }, -): Promise> { +): Promise> { if (!params) params = {} const { revoked = false, limit = Infinity, admin } = params @@ -68,8 +68,15 @@ export async function getInviteLinks( const peers = PeersIndex.from(res) - return makeArrayWithTotal( - res.invites.map((it) => new ChatInviteLink(this, it, peers)), - res.count, - ) + const links = res.invites.map((it) => new ChatInviteLink(this, it, peers)) + + const last = links[links.length - 1] + const nextOffset = last ? + { + date: last.raw.date, + link: last.raw.link, + } : + undefined + + return makeArrayPaginated(links, res.count, nextOffset) } diff --git a/packages/client/src/methods/invite-links/iter-invite-link-members.ts b/packages/client/src/methods/invite-links/iter-invite-link-members.ts index ef7a05ea..3f5a199f 100644 --- a/packages/client/src/methods/invite-links/iter-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/iter-invite-link-members.ts @@ -1,6 +1,5 @@ import { TelegramClient } from '../../client' import { ChatInviteLinkMember, InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils' /** * Iterate over users who have joined @@ -50,14 +49,15 @@ export async function* iterInviteLinkMembers( if (!items.length) break - const last = items[items.length - 1] - offsetDate = last.date - offsetUser = normalizeToInputUser(last.user.inputPeer) - for (const it of items) { yield it if (++current >= limit) return } + + if (!items.next) return + + offsetDate = items.next.date + offsetUser = items.next.user } } diff --git a/packages/client/src/types/utils.ts b/packages/client/src/types/utils.ts index 96c8248f..1e3c5aad 100644 --- a/packages/client/src/types/utils.ts +++ b/packages/client/src/types/utils.ts @@ -3,3 +3,4 @@ import { MaybeAsync } from '@mtcute/core' export type MaybeDynamic = MaybeAsync | (() => MaybeAsync) export type ArrayWithTotal = T[] & { total: number } +export type ArrayPaginated = T[] & { total: number; next?: Offset } diff --git a/packages/client/src/utils/misc-utils.ts b/packages/client/src/utils/misc-utils.ts index 4db234c3..8fae3c0f 100644 --- a/packages/client/src/utils/misc-utils.ts +++ b/packages/client/src/utils/misc-utils.ts @@ -1,6 +1,6 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { ArrayWithTotal, MaybeDynamic, Message } from '../types' +import { ArrayPaginated, ArrayWithTotal, MaybeDynamic, Message } from '../types' /** * Normalize phone number by stripping formatting @@ -24,6 +24,14 @@ export function makeArrayWithTotal(arr: T[], total: number): ArrayWithTotal(arr: T[], total: number, next?: Offset): ArrayPaginated { + const a = arr as ArrayPaginated + a.total = total + a.next = next + + return a +} + export function extractChannelIdFromUpdate(upd: tl.TypeUpdate): number | undefined { // holy shit let res = 0