chore: changed prettier width to 120

This commit is contained in:
alina 🌸 2023-09-24 01:32:22 +03:00
parent fbe264aab0
commit befbceaf8a
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
312 changed files with 2429 additions and 7867 deletions

View file

@ -6,14 +6,14 @@
"insertPragma": false, "insertPragma": false,
"jsxBracketSameLine": false, "jsxBracketSameLine": false,
"jsxSingleQuote": false, "jsxSingleQuote": false,
"printWidth": 80, "printWidth": 120,
"proseWrap": "preserve", "proseWrap": "preserve",
"quoteProps": "as-needed", "quoteProps": "as-needed",
"requirePragma": false, "requirePragma": false,
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"tabWidth": 4, "tabWidth": 4,
"trailingComma": "es5", "trailingComma": "all",
"useTabs": false, "useTabs": false,
"vueIndentScriptAndStyle": false "vueIndentScriptAndStyle": false
} }

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,4 @@ export * from './client'
export * from './types' export * from './types'
export * from './utils/peer-utils' export * from './utils/peer-utils'
export { createDummyUpdate } from './utils/updates-utils' export { createDummyUpdate } from './utils/updates-utils'
export { export { assertNever, JsonFileStorage, LocalstorageStorage, MemoryStorage, tl } from '@mtcute/core'
assertNever,
JsonFileStorage,
LocalstorageStorage,
MemoryStorage,
tl,
} from '@mtcute/core'

View file

@ -5,13 +5,7 @@ import { Readable } from 'stream'
// @copy // @copy
import { MaybeArray, MaybeAsync } from '@mtcute/core' import { MaybeArray, MaybeAsync } from '@mtcute/core'
// @copy // @copy
import { import { AsyncLock, ConditionVariable, Deque, Logger, SortedLinkedList } from '@mtcute/core/utils'
AsyncLock,
ConditionVariable,
Deque,
Logger,
SortedLinkedList,
} from '@mtcute/core/utils'
// @copy // @copy
import { tdFileId } from '@mtcute/file-id' import { tdFileId } from '@mtcute/file-id'

View file

@ -8,10 +8,7 @@ import { TelegramClient } from '../../client'
* @param tosId TOS id * @param tosId TOS id
* @internal * @internal
*/ */
export async function acceptTos( export async function acceptTos(this: TelegramClient, tosId: string): Promise<boolean> {
this: TelegramClient,
tosId: string,
): Promise<boolean> {
const res = await this.call({ const res = await this.call({
_: 'help.acceptTermsOfService', _: 'help.acceptTermsOfService',
id: { id: {
@ -21,11 +18,7 @@ export async function acceptTos(
}) })
if (!res) { if (!res) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('help.acceptTermsOfService', 'true', 'false')
'help.acceptTermsOfService',
'true',
'false',
)
} }
return true return true

View file

@ -11,10 +11,7 @@ import { User } from '../../types'
* @throws BadRequestError In case the password is invalid * @throws BadRequestError In case the password is invalid
* @internal * @internal
*/ */
export async function checkPassword( export async function checkPassword(this: TelegramClient, password: string): Promise<User> {
this: TelegramClient,
password: string,
): Promise<User> {
const res = await this.call({ const res = await this.call({
_: 'auth.checkPassword', _: 'auth.checkPassword',
password: await computeSrpParams( password: await computeSrpParams(
@ -26,16 +23,8 @@ export async function checkPassword(
), ),
}) })
assertTypeIs( assertTypeIs('checkPassword (@ auth.checkPassword)', res, 'auth.authorization')
'checkPassword (@ auth.checkPassword)', assertTypeIs('checkPassword (@ auth.checkPassword -> user)', res.user, 'user')
res,
'auth.authorization',
)
assertTypeIs(
'checkPassword (@ auth.checkPassword -> user)',
res.user,
'user',
)
this._userId = res.user.id this._userId = res.user.id
this.log.prefix = `[USER ${this._userId}] ` this.log.prefix = `[USER ${this._userId}] `

View file

@ -11,25 +11,14 @@ import { User } from '../../types'
* @throws BadRequestError In case the code is invalid * @throws BadRequestError In case the code is invalid
* @internal * @internal
*/ */
export async function recoverPassword( export async function recoverPassword(this: TelegramClient, recoveryCode: string): Promise<User> {
this: TelegramClient,
recoveryCode: string,
): Promise<User> {
const res = await this.call({ const res = await this.call({
_: 'auth.recoverPassword', _: 'auth.recoverPassword',
code: recoveryCode, code: recoveryCode,
}) })
assertTypeIs( assertTypeIs('recoverPassword (@ auth.recoverPassword)', res, 'auth.authorization')
'recoverPassword (@ auth.recoverPassword)', assertTypeIs('recoverPassword (@ auth.recoverPassword -> user)', res.user, 'user')
res,
'auth.authorization',
)
assertTypeIs(
'recoverPassword (@ auth.recoverPassword -> user)',
res.user,
'user',
)
this._userId = res.user.id this._userId = res.user.id
this._isBot = false this._isBot = false

View file

@ -14,11 +14,7 @@ import { normalizePhoneNumber } from '../../utils/misc-utils'
* @param phoneCodeHash Confirmation code identifier from {@link SentCode} * @param phoneCodeHash Confirmation code identifier from {@link SentCode}
* @internal * @internal
*/ */
export async function resendCode( export async function resendCode(this: TelegramClient, phone: string, phoneCodeHash: string): Promise<SentCode> {
this: TelegramClient,
phone: string,
phoneCodeHash: string,
): Promise<SentCode> {
phone = normalizePhoneNumber(phone) phone = normalizePhoneNumber(phone)
const res = await this.call({ const res = await this.call({

View file

@ -11,10 +11,7 @@ import { normalizePhoneNumber } from '../../utils/misc-utils'
* @returns An object containing information about the sent confirmation code * @returns An object containing information about the sent confirmation code
* @internal * @internal
*/ */
export async function sendCode( export async function sendCode(this: TelegramClient, phone: string): Promise<SentCode> {
this: TelegramClient,
phone: string,
): Promise<SentCode> {
phone = normalizePhoneNumber(phone) phone = normalizePhoneNumber(phone)
const res = await this.call({ const res = await this.call({

View file

@ -11,10 +11,7 @@ import { User } from '../../types'
* @throws BadRequestError In case the bot token is invalid * @throws BadRequestError In case the bot token is invalid
* @internal * @internal
*/ */
export async function signInBot( export async function signInBot(this: TelegramClient, token: string): Promise<User> {
this: TelegramClient,
token: string,
): Promise<User> {
const res = await this.call({ const res = await this.call({
_: 'auth.importBotAuthorization', _: 'auth.importBotAuthorization',
flags: 0, flags: 0,
@ -23,16 +20,8 @@ export async function signInBot(
botAuthToken: token, botAuthToken: token,
}) })
assertTypeIs( assertTypeIs('signInBot (@ auth.importBotAuthorization)', res, 'auth.authorization')
'signInBot (@ auth.importBotAuthorization)', assertTypeIs('signInBot (@ auth.importBotAuthorization -> user)', res.user, 'user')
res,
'auth.authorization',
)
assertTypeIs(
'signInBot (@ auth.importBotAuthorization -> user)',
res.user,
'user',
)
this._userId = res.user.id this._userId = res.user.id
this.log.prefix = `[USER ${this._userId}] ` this.log.prefix = `[USER ${this._userId}] `

View file

@ -72,9 +72,7 @@ export async function startTest(
if (phone) { if (phone) {
if (!phone.match(/^99966\d{5}/)) { if (!phone.match(/^99966\d{5}/)) {
throw new MtArgumentError( throw new MtArgumentError(`${phone} is an invalid test phone number`)
`${phone} is an invalid test phone number`,
)
} }
const id = parseInt(phone[5]) const id = parseInt(phone[5])

View file

@ -3,17 +3,8 @@ import { MtArgumentError } from '@mtcute/core'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { MaybeAsync, MaybeDynamic, SentCode, TermsOfService, User } from '../../types'
MaybeAsync, import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils'
MaybeDynamic,
SentCode,
TermsOfService,
User,
} from '../../types'
import {
normalizePhoneNumber,
resolveMaybeDynamic,
} from '../../utils/misc-utils'
/** /**
* Start the client in an interactive and declarative manner, * Start the client in an interactive and declarative manner,
@ -148,13 +139,7 @@ export async function start(
// user is already authorized // user is already authorized
this.log.prefix = `[USER ${me.id}] ` this.log.prefix = `[USER ${me.id}] `
this.log.info( this.log.info('Logged in as %s (ID: %s, username: %s, bot: %s)', me.displayName, me.id, me.username, me.isBot)
'Logged in as %s (ID: %s, username: %s, bot: %s)',
me.displayName,
me.id,
me.username,
me.isBot,
)
this.network.setIsPremium(me.isPremium) this.network.setIsPremium(me.isPremium)
@ -191,14 +176,10 @@ export async function start(
throw new MtArgumentError('You must pass `code` to use `phone`') throw new MtArgumentError('You must pass `code` to use `phone`')
} }
} else { } else {
const botToken = params.botToken ? const botToken = params.botToken ? await resolveMaybeDynamic(params.botToken) : null
await resolveMaybeDynamic(params.botToken) :
null
if (!botToken) { if (!botToken) {
throw new MtArgumentError( throw new MtArgumentError('Either bot token or phone number must be provided')
'Either bot token or phone number must be provided',
)
} }
return await this.signInBot(botToken) return await this.signInBot(botToken)
@ -258,9 +239,7 @@ export async function start(
if (has2fa) { if (has2fa) {
if (!params.password) { if (!params.password) {
throw new MtArgumentError( throw new MtArgumentError('2FA is enabled, but `password` was not provided.')
'2FA is enabled, but `password` was not provided.',
)
} }
for (;;) { for (;;) {

View file

@ -97,11 +97,7 @@ export async function answerInlineQuery(
): Promise<void> { ): Promise<void> {
if (!params) params = {} if (!params) params = {}
const [gallery, tlResults] = await BotInline._convertToTl( const [gallery, tlResults] = await BotInline._convertToTl(this, results, params.parseMode)
this,
results,
params.parseMode,
)
await this.call({ await this.call({
_: 'messages.setInlineBotResults', _: 'messages.setInlineBotResults',

View file

@ -9,11 +9,7 @@ import { TelegramClient } from '../../client'
* @param error If pre-checkout is rejected, error message to show to the user * @param error If pre-checkout is rejected, error message to show to the user
* @internal * @internal
*/ */
export async function answerPreCheckoutQuery( export async function answerPreCheckoutQuery(this: TelegramClient, queryId: tl.Long, error?: string): Promise<void> {
this: TelegramClient,
queryId: tl.Long,
error?: string,
): Promise<void> {
await this.call({ await this.call({
_: 'messages.setBotPrecheckoutResults', _: 'messages.setBotPrecheckoutResults',
queryId, queryId,

View file

@ -9,10 +9,7 @@ import { normalizeToInputUser } from '../../utils/peer-utils'
* *
* @internal * @internal
*/ */
export async function getBotMenuButton( export async function getBotMenuButton(this: TelegramClient, user: InputPeerLike): Promise<tl.TypeBotMenuButton> {
this: TelegramClient,
user: InputPeerLike,
): Promise<tl.TypeBotMenuButton> {
return await this.call({ return await this.call({
_: 'bots.getBotMenuButton', _: 'bots.getBotMenuButton',
userId: normalizeToInputUser(await this.resolvePeer(user), user), userId: normalizeToInputUser(await this.resolvePeer(user), user),

View file

@ -18,18 +18,12 @@ export async function _normalizeCommandScope(
const peer = await this.resolvePeer(scope.peer) const peer = await this.resolvePeer(scope.peer)
return { return {
_: _: scope.type === 'peer' ? 'botCommandScopePeer' : 'botCommandScopePeerAdmins',
scope.type === 'peer' ?
'botCommandScopePeer' :
'botCommandScopePeerAdmins',
peer, peer,
} }
} }
case 'member': { case 'member': {
const user = normalizeToInputUser( const user = normalizeToInputUser(await this.resolvePeer(scope.user), scope.user)
await this.resolvePeer(scope.user),
scope.user,
)
const chat = await this.resolvePeer(scope.chat) const chat = await this.resolvePeer(scope.chat)
return { return {

View file

@ -15,10 +15,7 @@ export async function setMyDefaultRights(
rights: Omit<tl.RawChatAdminRights, '_'>, rights: Omit<tl.RawChatAdminRights, '_'>,
): Promise<void> { ): Promise<void> {
await this.call({ await this.call({
_: _: target === 'group' ? 'bots.setBotGroupDefaultAdminRights' : 'bots.setBotBroadcastDefaultAdminRights',
target === 'group' ?
'bots.setBotGroupDefaultAdminRights' :
'bots.setBotBroadcastDefaultAdminRights',
adminRights: { adminRights: {
_: 'chatAdminRights', _: 'chatAdminRights',
...rights, ...rights,

View file

@ -10,10 +10,7 @@ import { InputPeerLike } from '../../types'
* @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"` * @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"`
* @internal * @internal
*/ */
export async function archiveChats( export async function archiveChats(this: TelegramClient, chats: MaybeArray<InputPeerLike>): Promise<void> {
this: TelegramClient,
chats: MaybeArray<InputPeerLike>,
): Promise<void> {
if (!Array.isArray(chats)) chats = [chats] if (!Array.isArray(chats)) chats = [chats]
const folderPeers: tl.TypeInputFolderPeer[] = [] const folderPeers: tl.TypeInputFolderPeer[] = []

View file

@ -51,10 +51,7 @@ export async function banChatMember(
try { try {
return this._findMessageInUpdate(res) return this._findMessageInUpdate(res)
} catch (e) { } catch (e) {
if ( if (e instanceof MtTypeAssertionError && e.context === '_findInUpdate (@ .updates[*])') {
e instanceof MtTypeAssertionError &&
e.context === '_findInUpdate (@ .updates[*])'
) {
// no service message // no service message
return null return null
} }

View file

@ -10,11 +10,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @returns Newly created channel * @returns Newly created channel
* @internal * @internal
*/ */
export async function createChannel( export async function createChannel(this: TelegramClient, title: string, description = ''): Promise<Chat> {
this: TelegramClient,
title: string,
description = '',
): Promise<Chat> {
const res = await this.call({ const res = await this.call({
_: 'channels.createChannel', _: 'channels.createChannel',
title, title,

View file

@ -9,11 +9,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @param description Description of the supergroup * @param description Description of the supergroup
* @internal * @internal
*/ */
export async function createSupergroup( export async function createSupergroup(this: TelegramClient, title: string, description = ''): Promise<Chat> {
this: TelegramClient,
title: string,
description = '',
): Promise<Chat> {
const res = await this.call({ const res = await this.call({
_: 'channels.createChannel', _: 'channels.createChannel',
title, title,

View file

@ -9,16 +9,10 @@ import { normalizeToInputChannel } from '../../utils/peer-utils'
* @param chatId Chat ID or username * @param chatId Chat ID or username
* @internal * @internal
*/ */
export async function deleteChannel( export async function deleteChannel(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
const res = await this.call({ const res = await this.call({
_: 'channels.deleteChannel', _: 'channels.deleteChannel',
channel: normalizeToInputChannel( channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId),
await this.resolvePeer(chatId),
chatId,
),
}) })
this._handleUpdate(res) this._handleUpdate(res)
} }

View file

@ -1,10 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
import { import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Delete a chat photo * Delete a chat photo
@ -14,10 +10,7 @@ import {
* @param chatId Chat ID or username * @param chatId Chat ID or username
* @internal * @internal
*/ */
export async function deleteChatPhoto( export async function deleteChatPhoto(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
const chat = await this.resolvePeer(chatId) const chat = await this.resolvePeer(chatId)
let res let res

View file

@ -8,10 +8,7 @@ import { isInputPeerChat } from '../../utils/peer-utils'
* @param chatId Chat ID * @param chatId Chat ID
* @internal * @internal
*/ */
export async function deleteGroup( export async function deleteGroup(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
const chat = await this.resolvePeer(chatId) const chat = await this.resolvePeer(chatId)
if (!isInputPeerChat(chat)) throw new MtInvalidPeerTypeError(chatId, 'chat') if (!isInputPeerChat(chat)) throw new MtInvalidPeerTypeError(chatId, 'chat')

View file

@ -35,9 +35,7 @@ export async function deleteHistory(
}) })
if (isInputPeerChannel(peer)) { if (isInputPeerChannel(peer)) {
this._handleUpdate( this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
createDummyUpdate(res.pts, res.ptsCount, peer.channelId),
)
} else { } else {
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount)) this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
} }

View file

@ -17,10 +17,7 @@ export async function deleteUserHistory(
chatId: InputPeerLike, chatId: InputPeerLike,
participantId: InputPeerLike, participantId: InputPeerLike,
): Promise<void> { ): Promise<void> {
const channel = normalizeToInputChannel( const channel = normalizeToInputChannel(await this.resolvePeer(chatId), chatId)
await this.resolvePeer(chatId),
chatId,
)
const peer = await this.resolvePeer(participantId) const peer = await this.resolvePeer(participantId)
@ -30,11 +27,5 @@ export async function deleteUserHistory(
participant: peer, participant: peer,
}) })
this._handleUpdate( this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount, (channel as tl.RawInputChannel).channelId))
createDummyUpdate(
res.pts,
res.ptsCount,
(channel as tl.RawInputChannel).channelId,
),
)
} }

View file

@ -2,10 +2,7 @@ import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike } from '../../types' import { InputPeerLike } from '../../types'
import { import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils'
normalizeToInputChannel,
normalizeToInputUser,
} from '../../utils/peer-utils'
/** /**
* Edit supergroup/channel admin rights of a user. * Edit supergroup/channel admin rights of a user.

View file

@ -4,16 +4,8 @@ import { assertNever, MaybeArray } from '@mtcute/core'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { ChatAction, ChatEvent, InputPeerLike, PeersIndex } from '../../types'
ChatAction, import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils'
ChatEvent,
InputPeerLike,
PeersIndex,
} from '../../types'
import {
normalizeToInputChannel,
normalizeToInputUser,
} from '../../utils/peer-utils'
/** /**
* Get chat event log ("Recent actions" in official * Get chat event log ("Recent actions" in official
@ -66,9 +58,7 @@ export async function* getChatEventLog(
* and when passing one or more action types, * and when passing one or more action types,
* they will be filtered locally. * they will be filtered locally.
*/ */
filters?: filters?: tl.TypeChannelAdminLogEventsFilter | MaybeArray<Exclude<ChatAction, null>['type']>
| tl.TypeChannelAdminLogEventsFilter
| MaybeArray<Exclude<ChatAction, null>['type']>
/** /**
* Limit the number of events returned. * Limit the number of events returned.
@ -101,16 +91,11 @@ export async function* getChatEventLog(
await this.resolvePeerMany(params.users, normalizeToInputUser) : await this.resolvePeerMany(params.users, normalizeToInputUser) :
undefined undefined
let serverFilter: let serverFilter: tl.Mutable<tl.TypeChannelAdminLogEventsFilter> | undefined = undefined
| tl.Mutable<tl.TypeChannelAdminLogEventsFilter>
| undefined = undefined
let localFilter: Record<string, true> | undefined = undefined let localFilter: Record<string, true> | undefined = undefined
if (params.filters) { if (params.filters) {
if ( if (typeof params.filters === 'string' || Array.isArray(params.filters)) {
typeof params.filters === 'string' ||
Array.isArray(params.filters)
) {
let input = params.filters let input = params.filters
if (!Array.isArray(input)) input = [input] if (!Array.isArray(input)) input = [input]
@ -224,10 +209,9 @@ export async function* getChatEventLog(
for (const evt of res.events) { for (const evt of res.events) {
const parsed = new ChatEvent(this, evt, peers) const parsed = new ChatEvent(this, evt, peers)
if ( if (localFilter && (!parsed.action || !localFilter[parsed.action.type])) {
localFilter && continue
(!parsed.action || !localFilter[parsed.action.type]) }
) { continue }
current += 1 current += 1
yield parsed yield parsed

View file

@ -2,18 +2,8 @@ import { assertTypeIs } from '@mtcute/core/utils'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types'
ChatMember, import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, normalizeToInputChannel } from '../../utils/peer-utils'
InputPeerLike,
MtInvalidPeerTypeError,
PeersIndex,
} from '../../types'
import {
isInputPeerChannel,
isInputPeerChat,
isInputPeerUser,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Get information about a single chat member * Get information about a single chat member
@ -41,23 +31,16 @@ export async function getChatMember(
chatId: chat.chatId, chatId: chat.chatId,
}) })
assertTypeIs( assertTypeIs('getChatMember (@ messages.getFullChat)', res.fullChat, 'chatFull')
'getChatMember (@ messages.getFullChat)',
res.fullChat,
'chatFull',
)
const members = const members =
res.fullChat.participants._ === 'chatParticipantsForbidden' ? res.fullChat.participants._ === 'chatParticipantsForbidden' ? [] : res.fullChat.participants.participants
[] :
res.fullChat.participants.participants
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
for (const m of members) { for (const m of members) {
if ( if (
(user._ === 'inputPeerSelf' && (user._ === 'inputPeerSelf' && (peers.user(m.userId) as tl.RawUser).self) ||
(peers.user(m.userId) as tl.RawUser).self) ||
(user._ === 'inputPeerUser' && m.userId === user.userId) (user._ === 'inputPeerUser' && m.userId === user.userId)
) { ) {
return new ChatMember(this, m, peers) return new ChatMember(this, m, peers)

View file

@ -5,18 +5,8 @@ import { assertTypeIs } from '@mtcute/core/utils'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types'
ArrayWithTotal, import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
ChatMember,
InputPeerLike,
MtInvalidPeerTypeError,
PeersIndex,
} from '../../types'
import {
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Get a chunk of members of some chat. * Get a chunk of members of some chat.
@ -63,15 +53,7 @@ export async function getChatMembers(
* *
* Only used for channels and supergroups. Defaults to `recent` * Only used for channels and supergroups. Defaults to `recent`
*/ */
type?: type?: 'all' | 'banned' | 'restricted' | 'bots' | 'recent' | 'admins' | 'contacts' | 'mention'
| 'all'
| 'banned'
| 'restricted'
| 'bots'
| 'recent'
| 'admins'
| 'contacts'
| 'mention'
}, },
): Promise<ArrayWithTotal<ChatMember>> { ): Promise<ArrayWithTotal<ChatMember>> {
if (!params) params = {} if (!params) params = {}
@ -84,25 +66,17 @@ export async function getChatMembers(
chatId: chat.chatId, chatId: chat.chatId,
}) })
assertTypeIs( assertTypeIs('getChatMember (@ messages.getFullChat)', res.fullChat, 'chatFull')
'getChatMember (@ messages.getFullChat)',
res.fullChat,
'chatFull',
)
let members = let members =
res.fullChat.participants._ === 'chatParticipantsForbidden' ? res.fullChat.participants._ === 'chatParticipantsForbidden' ? [] : res.fullChat.participants.participants
[] :
res.fullChat.participants.participants
if (params.offset) members = members.slice(params.offset) if (params.offset) members = members.slice(params.offset)
if (params.limit) members = members.slice(0, params.limit) if (params.limit) members = members.slice(0, params.limit)
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const ret = members.map( const ret = members.map((m) => new ChatMember(this, m, peers)) as ArrayWithTotal<ChatMember>
(m) => new ChatMember(this, m, peers),
) as ArrayWithTotal<ChatMember>
ret.total = ret.length ret.total = ret.length
@ -153,17 +127,11 @@ export async function getChatMembers(
hash: Long.ZERO, hash: Long.ZERO,
}) })
assertTypeIs( assertTypeIs('getChatMembers (@ channels.getParticipants)', res, 'channels.channelParticipants')
'getChatMembers (@ channels.getParticipants)',
res,
'channels.channelParticipants',
)
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const ret = res.participants.map( const ret = res.participants.map((i) => new ChatMember(this, i, peers)) as ArrayWithTotal<ChatMember>
(i) => new ChatMember(this, i, peers),
) as ArrayWithTotal<ChatMember>
ret.total = res.count ret.total = res.count
return ret return ret

View file

@ -14,10 +14,7 @@ import { INVITE_LINK_REGEX } from '../../utils/peer-utils'
* Use {@link getChat} or {@link getFullChat} instead. * Use {@link getChat} or {@link getFullChat} instead.
* @internal * @internal
*/ */
export async function getChatPreview( export async function getChatPreview(this: TelegramClient, inviteLink: string): Promise<ChatPreview> {
this: TelegramClient,
inviteLink: string,
): Promise<ChatPreview> {
const m = inviteLink.match(INVITE_LINK_REGEX) const m = inviteLink.match(INVITE_LINK_REGEX)
if (!m) throw new MtArgumentError('Invalid invite link') if (!m) throw new MtArgumentError('Invalid invite link')

View file

@ -21,10 +21,7 @@ import {
* Use {@link getChatPreview} instead. * Use {@link getChatPreview} instead.
* @internal * @internal
*/ */
export async function getChat( export async function getChat(this: TelegramClient, chatId: InputPeerLike): Promise<Chat> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<Chat> {
if (typeof chatId === 'string') { if (typeof chatId === 'string') {
const m = chatId.match(INVITE_LINK_REGEX) const m = chatId.match(INVITE_LINK_REGEX)
@ -35,9 +32,7 @@ export async function getChat(
}) })
if (res._ === 'chatInvite') { if (res._ === 'chatInvite') {
throw new MtArgumentError( throw new MtArgumentError(`You haven't joined ${JSON.stringify(res.title)}`)
`You haven't joined ${JSON.stringify(res.title)}`,
)
} }
return new Chat(this, res.chat) return new Chat(this, res.chat)

View file

@ -21,10 +21,7 @@ import {
* Use {@link getChatPreview} instead. * Use {@link getChatPreview} instead.
* @internal * @internal
*/ */
export async function getFullChat( export async function getFullChat(this: TelegramClient, chatId: InputPeerLike): Promise<Chat> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<Chat> {
if (typeof chatId === 'string') { if (typeof chatId === 'string') {
const m = chatId.match(INVITE_LINK_REGEX) const m = chatId.match(INVITE_LINK_REGEX)
@ -35,9 +32,7 @@ export async function getFullChat(
}) })
if (res._ === 'chatInvite') { if (res._ === 'chatInvite') {
throw new MtArgumentError( throw new MtArgumentError(`You haven't joined ${JSON.stringify(res.title)}`)
`You haven't joined ${JSON.stringify(res.title)}`,
)
} }
// we still need to fetch full chat info // we still need to fetch full chat info

View file

@ -13,11 +13,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @param longitude Longitude of the location * @param longitude Longitude of the location
* @internal * @internal
*/ */
export async function getNearbyChats( export async function getNearbyChats(this: TelegramClient, latitude: number, longitude: number): Promise<Chat[]> {
this: TelegramClient,
latitude: number,
longitude: number,
): Promise<Chat[]> {
const res = await this.call({ const res = await this.call({
_: 'contacts.getLocated', _: 'contacts.getLocated',
geoPoint: { geoPoint: {
@ -32,11 +28,7 @@ export async function getNearbyChats(
if (!res.updates.length) return [] if (!res.updates.length) return []
assertTypeIs( assertTypeIs('contacts.getLocated (@ .updates[0])', res.updates[0], 'updatePeerLocated')
'contacts.getLocated (@ .updates[0])',
res.updates[0],
'updatePeerLocated',
)
const chats = res.chats.map((it) => new Chat(this, it)) const chats = res.chats.map((it) => new Chat(this, it))

View file

@ -1,9 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { Chat, InputPeerLike } from '../../types' import { Chat, InputPeerLike } from '../../types'
import { import { INVITE_LINK_REGEX, normalizeToInputChannel } from '../../utils/peer-utils'
INVITE_LINK_REGEX,
normalizeToInputChannel,
} from '../../utils/peer-utils'
import { assertIsUpdatesGroup } from '../../utils/updates-utils' import { assertIsUpdatesGroup } from '../../utils/updates-utils'
/** /**
@ -18,10 +15,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* or ID of the linked supergroup or channel. * or ID of the linked supergroup or channel.
* @internal * @internal
*/ */
export async function joinChat( export async function joinChat(this: TelegramClient, chatId: InputPeerLike): Promise<Chat> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<Chat> {
if (typeof chatId === 'string') { if (typeof chatId === 'string') {
const m = chatId.match(INVITE_LINK_REGEX) const m = chatId.match(INVITE_LINK_REGEX)
@ -40,10 +34,7 @@ export async function joinChat(
const res = await this.call({ const res = await this.call({
_: 'channels.joinChannel', _: 'channels.joinChannel',
channel: normalizeToInputChannel( channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId),
await this.resolvePeer(chatId),
chatId,
),
}) })
assertIsUpdatesGroup('channels.joinChannel', res) assertIsUpdatesGroup('channels.joinChannel', res)

View file

@ -1,10 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
import { import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Leave a group chat, supergroup or channel * Leave a group chat, supergroup or channel
@ -13,11 +9,7 @@ import {
* @param clear Whether to clear history after leaving (only for legacy group chats) * @param clear Whether to clear history after leaving (only for legacy group chats)
* @internal * @internal
*/ */
export async function leaveChat( export async function leaveChat(this: TelegramClient, chatId: InputPeerLike, clear = false): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
clear = false,
): Promise<void> {
const chat = await this.resolvePeer(chatId) const chat = await this.resolvePeer(chatId)
if (isInputPeerChannel(chat)) { if (isInputPeerChannel(chat)) {

View file

@ -7,10 +7,7 @@ import { InputPeerLike } from '../../types'
* @param chatId Chat ID * @param chatId Chat ID
* @internal * @internal
*/ */
export async function markChatUnread( export async function markChatUnread(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
await this.call({ await this.call({
_: 'messages.markDialogUnread', _: 'messages.markDialogUnread',
peer: { peer: {

View file

@ -3,10 +3,7 @@ import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
import { normalizeDate } from '../../utils/misc-utils' import { normalizeDate } from '../../utils/misc-utils'
import { import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Restrict a user in a supergroup. * Restrict a user in a supergroup.
@ -34,7 +31,9 @@ export async function restrictChatMember(
): Promise<void> { ): Promise<void> {
const chat = await this.resolvePeer(chatId) const chat = await this.resolvePeer(chatId)
if (!isInputPeerChannel(chat)) { throw new MtInvalidPeerTypeError(chatId, 'channel') } if (!isInputPeerChannel(chat)) {
throw new MtInvalidPeerTypeError(chatId, 'channel')
}
const user = await this.resolvePeer(userId) const user = await this.resolvePeer(userId)

View file

@ -3,17 +3,8 @@ import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { InputFileLike, InputPeerLike, isUploadedFile, MtInvalidPeerTypeError } from '../../types'
InputFileLike, import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
InputPeerLike,
isUploadedFile,
MtInvalidPeerTypeError,
} from '../../types'
import {
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Set a new chat photo or video. * Set a new chat photo or video.

View file

@ -1,10 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
import { import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Change chat title * Change chat title
@ -15,11 +11,7 @@ import {
* @param title New chat title, 1-255 characters * @param title New chat title, 1-255 characters
* @internal * @internal
*/ */
export async function setChatTitle( export async function setChatTitle(this: TelegramClient, chatId: InputPeerLike, title: string): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
title: string,
): Promise<void> {
const chat = await this.resolvePeer(chatId) const chat = await this.resolvePeer(chatId)
let res let res

View file

@ -18,10 +18,7 @@ export async function setChatUsername(
): Promise<void> { ): Promise<void> {
await this.call({ await this.call({
_: 'channels.updateUsername', _: 'channels.updateUsername',
channel: normalizeToInputChannel( channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId),
await this.resolvePeer(chatId),
chatId,
),
username: username || '', username: username || '',
}) })
} }

View file

@ -12,17 +12,10 @@ import { normalizeToInputChannel } from '../../utils/peer-utils'
* Valid values are: `0 (off), 10, 30, 60 (1m), 300 (5m), 900 (15m) or 3600 (1h)` * Valid values are: `0 (off), 10, 30, 60 (1m), 300 (5m), 900 (15m) or 3600 (1h)`
* @internal * @internal
*/ */
export async function setSlowMode( export async function setSlowMode(this: TelegramClient, chatId: InputPeerLike, seconds = 0): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
seconds = 0,
): Promise<void> {
const res = await this.call({ const res = await this.call({
_: 'channels.toggleSlowMode', _: 'channels.toggleSlowMode',
channel: normalizeToInputChannel( channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId),
await this.resolvePeer(chatId),
chatId,
),
seconds, seconds,
}) })
this._handleUpdate(res) this._handleUpdate(res)

View file

@ -10,10 +10,7 @@ import { InputPeerLike } from '../../types'
* @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"` * @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"`
* @internal * @internal
*/ */
export async function unarchiveChats( export async function unarchiveChats(this: TelegramClient, chats: MaybeArray<InputPeerLike>): Promise<void> {
this: TelegramClient,
chats: MaybeArray<InputPeerLike>,
): Promise<void> {
if (!Array.isArray(chats)) chats = [chats] if (!Array.isArray(chats)) chats = [chats]
const folderPeers: tl.TypeInputFolderPeer[] = [] const folderPeers: tl.TypeInputFolderPeer[] = []

View file

@ -1,10 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
import { import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
} from '../../utils/peer-utils'
// @alias=unrestrictChatMember // @alias=unrestrictChatMember
/** /**

View file

@ -14,10 +14,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @param userId User ID, username or phone number * @param userId User ID, username or phone number
* @internal * @internal
*/ */
export async function deleteContacts( export async function deleteContacts(this: TelegramClient, userId: InputPeerLike): Promise<User | null>
this: TelegramClient,
userId: InputPeerLike
): Promise<User | null>
/** /**
* Delete one or more contacts from your Telegram contacts list * Delete one or more contacts from your Telegram contacts list
@ -28,10 +25,7 @@ export async function deleteContacts(
* @param userIds User IDs, usernames or phone numbers * @param userIds User IDs, usernames or phone numbers
* @internal * @internal
*/ */
export async function deleteContacts( export async function deleteContacts(this: TelegramClient, userIds: InputPeerLike[]): Promise<User[]>
this: TelegramClient,
userIds: InputPeerLike[]
): Promise<User[]>
/** @internal */ /** @internal */
export async function deleteContacts( export async function deleteContacts(
@ -41,16 +35,10 @@ export async function deleteContacts(
const single = !Array.isArray(userIds) const single = !Array.isArray(userIds)
if (single) userIds = [userIds as InputPeerLike] if (single) userIds = [userIds as InputPeerLike]
const inputPeers = await this.resolvePeerMany( const inputPeers = await this.resolvePeerMany(userIds as InputPeerLike[], normalizeToInputUser)
userIds as InputPeerLike[],
normalizeToInputUser,
)
if (single && !inputPeers.length) { if (single && !inputPeers.length) {
throw new MtInvalidPeerTypeError( throw new MtInvalidPeerTypeError((userIds as InputPeerLike[])[0], 'user')
(userIds as InputPeerLike[])[0],
'user',
)
} }
const res = await this.call({ const res = await this.call({

View file

@ -17,11 +17,7 @@ function _initializeConversation(this: TelegramClient) {
} }
/** @internal */ /** @internal */
export function _pushConversationMessage( export function _pushConversationMessage(this: TelegramClient, msg: Message, incoming = false): void {
this: TelegramClient,
msg: Message,
incoming = false,
): void {
// shortcut // shortcut
if (!this._hasConversations) return if (!this._hasConversations) return

View file

@ -8,10 +8,7 @@ import { TelegramClient } from '../../client'
* @param id Folder ID or folder itself * @param id Folder ID or folder itself
* @internal * @internal
*/ */
export async function deleteFolder( export async function deleteFolder(this: TelegramClient, id: number | tl.RawDialogFilter): Promise<void> {
this: TelegramClient,
id: number | tl.RawDialogFilter,
): Promise<void> {
await this.call({ await this.call({
_: 'messages.updateDialogFilter', _: 'messages.updateDialogFilter',
id: typeof id === 'number' ? id : id.id, id: typeof id === 'number' ? id : id.id,

View file

@ -25,11 +25,7 @@ export async function editFolder(
} }
if (typeof folder === 'number' || typeof folder === 'string') { if (typeof folder === 'number' || typeof folder === 'string') {
const old = await this.getFolders() const old = await this.getFolders()
const found = old.find( const found = old.find((it) => it._ === 'dialogFilter' && (it.id === folder || it.title === folder))
(it) =>
it._ === 'dialogFilter' &&
(it.id === folder || it.title === folder),
)
if (!found) { if (!found) {
throw new MtArgumentError(`Could not find a folder ${folder}`) throw new MtArgumentError(`Could not find a folder ${folder}`)

View file

@ -122,10 +122,7 @@ export async function* getDialogs(
// fetch folder if needed // fetch folder if needed
let filters: tl.TypeDialogFilter | undefined let filters: tl.TypeDialogFilter | undefined
if ( if (typeof params.folder === 'string' || typeof params.folder === 'number') {
typeof params.folder === 'string' ||
typeof params.folder === 'number'
) {
const folders = await this.getFolders() const folders = await this.getFolders()
const found = folders.find((it) => { const found = folders.find((it) => {
if (it._ === 'dialogFilterDefault') { if (it._ === 'dialogFilterDefault') {
@ -157,38 +154,28 @@ export async function* getDialogs(
} }
} }
const fetchPinnedDialogsFromFolder = const fetchPinnedDialogsFromFolder = async (): Promise<tl.messages.RawPeerDialogs | null> => {
async (): Promise<tl.messages.RawPeerDialogs | null> => { if (!filters || filters._ === 'dialogFilterDefault' || !filters.pinnedPeers.length) {
if ( return null
!filters ||
filters._ === 'dialogFilterDefault' ||
!filters.pinnedPeers.length
) {
return null
}
const res = await this.call({
_: 'messages.getPeerDialogs',
peers: filters.pinnedPeers.map((peer) => ({
_: 'inputDialogPeer',
peer,
})),
})
res.dialogs.forEach(
(dialog: tl.Mutable<tl.TypeDialog>) => (dialog.pinned = true),
)
return res
} }
const res = await this.call({
_: 'messages.getPeerDialogs',
peers: filters.pinnedPeers.map((peer) => ({
_: 'inputDialogPeer',
peer,
})),
})
res.dialogs.forEach((dialog: tl.Mutable<tl.TypeDialog>) => (dialog.pinned = true))
return res
}
const pinned = params.pinned ?? 'include' const pinned = params.pinned ?? 'include'
let archived = params.archived ?? 'exclude' let archived = params.archived ?? 'exclude'
if (filters) { if (filters) {
archived = archived = filters._ !== 'dialogFilterDefault' && filters.excludeArchived ? 'exclude' : 'keep'
filters._ !== 'dialogFilterDefault' && filters.excludeArchived ?
'exclude' :
'keep'
} }
if (pinned === 'only') { if (pinned === 'only') {
@ -215,12 +202,7 @@ export async function* getDialogs(
let offsetDate = normalizeDate(params.offsetDate) ?? 0 let offsetDate = normalizeDate(params.offsetDate) ?? 0
let offsetPeer = params.offsetPeer ?? { _: 'inputPeerEmpty' } let offsetPeer = params.offsetPeer ?? { _: 'inputPeerEmpty' }
if ( if (filters && filters._ !== 'dialogFilterDefault' && filters.pinnedPeers.length && pinned === 'include') {
filters &&
filters._ !== 'dialogFilterDefault' &&
filters.pinnedPeers.length &&
pinned === 'include'
) {
const res = await fetchPinnedDialogsFromFolder() const res = await fetchPinnedDialogsFromFolder()
if (res) { if (res) {
@ -238,9 +220,7 @@ export async function* getDialogs(
// if pinned is `exclude`, we want to exclude them // if pinned is `exclude`, we want to exclude them
// if pinned is `include`, we already yielded them, so we also want to exclude them // if pinned is `include`, we already yielded them, so we also want to exclude them
// if pinned is `keep`, we want to keep them // if pinned is `keep`, we want to keep them
const filterFolder = filters ? const filterFolder = filters ? Dialog.filterFolder(filters, pinned !== 'keep') : undefined
Dialog.filterFolder(filters, pinned !== 'keep') :
undefined
let folderId let folderId

View file

@ -6,9 +6,7 @@ import { TelegramClient } from '../../client'
* Get list of folders. * Get list of folders.
* @internal * @internal
*/ */
export async function getFolders( export async function getFolders(this: TelegramClient): Promise<tl.TypeDialogFilter[]> {
this: TelegramClient,
): Promise<tl.TypeDialogFilter[]> {
return this.call({ return this.call({
_: 'messages.getDialogFilters', _: 'messages.getDialogFilters',
}) })

View file

@ -9,20 +9,14 @@ import { Dialog, InputPeerLike } from '../../types'
* @param peers Peers for which to fetch dialogs. * @param peers Peers for which to fetch dialogs.
* @internal * @internal
*/ */
export async function getPeerDialogs( export async function getPeerDialogs(this: TelegramClient, peers: InputPeerLike): Promise<Dialog>
this: TelegramClient,
peers: InputPeerLike
): Promise<Dialog>
/** /**
* Get dialogs with certain peers. * Get dialogs with certain peers.
* *
* @param peers Peers for which to fetch dialogs. * @param peers Peers for which to fetch dialogs.
* @internal * @internal
*/ */
export async function getPeerDialogs( export async function getPeerDialogs(this: TelegramClient, peers: InputPeerLike[]): Promise<Dialog[]>
this: TelegramClient,
peers: InputPeerLike[]
): Promise<Dialog[]>
/** /**
* @internal * @internal
@ -36,12 +30,11 @@ export async function getPeerDialogs(
const res = await this.call({ const res = await this.call({
_: 'messages.getPeerDialogs', _: 'messages.getPeerDialogs',
peers: await this.resolvePeerMany(peers as InputPeerLike[]).then( peers: await this.resolvePeerMany(peers as InputPeerLike[]).then((peers) =>
(peers) => peers.map((it) => ({
peers.map((it) => ({ _: 'inputDialogPeer',
_: 'inputDialogPeer', peer: it,
peer: it, })),
})),
), ),
}) })

View file

@ -7,10 +7,7 @@ import { TelegramClient } from '../../client'
* *
* @internal * @internal
*/ */
export async function setFoldersOrder( export async function setFoldersOrder(this: TelegramClient, order: number[]): Promise<void> {
this: TelegramClient,
order: number[],
): Promise<void> {
await this.call({ await this.call({
_: 'messages.updateDialogFiltersOrder', _: 'messages.updateDialogFiltersOrder',
order, order,

View file

@ -10,14 +10,8 @@ import { FileDownloadParameters, FileLocation } from '../../types'
* @param params File download parameters * @param params File download parameters
* @internal * @internal
*/ */
export async function downloadAsBuffer( export async function downloadAsBuffer(this: TelegramClient, params: FileDownloadParameters): Promise<Buffer> {
this: TelegramClient, if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) {
params: FileDownloadParameters,
): Promise<Buffer> {
if (
params.location instanceof FileLocation &&
Buffer.isBuffer(params.location.location)
) {
return params.location.location return params.location.location
} }

View file

@ -16,21 +16,12 @@ try {
* @param params File download parameters * @param params File download parameters
* @internal * @internal
*/ */
export function downloadToFile( export function downloadToFile(this: TelegramClient, filename: string, params: FileDownloadParameters): Promise<void> {
this: TelegramClient,
filename: string,
params: FileDownloadParameters,
): Promise<void> {
if (!fs) { if (!fs) {
throw new MtUnsupportedError( throw new MtUnsupportedError('Downloading to file is only supported in NodeJS')
'Downloading to file is only supported in NodeJS',
)
} }
if ( if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) {
params.location instanceof FileLocation &&
Buffer.isBuffer(params.location.location)
) {
// early return for inline files // early return for inline files
const buf = params.location.location const buf = params.location.location
@ -46,10 +37,6 @@ export function downloadToFile(
const stream = this.downloadAsStream(params) const stream = this.downloadAsStream(params)
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stream stream.on('error', reject).pipe(output).on('finish', resolve).on('error', reject)
.on('error', reject)
.pipe(output)
.on('finish', resolve)
.on('error', reject)
}) })
} }

View file

@ -1,14 +1,6 @@
import { import { ConnectionKind, MtArgumentError, MtUnsupportedError } from '@mtcute/core'
ConnectionKind,
MtArgumentError,
MtUnsupportedError,
} from '@mtcute/core'
import { ConditionVariable } from '@mtcute/core/utils' import { ConditionVariable } from '@mtcute/core/utils'
import { import { fileIdToInputFileLocation, fileIdToInputWebFileLocation, parseFileId } from '@mtcute/file-id'
fileIdToInputFileLocation,
fileIdToInputWebFileLocation,
parseFileId,
} from '@mtcute/file-id'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
@ -36,9 +28,7 @@ export async function* downloadAsIterable(
const offset = params.offset ?? 0 const offset = params.offset ?? 0
if (offset % 4096 !== 0) { if (offset % 4096 !== 0) {
throw new MtArgumentError( throw new MtArgumentError(`Invalid offset: ${offset}. Must be divisible by 4096`)
`Invalid offset: ${offset}. Must be divisible by 4096`,
)
} }
let dcId = params.dcId let dcId = params.dcId
@ -76,13 +66,10 @@ export async function* downloadAsIterable(
// we will receive a FileMigrateError in case this is invalid // we will receive a FileMigrateError in case this is invalid
if (!dcId) dcId = this._defaultDcs.main.id if (!dcId) dcId = this._defaultDcs.main.id
const partSizeKb = const partSizeKb = params.partSize ?? (fileSize ? determinePartSize(fileSize) : 64)
params.partSize ?? (fileSize ? determinePartSize(fileSize) : 64)
if (partSizeKb % 4 !== 0) { if (partSizeKb % 4 !== 0) {
throw new MtArgumentError( throw new MtArgumentError(`Invalid part size: ${partSizeKb}. Must be divisible by 4.`)
`Invalid part size: ${partSizeKb}. Must be divisible by 4.`,
)
} }
const chunkSize = partSizeKb * 1024 const chunkSize = partSizeKb * 1024
@ -90,10 +77,7 @@ export async function* downloadAsIterable(
let limitBytes = params.limit ?? fileSize ?? Infinity let limitBytes = params.limit ?? fileSize ?? Infinity
if (limitBytes === 0) return if (limitBytes === 0) return
let numChunks = let numChunks = limitBytes === Infinity ? Infinity : ~~((limitBytes + chunkSize - offset - 1) / chunkSize)
limitBytes === Infinity ?
Infinity :
~~((limitBytes + chunkSize - offset - 1) / chunkSize)
let nextChunkIdx = 0 let nextChunkIdx = 0
let nextWorkerChunkIdx = 0 let nextWorkerChunkIdx = 0
@ -104,8 +88,7 @@ export async function* downloadAsIterable(
let connectionKind: ConnectionKind let connectionKind: ConnectionKind
if (isSmall) { if (isSmall) {
connectionKind = connectionKind = dcId === this.network.getPrimaryDcId() ? 'main' : 'downloadSmall'
dcId === this.network.getPrimaryDcId() ? 'main' : 'downloadSmall'
} else { } else {
connectionKind = 'download' connectionKind = 'download'
} }
@ -119,12 +102,8 @@ export async function* downloadAsIterable(
poolSize, poolSize,
) )
const downloadChunk = async ( const downloadChunk = async (chunk = nextWorkerChunkIdx++): Promise<void> => {
chunk = nextWorkerChunkIdx++, let result: tl.RpcCallReturn['upload.getFile'] | tl.RpcCallReturn['upload.getWebFile']
): Promise<void> => {
let result:
| tl.RpcCallReturn['upload.getFile']
| tl.RpcCallReturn['upload.getWebFile']
try { try {
result = await this.call( result = await this.call(
@ -155,16 +134,10 @@ export async function* downloadAsIterable(
// we shouldnt receive them since cdnSupported is not set in the getFile request. // we shouldnt receive them since cdnSupported is not set in the getFile request.
// also, i couldnt find any media that would be downloaded from cdn, so even if // also, i couldnt find any media that would be downloaded from cdn, so even if
// i implemented that, i wouldnt be able to test that, so :shrug: // i implemented that, i wouldnt be able to test that, so :shrug:
throw new MtUnsupportedError( throw new MtUnsupportedError('Received CDN redirect, which is not supported (yet)')
'Received CDN redirect, which is not supported (yet)',
)
} }
if ( if (result._ === 'upload.webFile' && result.size && limitBytes === Infinity) {
result._ === 'upload.webFile' &&
result.size &&
limitBytes === Infinity
) {
limitBytes = result.size limitBytes = result.size
numChunks = ~~((limitBytes + chunkSize - offset - 1) / chunkSize) numChunks = ~~((limitBytes + chunkSize - offset - 1) / chunkSize)
} }
@ -175,21 +148,13 @@ export async function* downloadAsIterable(
nextChunkCv.notify() nextChunkCv.notify()
} }
if ( if (nextWorkerChunkIdx < numChunks && result.bytes.length === chunkSize) {
nextWorkerChunkIdx < numChunks &&
result.bytes.length === chunkSize
) {
return downloadChunk() return downloadChunk()
} }
} }
let error: unknown = undefined let error: unknown = undefined
void Promise.all( void Promise.all(Array.from({ length: Math.min(poolSize * REQUESTS_PER_CONNECTION, numChunks) }, downloadChunk))
Array.from(
{ length: Math.min(poolSize * REQUESTS_PER_CONNECTION, numChunks) },
downloadChunk,
),
)
.catch((e) => { .catch((e) => {
this.log.debug('download workers errored: %s', e.message) this.log.debug('download workers errored: %s', e.message)
error = e error = e

View file

@ -11,14 +11,8 @@ import { bufferToStream } from '../../utils/stream-utils'
* @param params File download parameters * @param params File download parameters
* @internal * @internal
*/ */
export function downloadAsStream( export function downloadAsStream(this: TelegramClient, params: FileDownloadParameters): Readable {
this: TelegramClient, if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) {
params: FileDownloadParameters,
): Readable {
if (
params.location instanceof FileLocation &&
Buffer.isBuffer(params.location.location)
) {
return bufferToStream(params.location.location) return bufferToStream(params.location.location)
} }

View file

@ -22,9 +22,7 @@ export async function _normalizeInputFile(
}, },
): Promise<tl.TypeInputFile> { ): Promise<tl.TypeInputFile> {
if (typeof input === 'object' && tl.isAnyInputMedia(input)) { if (typeof input === 'object' && tl.isAnyInputMedia(input)) {
throw new MtArgumentError( throw new MtArgumentError("InputFile can't be created from an InputMedia")
"InputFile can't be created from an InputMedia",
)
} else if (tdFileId.isFileIdLike(input)) { } else if (tdFileId.isFileIdLike(input)) {
if (typeof input === 'string' && input.match(/^file:/)) { if (typeof input === 'string' && input.match(/^file:/)) {
const uploaded = await this.uploadFile({ const uploaded = await this.uploadFile({
@ -34,9 +32,7 @@ export async function _normalizeInputFile(
return uploaded.inputFile return uploaded.inputFile
} }
throw new MtArgumentError( throw new MtArgumentError("InputFile can't be created from an URL or a File ID")
"InputFile can't be created from an URL or a File ID",
)
} else if (isUploadedFile(input)) { } else if (isUploadedFile(input)) {
return input.inputFile return input.inputFile
} else if (typeof input === 'object' && tl.isAnyInputFile(input)) { } else if (typeof input === 'object' && tl.isAnyInputFile(input)) {

View file

@ -1,12 +1,7 @@
import Long from 'long' import Long from 'long'
import { assertTypeIs } from '@mtcute/core/utils' import { assertTypeIs } from '@mtcute/core/utils'
import { import { fileIdToInputDocument, fileIdToInputPhoto, parseFileId, tdFileId } from '@mtcute/file-id'
fileIdToInputDocument,
fileIdToInputPhoto,
parseFileId,
tdFileId,
} from '@mtcute/file-id'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
@ -205,9 +200,7 @@ export async function _normalizeInputMedia(
let sendMime let sendMime
if (media.type === 'sticker') { if (media.type === 'sticker') {
sendMime = media.isAnimated ? sendMime = media.isAnimated ? 'application/x-tgsticker' : 'image/webp'
'application/x-tgsticker' :
'image/webp'
} else { } else {
sendMime = media.fileMime sendMime = media.fileMime
} }
@ -225,10 +218,7 @@ export async function _normalizeInputMedia(
const uploadPeer = params.uploadPeer ?? { _: 'inputPeerSelf' } const uploadPeer = params.uploadPeer ?? { _: 'inputPeerSelf' }
const uploadMediaIfNeeded = async ( const uploadMediaIfNeeded = async (inputMedia: tl.TypeInputMedia, photo: boolean): Promise<tl.TypeInputMedia> => {
inputMedia: tl.TypeInputMedia,
photo: boolean,
): Promise<tl.TypeInputMedia> => {
if (!uploadMedia) return inputMedia if (!uploadMedia) return inputMedia
const res = await this.call({ const res = await this.call({
@ -238,16 +228,8 @@ export async function _normalizeInputMedia(
}) })
if (photo) { if (photo) {
assertTypeIs( assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res, 'messageMediaPhoto')
'normalizeInputMedia (@ messages.uploadMedia)', assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res.photo!, 'photo')
res,
'messageMediaPhoto',
)
assertTypeIs(
'normalizeInputMedia (@ messages.uploadMedia)',
res.photo!,
'photo',
)
return { return {
_: 'inputMediaPhoto', _: 'inputMediaPhoto',
@ -260,16 +242,8 @@ export async function _normalizeInputMedia(
ttlSeconds: media.ttlSeconds, ttlSeconds: media.ttlSeconds,
} }
} }
assertTypeIs( assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res, 'messageMediaDocument')
'normalizeInputMedia (@ messages.uploadMedia)', assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res.document!, 'document')
res,
'messageMediaDocument',
)
assertTypeIs(
'normalizeInputMedia (@ messages.uploadMedia)',
res.document!,
'document',
)
return { return {
_: 'inputMediaDocument', _: 'inputMediaDocument',
@ -289,10 +263,7 @@ export async function _normalizeInputMedia(
if (typeof input === 'string' && input.match(/^https?:\/\//)) { if (typeof input === 'string' && input.match(/^https?:\/\//)) {
return uploadMediaIfNeeded( return uploadMediaIfNeeded(
{ {
_: _: media.type === 'photo' ? 'inputMediaPhotoExternal' : 'inputMediaDocumentExternal',
media.type === 'photo' ?
'inputMediaPhotoExternal' :
'inputMediaDocumentExternal',
url: input, url: input,
}, },
media.type === 'photo', media.type === 'photo',
@ -300,8 +271,7 @@ export async function _normalizeInputMedia(
} else if (typeof input === 'string' && input.match(/^file:/)) { } else if (typeof input === 'string' && input.match(/^file:/)) {
await upload(input.substring(5)) await upload(input.substring(5))
} else { } else {
const parsed = const parsed = typeof input === 'string' ? parseFileId(input) : input
typeof input === 'string' ? parseFileId(input) : input
if (parsed.location._ === 'photo') { if (parsed.location._ === 'photo') {
return { return {
@ -359,11 +329,7 @@ export async function _normalizeInputMedia(
if (media.type !== 'voice') { if (media.type !== 'voice') {
attributes.push({ attributes.push({
_: 'documentAttributeFilename', _: 'documentAttributeFilename',
fileName: fileName: media.fileName || (typeof media.file === 'string' ? extractFileName(media.file) : 'unnamed'),
media.fileName ||
(typeof media.file === 'string' ?
extractFileName(media.file) :
'unnamed'),
}) })
} }
@ -389,10 +355,7 @@ export async function _normalizeInputMedia(
duration: media.duration || 0, duration: media.duration || 0,
title: media.type === 'audio' ? media.title : undefined, title: media.type === 'audio' ? media.title : undefined,
performer: media.type === 'audio' ? media.performer : undefined, performer: media.type === 'audio' ? media.performer : undefined,
waveform: waveform: media.type === 'voice' && media.waveform ? encodeWaveform(media.waveform) : undefined,
media.type === 'voice' && media.waveform ?
encodeWaveform(media.waveform) :
undefined,
}) })
} }

View file

@ -9,11 +9,7 @@ import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { UploadedFile, UploadFileLike } from '../../types' import { UploadedFile, UploadFileLike } from '../../types'
import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils' import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils'
import { import { bufferToStream, convertWebStreamToNodeReadable, readBytesFromStream } from '../../utils/stream-utils'
bufferToStream,
convertWebStreamToNodeReadable,
readBytesFromStream,
} from '../../utils/stream-utils'
let fs: typeof import('fs') | null = null let fs: typeof import('fs') | null = null
let path: typeof import('path') | null = null let path: typeof import('path') | null = null
@ -124,9 +120,7 @@ export async function uploadFile(
if (typeof file === 'string') { if (typeof file === 'string') {
if (!fs) { if (!fs) {
throw new MtArgumentError( throw new MtArgumentError('Local paths are only supported for NodeJS!')
'Local paths are only supported for NodeJS!',
)
} }
file = fs.createReadStream(file) file = fs.createReadStream(file)
} }
@ -142,19 +136,11 @@ export async function uploadFile(
// fs.ReadStream is a subclass of Readable, no conversion needed // fs.ReadStream is a subclass of Readable, no conversion needed
} }
if ( if (typeof ReadableStream !== 'undefined' && file instanceof ReadableStream) {
typeof ReadableStream !== 'undefined' &&
file instanceof ReadableStream
) {
file = convertWebStreamToNodeReadable(file) file = convertWebStreamToNodeReadable(file)
} }
if ( if (typeof file === 'object' && 'headers' in file && 'body' in file && 'url' in file) {
typeof file === 'object' &&
'headers' in file &&
'body' in file &&
'url' in file
) {
// fetch() response // fetch() response
const length = parseInt(file.headers.get('content-length') || '0') const length = parseInt(file.headers.get('content-length') || '0')
if (!isNaN(length) && length) fileSize = length if (!isNaN(length) && length) fileSize = length
@ -186,10 +172,7 @@ export async function uploadFile(
throw new MtArgumentError('Fetch response contains `null` body') throw new MtArgumentError('Fetch response contains `null` body')
} }
if ( if (typeof ReadableStream !== 'undefined' && file.body instanceof ReadableStream) {
typeof ReadableStream !== 'undefined' &&
file.body instanceof ReadableStream
) {
file = convertWebStreamToNodeReadable(file.body) file = convertWebStreamToNodeReadable(file.body)
} else { } else {
file = file.body file = file.body
@ -206,9 +189,7 @@ export async function uploadFile(
if (!partSizeKb) { if (!partSizeKb) {
if (fileSize === -1) { if (fileSize === -1) {
partSizeKb = params.estimatedSize ? partSizeKb = params.estimatedSize ? determinePartSize(params.estimatedSize) : 64
determinePartSize(params.estimatedSize) :
64
} else { } else {
partSizeKb = determinePartSize(fileSize) partSizeKb = determinePartSize(fileSize)
} }
@ -223,27 +204,18 @@ export async function uploadFile(
} }
const partSize = partSizeKb * 1024 const partSize = partSizeKb * 1024
let partCount = let partCount = fileSize === -1 ? -1 : ~~((fileSize + partSize - 1) / partSize)
fileSize === -1 ? -1 : ~~((fileSize + partSize - 1) / partSize) const maxPartCount = this.network.params.isPremium ? MAX_PART_COUNT_PREMIUM : MAX_PART_COUNT
const maxPartCount = this.network.params.isPremium ?
MAX_PART_COUNT_PREMIUM :
MAX_PART_COUNT
if (partCount > maxPartCount) { if (partCount > maxPartCount) {
throw new MtArgumentError( throw new MtArgumentError(`File is too large (max ${maxPartCount} parts, got ${partCount})`)
`File is too large (max ${maxPartCount} parts, got ${partCount})`,
)
} }
const isBig = fileSize === -1 || fileSize > BIG_FILE_MIN_SIZE const isBig = fileSize === -1 || fileSize > BIG_FILE_MIN_SIZE
const isSmall = fileSize !== -1 && fileSize < SMALL_FILE_MAX_SIZE const isSmall = fileSize !== -1 && fileSize < SMALL_FILE_MAX_SIZE
const connectionKind = isSmall ? 'main' : 'upload' const connectionKind = isSmall ? 'main' : 'upload'
const connectionPoolSize = Math.min( const connectionPoolSize = Math.min(this.network.getPoolSize(connectionKind), partCount)
this.network.getPoolSize(connectionKind), const requestsPerConnection = params.requestsPerConnection ?? REQUESTS_PER_CONNECTION
partCount,
)
const requestsPerConnection =
params.requestsPerConnection ?? REQUESTS_PER_CONNECTION
this.log.debug( this.log.debug(
'uploading %d bytes file in %d chunks, each %d bytes in %s connection pool of size %d', 'uploading %d bytes file in %d chunks, each %d bytes in %s connection pool of size %d',
@ -278,26 +250,18 @@ export async function uploadFile(
if (fileSize === -1 && stream.readableEnded) { if (fileSize === -1 && stream.readableEnded) {
fileSize = pos + (part?.length ?? 0) fileSize = pos + (part?.length ?? 0)
partCount = ~~((fileSize + partSize - 1) / partSize) partCount = ~~((fileSize + partSize - 1) / partSize)
this.log.debug( this.log.debug('readable ended, file size = %d, part count = %d', fileSize, partCount)
'readable ended, file size = %d, part count = %d',
fileSize,
partCount,
)
} }
if (!part) { if (!part) {
throw new MtArgumentError( throw new MtArgumentError(`Unexpected EOS (there were only ${idx} parts, but expected ${partCount})`)
`Unexpected EOS (there were only ${idx} parts, but expected ${partCount})`,
)
} }
if (!Buffer.isBuffer(part)) { if (!Buffer.isBuffer(part)) {
throw new MtArgumentError(`Part ${thisIdx} was not a Buffer!`) throw new MtArgumentError(`Part ${thisIdx} was not a Buffer!`)
} }
if (part.length > partSize) { if (part.length > partSize) {
throw new MtArgumentError( throw new MtArgumentError(`Part ${thisIdx} had invalid size (expected ${partSize}, got ${part.length})`)
`Part ${thisIdx} had invalid size (expected ${partSize}, got ${part.length})`,
)
} }
if (thisIdx === 0 && fileMime === undefined) { if (thisIdx === 0 && fileMime === undefined) {
@ -310,9 +274,7 @@ export async function uploadFile(
// if all 8 bytes are printable ASCII characters, // if all 8 bytes are printable ASCII characters,
// the entire file is probably plain text // the entire file is probably plain text
const isPlainText = isProbablyPlainText(part.slice(0, 8)) const isPlainText = isProbablyPlainText(part.slice(0, 8))
fileMime = isPlainText ? fileMime = isPlainText ? 'text/plain' : 'application/octet-stream'
'text/plain' :
'application/octet-stream'
} }
} }

View file

@ -1,18 +1,8 @@
import { import { assertNever, MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
assertNever,
MtArgumentError,
MtTypeAssertionError,
} from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils' import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { InputMediaLike, InputPeerLike, MessageMedia, Photo, RawDocument } from '../../types'
InputMediaLike,
InputPeerLike,
MessageMedia,
Photo,
RawDocument,
} from '../../types'
import { parseDocument } from '../../types/media/document-utils' import { parseDocument } from '../../types/media/document-utils'
/** /**
@ -72,11 +62,7 @@ export async function uploadMedia(
}) })
if (res._ === 'messageMediaEmpty') { if (res._ === 'messageMediaEmpty') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('uploadMedia', 'not messageMediaEmpty', 'messageMediaEmpty')
'uploadMedia',
'not messageMediaEmpty',
'messageMediaEmpty',
)
} }
switch (normMedia._) { switch (normMedia._) {

View file

@ -11,10 +11,7 @@ import { ChatInviteLink, InputPeerLike } from '../../types'
* @param chatId Chat IDs * @param chatId Chat IDs
* @internal * @internal
*/ */
export async function exportInviteLink( export async function exportInviteLink(this: TelegramClient, chatId: InputPeerLike): Promise<ChatInviteLink> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<ChatInviteLink> {
const res = await this.call({ const res = await this.call({
_: 'messages.exportChatInvite', _: 'messages.exportChatInvite',
peer: await this.resolvePeer(chatId), peer: await this.resolvePeer(chatId),

View file

@ -50,17 +50,16 @@ export async function* getInviteLinkMembers(
for (;;) { for (;;) {
// for some reason ts needs annotation, idk // for some reason ts needs annotation, idk
const res: tl.RpcCallReturn['messages.getChatInviteImporters'] = const res: tl.RpcCallReturn['messages.getChatInviteImporters'] = await this.call({
await this.call({ _: 'messages.getChatInviteImporters',
_: 'messages.getChatInviteImporters', limit: Math.min(100, limit - current),
limit: Math.min(100, limit - current), peer,
peer, link: params.link,
link: params.link, requested: params.requested,
requested: params.requested, q: params.requestedSearch,
q: params.requestedSearch, offsetDate,
offsetDate, offsetUser,
offsetUser, })
})
if (!res.importers.length) break if (!res.importers.length) break

View file

@ -54,15 +54,14 @@ export async function* getInviteLinks(
let offsetLink: string | undefined = undefined let offsetLink: string | undefined = undefined
for (;;) { for (;;) {
const res: tl.RpcCallReturn['messages.getExportedChatInvites'] = const res: tl.RpcCallReturn['messages.getExportedChatInvites'] = await this.call({
await this.call({ _: 'messages.getExportedChatInvites',
_: 'messages.getExportedChatInvites', peer,
peer, adminId: admin,
adminId: admin, limit: Math.min(chunkSize, total - current),
limit: Math.min(chunkSize, total - current), offsetDate,
offsetDate, offsetLink,
offsetLink, })
})
if (!res.invites.length) break if (!res.invites.length) break
@ -71,11 +70,7 @@ export async function* getInviteLinks(
const last = res.invites[res.invites.length - 1] const last = res.invites[res.invites.length - 1]
if (last._ === 'chatInvitePublicJoinRequests') { if (last._ === 'chatInvitePublicJoinRequests') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('getInviteLinks', 'chatInviteExported', last._)
'getInviteLinks',
'chatInviteExported',
last._,
)
} }
offsetDate = last.date offsetDate = last.date
offsetLink = last.link offsetLink = last.link

View file

@ -9,10 +9,7 @@ import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
* @param chatId Chat ID * @param chatId Chat ID
* @internal * @internal
*/ */
export async function getPrimaryInviteLink( export async function getPrimaryInviteLink(this: TelegramClient, chatId: InputPeerLike): Promise<ChatInviteLink> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<ChatInviteLink> {
const res = await this.call({ const res = await this.call({
_: 'messages.getExportedChatInvites', _: 'messages.getExportedChatInvites',
peer: await this.resolvePeer(chatId), peer: await this.resolvePeer(chatId),
@ -30,11 +27,7 @@ export async function getPrimaryInviteLink(
} }
if (!res.invites[0].permanent) { if (!res.invites[0].permanent) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.getExportedChatInvites (@ .invites[0].permanent)', 'true', 'false')
'messages.getExportedChatInvites (@ .invites[0].permanent)',
'true',
'false',
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -26,10 +26,7 @@ export async function revokeInviteLink(
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const invite = const invite = res._ === 'messages.exportedChatInviteReplaced' ? res.newInvite : res.invite
res._ === 'messages.exportedChatInviteReplaced' ?
res.newInvite :
res.invite
return new ChatInviteLink(this, invite, peers) return new ChatInviteLink(this, invite, peers)
} }

View file

@ -17,11 +17,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @param message Message ID where this poll was found * @param message Message ID where this poll was found
* @internal * @internal
*/ */
export async function closePoll( export async function closePoll(this: TelegramClient, chatId: InputPeerLike, message: number): Promise<Poll> {
this: TelegramClient,
chatId: InputPeerLike,
message: number,
): Promise<Poll> {
const res = await this.call({ const res = await this.call({
_: 'messages.editMessage', _: 'messages.editMessage',
peer: await this.resolvePeer(chatId), peer: await this.resolvePeer(chatId),
@ -43,18 +39,10 @@ export async function closePoll(
this._handleUpdate(res, true) this._handleUpdate(res, true)
const upd = res.updates[0] const upd = res.updates[0]
assertTypeIs( assertTypeIs('messages.editMessage (@ .updates[0])', upd, 'updateMessagePoll')
'messages.editMessage (@ .updates[0])',
upd,
'updateMessagePoll',
)
if (!upd.poll) { if (!upd.poll) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.editMessage (@ .updates[0].poll)', 'poll', 'undefined')
'messages.editMessage (@ .updates[0].poll)',
'poll',
'undefined',
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -2,10 +2,7 @@ import { MaybeArray } from '@mtcute/core'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike } from '../../types' import { InputPeerLike } from '../../types'
import { import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
normalizeToInputChannel,
} from '../../utils/peer-utils'
import { createDummyUpdate } from '../../utils/updates-utils' import { createDummyUpdate } from '../../utils/updates-utils'
/** /**

View file

@ -1,12 +1,7 @@
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { BotKeyboard, FormattedString, InputMediaLike, ReplyMarkup } from '../../types'
BotKeyboard,
FormattedString,
InputMediaLike,
ReplyMarkup,
} from '../../types'
import { normalizeInlineId } from '../../utils/inline-utils' import { normalizeInlineId } from '../../utils/inline-utils'
/** /**
@ -91,11 +86,7 @@ export async function editInlineMessage(
) )
} }
} else if (params.text) { } else if (params.text) {
[content, entities] = await this._parseEntities( [content, entities] = await this._parseEntities(params.text, params.parseMode, params.entities)
params.text,
params.parseMode,
params.entities,
)
} }
let retries = 3 let retries = 3

View file

@ -1,14 +1,7 @@
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { BotKeyboard, FormattedString, InputMediaLike, InputPeerLike, Message, ReplyMarkup } from '../../types'
BotKeyboard,
FormattedString,
InputMediaLike,
InputPeerLike,
Message,
ReplyMarkup,
} from '../../types'
/** /**
* Edit message text, media, reply markup and schedule date. * Edit message text, media, reply markup and schedule date.
@ -96,11 +89,7 @@ export async function editMessage(
) )
} }
} else if (params.text) { } else if (params.text) {
[content, entities] = await this._parseEntities( [content, entities] = await this._parseEntities(params.text, params.parseMode, params.entities)
params.text,
params.parseMode,
params.entities,
)
} }
const res = await this.call({ const res = await this.call({

View file

@ -6,20 +6,14 @@ import { Message, PeersIndex } from '../../types'
import { assertIsUpdatesGroup } from '../../utils/updates-utils' import { assertIsUpdatesGroup } from '../../utils/updates-utils'
/** @internal */ /** @internal */
export function _findMessageInUpdate( export function _findMessageInUpdate(this: TelegramClient, res: tl.TypeUpdates, isEdit = false): Message {
this: TelegramClient,
res: tl.TypeUpdates,
isEdit = false,
): Message {
assertIsUpdatesGroup('_findMessageInUpdate', res) assertIsUpdatesGroup('_findMessageInUpdate', res)
this._handleUpdate(res, true) this._handleUpdate(res, true)
for (const u of res.updates) { for (const u of res.updates) {
if ( if (
(isEdit && (isEdit && (u._ === 'updateEditMessage' || u._ === 'updateEditChannelMessage')) ||
(u._ === 'updateEditMessage' ||
u._ === 'updateEditChannelMessage')) ||
(!isEdit && (!isEdit &&
(u._ === 'updateNewMessage' || (u._ === 'updateNewMessage' ||
u._ === 'updateNewChannelMessage' || u._ === 'updateNewChannelMessage' ||
@ -27,12 +21,7 @@ export function _findMessageInUpdate(
) { ) {
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
return new Message( return new Message(this, u.message, peers, u._ === 'updateNewScheduledMessage')
this,
u.message,
peers,
u._ === 'updateNewScheduledMessage',
)
} }
} }

View file

@ -3,13 +3,7 @@ import { randomLong } from '@mtcute/core/utils'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { FormattedString, InputMediaLike, InputPeerLike, Message, PeersIndex } from '../../types'
FormattedString,
InputMediaLike,
InputPeerLike,
Message,
PeersIndex,
} from '../../types'
import { normalizeDate } from '../../utils/misc-utils' import { normalizeDate } from '../../utils/misc-utils'
import { assertIsUpdatesGroup } from '../../utils/updates-utils' import { assertIsUpdatesGroup } from '../../utils/updates-utils'
@ -104,7 +98,7 @@ export async function forwardMessages(
* have content protection. * have content protection.
*/ */
forbidForwards?: boolean forbidForwards?: boolean
} },
): Promise<Message> ): Promise<Message>
/** /**
@ -201,7 +195,7 @@ export async function forwardMessages(
* have content protection. * have content protection.
*/ */
forbidForwards?: boolean forbidForwards?: boolean
} },
): Promise<MaybeArray<Message>> ): Promise<MaybeArray<Message>>
/** @internal */ /** @internal */
@ -303,9 +297,7 @@ export async function forwardMessages(
// error, instead only first 100 IDs will be forwarded, // error, instead only first 100 IDs will be forwarded,
// which is definitely not the best outcome. // which is definitely not the best outcome.
if (messages.length > 100) { if (messages.length > 100) {
throw new MtArgumentError( throw new MtArgumentError('You can forward no more than 100 messages at once')
'You can forward no more than 100 messages at once',
)
} }
const toPeer = await this.resolvePeer(toChatId) const toPeer = await this.resolvePeer(toChatId)
@ -314,9 +306,7 @@ export async function forwardMessages(
if (params.caption) { if (params.caption) {
if (params.captionMedia) { if (params.captionMedia) {
throw new MtArgumentError( throw new MtArgumentError('You can either pass `caption` or `captionMedia`')
'You can either pass `caption` or `captionMedia`',
)
} }
captionMessage = await this.sendText(toPeer, params.caption, { captionMessage = await this.sendText(toPeer, params.caption, {
@ -350,9 +340,7 @@ export async function forwardMessages(
dropAuthor: params.noAuthor, dropAuthor: params.noAuthor,
dropMediaCaptions: params.noCaption, dropMediaCaptions: params.noCaption,
noforwards: params.forbidForwards, noforwards: params.forbidForwards,
sendAs: params.sendAs ? sendAs: params.sendAs ? await this.resolvePeer(params.sendAs) : undefined,
await this.resolvePeer(params.sendAs) :
undefined,
}) })
assertIsUpdatesGroup('messages.forwardMessages', res) assertIsUpdatesGroup('messages.forwardMessages', res)
@ -367,14 +355,7 @@ export async function forwardMessages(
case 'updateNewMessage': case 'updateNewMessage':
case 'updateNewChannelMessage': case 'updateNewChannelMessage':
case 'updateNewScheduledMessage': case 'updateNewScheduledMessage':
forwarded.push( forwarded.push(new Message(this, upd.message, peers, upd._ === 'updateNewScheduledMessage'))
new Message(
this,
upd.message,
peers,
upd._ === 'updateNewScheduledMessage',
),
)
break break
} }
}) })

View file

@ -23,9 +23,7 @@ export async function _getDiscussionMessage(
} }
const msg = res.messages[0] const msg = res.messages[0]
const chat = res.chats.find( const chat = res.chats.find((it) => it.id === (msg.peerId as tl.RawPeerChannel).channelId)! as tl.RawChannel
(it) => it.id === (msg.peerId as tl.RawPeerChannel).channelId,
)! as tl.RawChannel
return [ return [
{ {

View file

@ -84,13 +84,10 @@ export async function* getHistory(
const minId = params.minId || 0 const minId = params.minId || 0
const maxId = params.maxId || 0 const maxId = params.maxId || 0
let offsetId = let offsetId = params.offsetId ?? (params.reverse && !params.offsetDate ? 1 : 0)
params.offsetId ?? (params.reverse && !params.offsetDate ? 1 : 0)
const offsetDate = normalizeDate(params.offsetDate) || 0 const offsetDate = normalizeDate(params.offsetDate) || 0
const baseOffset = -(params.reverse ? limit : 0) const baseOffset = -(params.reverse ? limit : 0)
let addOffset = let addOffset = (params.offset ? params.offset * (params.reverse ? -1 : 1) : 0) + baseOffset
(params.offset ? params.offset * (params.reverse ? -1 : 1) : 0) +
baseOffset
// resolve peer once and pass an InputPeer afterwards // resolve peer once and pass an InputPeer afterwards
const peer = await this.resolvePeer(chatId) const peer = await this.resolvePeer(chatId)
@ -109,18 +106,12 @@ export async function* getHistory(
}) })
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.getHistory', '!messages.messagesNotModified', res._)
'messages.getHistory',
'!messages.messagesNotModified',
res._,
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const msgs = res.messages const msgs = res.messages.filter((msg) => msg._ !== 'messageEmpty').map((msg) => new Message(this, msg, peers))
.filter((msg) => msg._ !== 'messageEmpty')
.map((msg) => new Message(this, msg, peers))
if (!msgs.length) break if (!msgs.length) break

View file

@ -37,7 +37,5 @@ export async function getMessageGroup(
if (!groupedId) throw new MtArgumentError('This message is not grouped') if (!groupedId) throw new MtArgumentError('This message is not grouped')
return messages.filter( return messages.filter((it) => it && it.groupedId?.eq(groupedId)) as Message[]
(it) => it && it.groupedId?.eq(groupedId),
) as Message[]
} }

View file

@ -20,7 +20,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
export async function getMessageReactions( export async function getMessageReactions(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messages: number messages: number,
): Promise<MessageReactions | null> ): Promise<MessageReactions | null>
/** /**
@ -38,7 +38,7 @@ export async function getMessageReactions(
export async function getMessageReactions( export async function getMessageReactions(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messages: number[] messages: number[],
): Promise<(MessageReactions | null)[]> ): Promise<(MessageReactions | null)[]>
/** /**
@ -74,11 +74,7 @@ export async function getMessageReactions(
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
for (const update of res.updates) { for (const update of res.updates) {
assertTypeIs( assertTypeIs('messages.getMessagesReactions', update, 'updateMessageReactions')
'messages.getMessagesReactions',
update,
'updateMessageReactions',
)
index[update.msgId] = new MessageReactions( index[update.msgId] = new MessageReactions(
this, this,

View file

@ -20,7 +20,7 @@ import { Message, PeersIndex } from '../../types'
export async function getMessagesUnsafe( export async function getMessagesUnsafe(
this: TelegramClient, this: TelegramClient,
messageId: number, messageId: number,
fromReply?: boolean fromReply?: boolean,
): Promise<Message | null> ): Promise<Message | null>
/** /**
* Get messages from PM or legacy group by their IDs. * Get messages from PM or legacy group by their IDs.
@ -41,7 +41,7 @@ export async function getMessagesUnsafe(
export async function getMessagesUnsafe( export async function getMessagesUnsafe(
this: TelegramClient, this: TelegramClient,
messageIds: number[], messageIds: number[],
fromReply?: boolean fromReply?: boolean,
): Promise<(Message | null)[]> ): Promise<(Message | null)[]>
/** @internal */ /** @internal */
@ -65,11 +65,7 @@ export async function getMessagesUnsafe(
}) })
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('getMessages', '!messages.messagesNotModified', res._)
'getMessages',
'!messages.messagesNotModified',
res._,
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -3,10 +3,7 @@ import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike, Message, PeersIndex } from '../../types' import { InputPeerLike, Message, PeersIndex } from '../../types'
import { import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
normalizeToInputChannel,
} from '../../utils/peer-utils'
/** /**
* Get a single message in chat by its ID * Get a single message in chat by its ID
@ -22,7 +19,7 @@ export async function getMessages(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messageId: number, messageId: number,
fromReply?: boolean fromReply?: boolean,
): Promise<Message | null> ): Promise<Message | null>
/** /**
* Get messages in chat by their IDs * Get messages in chat by their IDs
@ -41,7 +38,7 @@ export async function getMessages(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messageIds: number[], messageIds: number[],
fromReply?: boolean fromReply?: boolean,
): Promise<(Message | null)[]> ): Promise<(Message | null)[]>
/** @internal */ /** @internal */
@ -78,11 +75,7 @@ export async function getMessages(
) )
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('getMessages', '!messages.messagesNotModified', res._)
'getMessages',
'!messages.messagesNotModified',
res._,
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
@ -95,33 +88,18 @@ export async function getMessages(
// (channels have their own message numbering) // (channels have their own message numbering)
switch (peer._) { switch (peer._) {
case 'inputPeerSelf': case 'inputPeerSelf':
if ( if (!(msg.peerId._ === 'peerUser' && msg.peerId.userId === this._userId)) {
!(
msg.peerId._ === 'peerUser' &&
msg.peerId.userId === this._userId
)
) {
return null return null
} }
break break
case 'inputPeerUser': case 'inputPeerUser':
case 'inputPeerUserFromMessage': case 'inputPeerUserFromMessage':
if ( if (!(msg.peerId._ === 'peerUser' && msg.peerId.userId === peer.userId)) {
!(
msg.peerId._ === 'peerUser' &&
msg.peerId.userId === peer.userId
)
) {
return null return null
} }
break break
case 'inputPeerChat': case 'inputPeerChat':
if ( if (!(msg.peerId._ === 'peerChat' && msg.peerId.chatId === peer.chatId)) {
!(
msg.peerId._ === 'peerChat' &&
msg.peerId.chatId === peer.chatId
)
) {
return null return null
} }
break break

View file

@ -69,15 +69,14 @@ export async function* getReactionUsers(
} }
for (;;) { for (;;) {
const res: tl.RpcCallReturn['messages.getMessageReactionsList'] = const res: tl.RpcCallReturn['messages.getMessageReactionsList'] = await this.call({
await this.call({ _: 'messages.getMessageReactionsList',
_: 'messages.getMessageReactionsList', peer,
peer, id: messageId,
id: messageId, reaction,
reaction, limit: Math.min(chunkSize, total - current),
limit: Math.min(chunkSize, total - current), offset,
offset, })
})
if (!res.reactions.length) break if (!res.reactions.length) break

View file

@ -13,7 +13,7 @@ import { InputPeerLike, Message, PeersIndex } from '../../types'
export async function getScheduledMessages( export async function getScheduledMessages(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messageId: number messageId: number,
): Promise<Message | null> ): Promise<Message | null>
/** /**
* Get scheduled messages in chat by their IDs * Get scheduled messages in chat by their IDs
@ -28,7 +28,7 @@ export async function getScheduledMessages(
export async function getScheduledMessages( export async function getScheduledMessages(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
messageIds: number[] messageIds: number[],
): Promise<(Message | null)[]> ): Promise<(Message | null)[]>
/** @internal */ /** @internal */
@ -49,11 +49,7 @@ export async function getScheduledMessages(
}) })
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('getMessages', '!messages.messagesNotModified', res._)
'getMessages',
'!messages.messagesNotModified',
res._,
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -44,14 +44,10 @@ export async function _parseEntities(
for (const ent of entities) { for (const ent of entities) {
if (ent._ === 'messageEntityMentionName') { if (ent._ === 'messageEntityMentionName') {
try { try {
const inputPeer = normalizeToInputUser( const inputPeer = normalizeToInputUser(await this.resolvePeer(ent.userId), ent.userId)
await this.resolvePeer(ent.userId),
ent.userId,
)
// not a user // not a user
if (!inputPeer) continue if (!inputPeer) continue
(ent as any)._ = 'inputMessageEntityMentionName' (ent as any)._ = 'inputMessageEntityMentionName'
;(ent as any).userId = inputPeer ;(ent as any).userId = inputPeer
} catch (e) {} } catch (e) {}

View file

@ -1,9 +1,6 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { InputPeerLike } from '../../types' import { InputPeerLike } from '../../types'
import { import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
isInputPeerChannel,
normalizeToInputChannel,
} from '../../utils/peer-utils'
import { createDummyUpdate } from '../../utils/updates-utils' import { createDummyUpdate } from '../../utils/updates-utils'
/** /**
@ -29,9 +26,7 @@ export async function readHistory(
}) })
if (isInputPeerChannel(peer)) { if (isInputPeerChannel(peer)) {
this._handleUpdate( this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
createDummyUpdate(res.pts, res.ptsCount, peer.channelId),
)
} else { } else {
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount)) this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
} }

View file

@ -8,10 +8,7 @@ import { createDummyUpdate } from '../../utils/updates-utils'
* @param chatId Chat ID * @param chatId Chat ID
* @internal * @internal
*/ */
export async function readReactions( export async function readReactions(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
const res = await this.call({ const res = await this.call({
_: 'messages.readReactions', _: 'messages.readReactions',
peer: await this.resolvePeer(chatId), peer: await this.resolvePeer(chatId),

View file

@ -71,24 +71,17 @@ export async function* searchGlobal(
}) })
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.searchGlobal', '!messages.messagesNotModified', res._)
'messages.searchGlobal',
'!messages.messagesNotModified',
res._,
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const msgs = res.messages const msgs = res.messages.filter((msg) => msg._ !== 'messageEmpty').map((msg) => new Message(this, msg, peers))
.filter((msg) => msg._ !== 'messageEmpty')
.map((msg) => new Message(this, msg, peers))
if (!msgs.length) break if (!msgs.length) break
const last = msgs[msgs.length - 1] const last = msgs[msgs.length - 1]
offsetRate = offsetRate = (res as tl.messages.RawMessagesSlice).nextRate ?? last.raw.date
(res as tl.messages.RawMessagesSlice).nextRate ?? last.raw.date
offsetPeer = last.chat.inputPeer offsetPeer = last.chat.inputPeer
offsetId = last.id offsetId = last.id

View file

@ -123,9 +123,7 @@ export async function* searchMessages(
const limit = Math.min(params.chunkSize || 100, total) const limit = Math.min(params.chunkSize || 100, total)
const peer = await this.resolvePeer(chatId) const peer = await this.resolvePeer(chatId)
const fromUser = const fromUser = (params.fromUser ? await this.resolvePeer(params.fromUser) : null) || undefined
(params.fromUser ? await this.resolvePeer(params.fromUser) : null) ||
undefined
for (;;) { for (;;) {
const res = await this.call({ const res = await this.call({
@ -145,11 +143,7 @@ export async function* searchMessages(
}) })
if (res._ === 'messages.messagesNotModified') { if (res._ === 'messages.messagesNotModified') {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.search', '!messages.messagesNotModified', res._)
'messages.search',
'!messages.messagesNotModified',
res._,
)
} }
// for successive chunks, we need to reset the offset // for successive chunks, we need to reset the offset
@ -157,9 +151,7 @@ export async function* searchMessages(
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)
const msgs = res.messages const msgs = res.messages.filter((msg) => msg._ !== 'messageEmpty').map((msg) => new Message(this, msg, peers))
.filter((msg) => msg._ !== 'messageEmpty')
.map((msg) => new Message(this, msg, peers))
if (!msgs.length) break if (!msgs.length) break

View file

@ -2,13 +2,7 @@ import { getMarkedPeerId } from '@mtcute/core'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { FormattedString, InputPeerLike, Message, MtMessageNotFoundError, ReplyMarkup } from '../../types'
FormattedString,
InputPeerLike,
Message,
MtMessageNotFoundError,
ReplyMarkup,
} from '../../types'
/** /**
* Copy a message (i.e. send the same message, * Copy a message (i.e. send the same message,
@ -107,11 +101,7 @@ export async function sendCopy(
const msg = await this.getMessages(fromPeer, message) const msg = await this.getMessages(fromPeer, message)
if (!msg) { if (!msg) {
throw new MtMessageNotFoundError( throw new MtMessageNotFoundError(getMarkedPeerId(fromPeer), message, 'to copy')
getMarkedPeerId(fromPeer),
message,
'to copy',
)
} }
return msg.sendCopy(toChatId, params) return msg.sendCopy(toChatId, params)

View file

@ -3,13 +3,7 @@ import { randomLong } from '@mtcute/core/utils'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { InputMediaLike, InputPeerLike, Message, MtMessageNotFoundError, PeersIndex } from '../../types'
InputMediaLike,
InputPeerLike,
Message,
MtMessageNotFoundError,
PeersIndex,
} from '../../types'
import { normalizeDate, normalizeMessageId } from '../../utils/misc-utils' import { normalizeDate, normalizeMessageId } from '../../utils/misc-utils'
import { assertIsUpdatesGroup } from '../../utils/updates-utils' import { assertIsUpdatesGroup } from '../../utils/updates-utils'
@ -86,11 +80,7 @@ export async function sendMediaGroup(
* @param uploaded Number of bytes already uploaded * @param uploaded Number of bytes already uploaded
* @param total Total file size * @param total Total file size
*/ */
progressCallback?: ( progressCallback?: (index: number, uploaded: number, total: number) => void
index: number,
uploaded: number,
total: number
) => void
/** /**
* Whether to clear draft after sending this message. * Whether to clear draft after sending this message.
@ -120,27 +110,18 @@ export async function sendMediaGroup(
let replyTo = normalizeMessageId(params.replyTo) let replyTo = normalizeMessageId(params.replyTo)
if (params.commentTo) { if (params.commentTo) {
[peer, replyTo] = await this._getDiscussionMessage( [peer, replyTo] = await this._getDiscussionMessage(peer, normalizeMessageId(params.commentTo)!)
peer,
normalizeMessageId(params.commentTo)!,
)
} }
if (params.mustReply) { if (params.mustReply) {
if (!replyTo) { if (!replyTo) {
throw new MtArgumentError( throw new MtArgumentError('mustReply used, but replyTo was not passed')
'mustReply used, but replyTo was not passed',
)
} }
const msg = await this.getMessages(peer, replyTo) const msg = await this.getMessages(peer, replyTo)
if (!msg) { if (!msg) {
throw new MtMessageNotFoundError( throw new MtMessageNotFoundError(getMarkedPeerId(peer), replyTo, 'to reply to')
getMarkedPeerId(peer),
replyTo,
'to reply to',
)
} }
} }
@ -200,9 +181,7 @@ export async function sendMediaGroup(
scheduleDate: normalizeDate(params.schedule), scheduleDate: normalizeDate(params.schedule),
clearDraft: params.clearDraft, clearDraft: params.clearDraft,
noforwards: params.forbidForwards, noforwards: params.forbidForwards,
sendAs: params.sendAs ? sendAs: params.sendAs ? await this.resolvePeer(params.sendAs) : undefined,
await this.resolvePeer(params.sendAs) :
undefined,
}) })
assertIsUpdatesGroup('_findMessageInUpdate', res) assertIsUpdatesGroup('_findMessageInUpdate', res)
@ -212,25 +191,10 @@ export async function sendMediaGroup(
const msgs = res.updates const msgs = res.updates
.filter( .filter(
( (u): u is tl.RawUpdateNewMessage | tl.RawUpdateNewChannelMessage | tl.RawUpdateNewScheduledMessage =>
u, u._ === 'updateNewMessage' || u._ === 'updateNewChannelMessage' || u._ === 'updateNewScheduledMessage',
): u is
| tl.RawUpdateNewMessage
| tl.RawUpdateNewChannelMessage
| tl.RawUpdateNewScheduledMessage =>
u._ === 'updateNewMessage' ||
u._ === 'updateNewChannelMessage' ||
u._ === 'updateNewScheduledMessage',
)
.map(
(u) =>
new Message(
this,
u.message,
peers,
u._ === 'updateNewScheduledMessage',
),
) )
.map((u) => new Message(this, u.message, peers, u._ === 'updateNewScheduledMessage'))
this._pushConversationMessage(msgs[msgs.length - 1]) this._pushConversationMessage(msgs[msgs.length - 1])

View file

@ -146,11 +146,9 @@ export async function sendMedia(
// some types dont have `caption` field, and ts warns us, // some types dont have `caption` field, and ts warns us,
// but since it's JS, they'll just be `undefined` and properly // but since it's JS, they'll just be `undefined` and properly
// handled by _parseEntities method // handled by _parseEntities method
params.caption || params.caption || (media as Extract<typeof media, { caption?: unknown }>).caption,
(media as Extract<typeof media, { caption?: unknown }>).caption,
params.parseMode, params.parseMode,
params.entities || params.entities || (media as Extract<typeof media, { entities?: unknown }>).entities,
(media as Extract<typeof media, { entities?: unknown }>).entities,
) )
let peer = await this.resolvePeer(chatId) let peer = await this.resolvePeer(chatId)
@ -159,27 +157,18 @@ export async function sendMedia(
let replyTo = normalizeMessageId(params.replyTo) let replyTo = normalizeMessageId(params.replyTo)
if (params.commentTo) { if (params.commentTo) {
[peer, replyTo] = await this._getDiscussionMessage( [peer, replyTo] = await this._getDiscussionMessage(peer, normalizeMessageId(params.commentTo)!)
peer,
normalizeMessageId(params.commentTo)!,
)
} }
if (params.mustReply) { if (params.mustReply) {
if (!replyTo) { if (!replyTo) {
throw new MtArgumentError( throw new MtArgumentError('mustReply used, but replyTo was not passed')
'mustReply used, but replyTo was not passed',
)
} }
const msg = await this.getMessages(peer, replyTo) const msg = await this.getMessages(peer, replyTo)
if (!msg) { if (!msg) {
throw new MtMessageNotFoundError( throw new MtMessageNotFoundError(getMarkedPeerId(peer), replyTo, 'to reply to')
getMarkedPeerId(peer),
replyTo,
'to reply to',
)
} }
} }
@ -201,9 +190,7 @@ export async function sendMedia(
entities, entities,
clearDraft: params.clearDraft, clearDraft: params.clearDraft,
noforwards: params.forbidForwards, noforwards: params.forbidForwards,
sendAs: params.sendAs ? sendAs: params.sendAs ? await this.resolvePeer(params.sendAs) : undefined,
await this.resolvePeer(params.sendAs) :
undefined,
}) })
const msg = this._findMessageInUpdate(res) const msg = this._findMessageInUpdate(res)

View file

@ -60,16 +60,12 @@ export async function sendReaction(
this._handleUpdate(res, true) this._handleUpdate(res, true)
const upd = res.updates.find( const upd = res.updates.find((it) => it._ === 'updateEditChannelMessage') as
(it) => it._ === 'updateEditChannelMessage', | tl.RawUpdateEditChannelMessage
) as tl.RawUpdateEditChannelMessage | undefined | undefined
if (!upd) { if (!upd) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.sendReaction (@ .updates[*])', 'updateEditChannelMessage', 'undefined')
'messages.sendReaction (@ .updates[*])',
'updateEditChannelMessage',
'undefined',
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -15,11 +15,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils'
* @param id ID of the message * @param id ID of the message
* @internal * @internal
*/ */
export async function sendScheduled( export async function sendScheduled(this: TelegramClient, peer: InputPeerLike, id: number): Promise<Message>
this: TelegramClient,
peer: InputPeerLike,
id: number
): Promise<Message>
/** /**
* Send previously scheduled message(s) * Send previously scheduled message(s)
@ -32,11 +28,7 @@ export async function sendScheduled(
* @param ids ID(s) of the messages * @param ids ID(s) of the messages
* @internal * @internal
*/ */
export async function sendScheduled( export async function sendScheduled(this: TelegramClient, peer: InputPeerLike, ids: number[]): Promise<Message[]>
this: TelegramClient,
peer: InputPeerLike,
ids: number[]
): Promise<Message[]>
/** @internal */ /** @internal */
export async function sendScheduled( export async function sendScheduled(

View file

@ -1,8 +1,4 @@
import { import { getMarkedPeerId, MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
getMarkedPeerId,
MtArgumentError,
MtTypeAssertionError,
} from '@mtcute/core'
import { randomLong } from '@mtcute/core/utils' import { randomLong } from '@mtcute/core/utils'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
@ -122,11 +118,7 @@ export async function sendText(
): Promise<Message> { ): Promise<Message> {
if (!params) params = {} if (!params) params = {}
const [message, entities] = await this._parseEntities( const [message, entities] = await this._parseEntities(text, params.parseMode, params.entities)
text,
params.parseMode,
params.entities,
)
let peer = await this.resolvePeer(chatId) let peer = await this.resolvePeer(chatId)
const replyMarkup = BotKeyboard._convertToTl(params.replyMarkup) const replyMarkup = BotKeyboard._convertToTl(params.replyMarkup)
@ -134,27 +126,18 @@ export async function sendText(
let replyTo = normalizeMessageId(params.replyTo) let replyTo = normalizeMessageId(params.replyTo)
if (params.commentTo) { if (params.commentTo) {
[peer, replyTo] = await this._getDiscussionMessage( [peer, replyTo] = await this._getDiscussionMessage(peer, normalizeMessageId(params.commentTo)!)
peer,
normalizeMessageId(params.commentTo)!,
)
} }
if (params.mustReply) { if (params.mustReply) {
if (!replyTo) { if (!replyTo) {
throw new MtArgumentError( throw new MtArgumentError('mustReply used, but replyTo was not passed')
'mustReply used, but replyTo was not passed',
)
} }
const msg = await this.getMessages(peer, replyTo) const msg = await this.getMessages(peer, replyTo)
if (!msg) { if (!msg) {
throw new MtMessageNotFoundError( throw new MtMessageNotFoundError(getMarkedPeerId(peer), replyTo, 'to reply to')
getMarkedPeerId(peer),
replyTo,
'to reply to',
)
} }
} }
@ -176,9 +159,7 @@ export async function sendText(
entities, entities,
clearDraft: params.clearDraft, clearDraft: params.clearDraft,
noforwards: params.forbidForwards, noforwards: params.forbidForwards,
sendAs: params.sendAs ? sendAs: params.sendAs ? await this.resolvePeer(params.sendAs) : undefined,
await this.resolvePeer(params.sendAs) :
undefined,
}) })
if (res._ === 'updateShortSentMessage') { if (res._ === 'updateShortSentMessage') {
@ -199,9 +180,7 @@ export async function sendText(
const peers = new PeersIndex() const peers = new PeersIndex()
const fetchPeer = async ( const fetchPeer = async (peer: tl.TypePeer | tl.TypeInputPeer): Promise<void> => {
peer: tl.TypePeer | tl.TypeInputPeer,
): Promise<void> => {
const id = getMarkedPeerId(peer) const id = getMarkedPeerId(peer)
let cached = await this.storage.getFullPeerById(id) let cached = await this.storage.getFullPeerById(id)
@ -224,11 +203,7 @@ export async function sendText(
} }
if (!cached) { if (!cached) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('sendText (@ getFullPeerById)', 'user | chat', 'null')
'sendText (@ getFullPeerById)',
'user | chat',
'null',
)
} }
switch (cached._) { switch (cached._) {

View file

@ -1,18 +1,8 @@
import { import { getMarkedPeerId, MaybeArray, MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
getMarkedPeerId,
MaybeArray,
MtArgumentError,
MtTypeAssertionError,
} from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils' import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { import { InputPeerLike, MtMessageNotFoundError, PeersIndex, Poll } from '../../types'
InputPeerLike,
MtMessageNotFoundError,
PeersIndex,
Poll,
} from '../../types'
import { assertIsUpdatesGroup } from '../../utils/updates-utils' import { assertIsUpdatesGroup } from '../../utils/updates-utils'
/** /**
@ -44,11 +34,7 @@ export async function sendVote(
const msg = await this.getMessages(peer, message) const msg = await this.getMessages(peer, message)
if (!msg) { if (!msg) {
throw new MtMessageNotFoundError( throw new MtMessageNotFoundError(getMarkedPeerId(peer), message, 'to vote in')
getMarkedPeerId(peer),
message,
'to vote in',
)
} }
if (!(msg.media instanceof Poll)) { if (!(msg.media instanceof Poll)) {
@ -80,11 +66,7 @@ export async function sendVote(
assertTypeIs('messages.sendVote (@ .updates[0])', upd, 'updateMessagePoll') assertTypeIs('messages.sendVote (@ .updates[0])', upd, 'updateMessagePoll')
if (!upd.poll) { if (!upd.poll) {
throw new MtTypeAssertionError( throw new MtTypeAssertionError('messages.sendVote (@ .updates[0].poll)', 'poll', 'undefined')
'messages.sendVote (@ .updates[0].poll)',
'poll',
'undefined',
)
} }
const peers = PeersIndex.from(res) const peers = PeersIndex.from(res)

View file

@ -28,10 +28,5 @@ export async function translateMessage(
toLang: toLanguage, toLang: toLanguage,
}) })
return [ return [res.result[0].text, res.result[0].entities.map((it) => MessageEntity._parse(it)).filter(isPresent)]
res.result[0].text,
res.result[0].entities
.map((it) => MessageEntity._parse(it))
.filter(isPresent),
]
} }

View file

@ -11,11 +11,7 @@ import { TelegramClient } from '../../client'
* @param toLanguage Target language (two-letter ISO 639-1 language code) * @param toLanguage Target language (two-letter ISO 639-1 language code)
* @internal * @internal
*/ */
export async function translateText( export async function translateText(this: TelegramClient, text: string, toLanguage: string): Promise<string | null> {
this: TelegramClient,
text: string,
toLanguage: string,
): Promise<string | null> {
const res = await this.call({ const res = await this.call({
_: 'messages.translateText', _: 'messages.translateText',
text: [ text: [

View file

@ -9,10 +9,7 @@ import { createDummyUpdate } from '../../utils/updates-utils'
* @param chatId Chat or user ID * @param chatId Chat or user ID
* @internal * @internal
*/ */
export async function unpinAllMessages( export async function unpinAllMessages(this: TelegramClient, chatId: InputPeerLike): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
): Promise<void> {
const peer = await this.resolvePeer(chatId) const peer = await this.resolvePeer(chatId)
const res = await this.call({ const res = await this.call({
@ -21,9 +18,7 @@ export async function unpinAllMessages(
}) })
if (isInputPeerChannel(peer)) { if (isInputPeerChannel(peer)) {
this._handleUpdate( this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
createDummyUpdate(res.pts, res.ptsCount, peer.channelId),
)
} else { } else {
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount)) this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
} }

View file

@ -11,11 +11,7 @@ import { InputPeerLike } from '../../types'
* @param messageId Message ID * @param messageId Message ID
* @internal * @internal
*/ */
export async function unpinMessage( export async function unpinMessage(this: TelegramClient, chatId: InputPeerLike, messageId: number): Promise<void> {
this: TelegramClient,
chatId: InputPeerLike,
messageId: number,
): Promise<void> {
const res = await this.call({ const res = await this.call({
_: 'messages.updatePinnedMessage', _: 'messages.updatePinnedMessage',
peer: await this.resolvePeer(chatId), peer: await this.resolvePeer(chatId),

View file

@ -12,16 +12,11 @@ import { IMessageEntityParser } from '../../types'
* @throws MtClientError When the parse mode with a given name is already registered. * @throws MtClientError When the parse mode with a given name is already registered.
* @internal * @internal
*/ */
export function registerParseMode( export function registerParseMode(this: TelegramClient, parseMode: IMessageEntityParser): void {
this: TelegramClient,
parseMode: IMessageEntityParser,
): void {
const name = parseMode.name const name = parseMode.name
if (this._parseModes.has(name)) { if (this._parseModes.has(name)) {
throw new MtArgumentError( throw new MtArgumentError(`Parse mode ${name} is already registered. Unregister it first!`)
`Parse mode ${name} is already registered. Unregister it first!`,
)
} }
this._parseModes.set(name, parseMode) this._parseModes.set(name, parseMode)
@ -56,10 +51,7 @@ export function unregisterParseMode(this: TelegramClient, name: string): void {
* @throws MtClientError When `name` is omitted and there is no default parse mode * @throws MtClientError When `name` is omitted and there is no default parse mode
* @internal * @internal
*/ */
export function getParseMode( export function getParseMode(this: TelegramClient, name?: string | null): IMessageEntityParser {
this: TelegramClient,
name?: string | null,
): IMessageEntityParser {
if (!name) { if (!name) {
if (!this._defaultParseMode) { if (!this._defaultParseMode) {
throw new MtArgumentError('There is no default parse mode') throw new MtArgumentError('There is no default parse mode')

View file

@ -1,9 +1,5 @@
import { MtArgumentError } from '@mtcute/core' import { MtArgumentError } from '@mtcute/core'
import { import { assertTypeIs, computeNewPasswordHash, computeSrpParams } from '@mtcute/core/utils'
assertTypeIs,
computeNewPasswordHash,
computeSrpParams,
} from '@mtcute/core/utils'
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
@ -28,18 +24,10 @@ export async function changeCloudPassword(
} }
const algo = pwd.newAlgo const algo = pwd.newAlgo
assertTypeIs( assertTypeIs('account.getPassword', algo, 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow')
'account.getPassword',
algo,
'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow',
)
const oldSrp = await computeSrpParams(this._crypto, pwd, currentPassword) const oldSrp = await computeSrpParams(this._crypto, pwd, currentPassword)
const newHash = await computeNewPasswordHash( const newHash = await computeNewPasswordHash(this._crypto, algo, newPassword)
this._crypto,
algo,
newPassword,
)
await this.call({ await this.call({
_: 'account.updatePasswordSettings', _: 'account.updatePasswordSettings',

View file

@ -29,11 +29,7 @@ export async function enableCloudPassword(
} }
const algo = pwd.newAlgo const algo = pwd.newAlgo
assertTypeIs( assertTypeIs('account.getPassword', algo, 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow')
'account.getPassword',
algo,
'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow',
)
const newHash = await computeNewPasswordHash(this._crypto, algo, password) const newHash = await computeNewPasswordHash(this._crypto, algo, password)

View file

@ -6,10 +6,7 @@ import { TelegramClient } from '../../client'
* @param code Code which was sent via email * @param code Code which was sent via email
* @internal * @internal
*/ */
export async function verifyPasswordEmail( export async function verifyPasswordEmail(this: TelegramClient, code: string): Promise<void> {
this: TelegramClient,
code: string,
): Promise<void> {
await this.call({ await this.call({
_: 'account.confirmPasswordEmail', _: 'account.confirmPasswordEmail',
code, code,

View file

@ -9,10 +9,7 @@ import { TelegramClient } from '../../client'
* @param password 2FA password as plaintext * @param password 2FA password as plaintext
* @internal * @internal
*/ */
export async function removeCloudPassword( export async function removeCloudPassword(this: TelegramClient, password: string): Promise<void> {
this: TelegramClient,
password: string,
): Promise<void> {
const pwd = await this.call({ _: 'account.getPassword' }) const pwd = await this.call({ _: 'account.getPassword' })
if (!pwd.hasPassword) { if (!pwd.hasPassword) {

Some files were not shown because too many files have changed in this diff Show more