refactor: move errors to core
This commit is contained in:
parent
6e8351ac01
commit
976c25141c
113 changed files with 523 additions and 399 deletions
|
@ -1,5 +1,6 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtTypeAssertionError } from '../../types'
|
||||
|
||||
/**
|
||||
* Accept the given TOS
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { computeSrpParams } from '@mtcute/core/utils'
|
||||
import { assertTypeIs, computeSrpParams } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Check your Two-Step verification password and log in
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Recover your password with a recovery code and log in.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { SentCode } from '../../types'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Re-send the confirmation code using a different type.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { SentCode } from '../../types'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Send the confirmation code to the given phone number
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Authorize a bot using its token issued by [@BotFather](//t.me/BotFather)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { TermsOfService, User } from '../../types'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Authorize a user in Telegram with a valid confirmation code.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Register a new user in Telegram.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MaybeDynamic, MtArgumentError, User } from '../../types'
|
||||
import { MaybeDynamic, User } from '../../types'
|
||||
|
||||
/**
|
||||
* Utility function to quickly authorize on test DC
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* eslint-disable no-console */
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
MaybeAsync,
|
||||
MaybeDynamic,
|
||||
MtArgumentError,
|
||||
SentCode,
|
||||
TermsOfService,
|
||||
User,
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtInvalidPeerTypeError,
|
||||
MtTypeAssertionError,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, Message, MtInvalidPeerTypeError } from '../../types'
|
||||
import {
|
||||
isInputPeerChannel,
|
||||
isInputPeerChat,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
|
@ -13,7 +14,6 @@ import {
|
|||
isInputPeerUser,
|
||||
normalizeToInputChannel,
|
||||
} from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get information about a single chat member
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { assertNever } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
ArrayWithTotal, ChatMember,
|
||||
ArrayWithTotal,
|
||||
ChatMember,
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
PeersIndex } from '../../types'
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import {
|
||||
isInputPeerChannel,
|
||||
isInputPeerChat,
|
||||
normalizeToInputChannel,
|
||||
} from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get a chunk of members of some chat.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { ChatPreview, MtArgumentError, MtPeerNotFoundError } from '../../types'
|
||||
import { ChatPreview, MtPeerNotFoundError } from '../../types'
|
||||
import { INVITE_LINK_REGEX } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Chat, InputPeerLike, MtArgumentError } from '../../types'
|
||||
import { Chat, InputPeerLike } from '../../types'
|
||||
import {
|
||||
INVITE_LINK_REGEX,
|
||||
isInputPeerChannel,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Chat, InputPeerLike, MtArgumentError } from '../../types'
|
||||
import { Chat, InputPeerLike } from '../../types'
|
||||
import {
|
||||
INVITE_LINK_REGEX,
|
||||
isInputPeerChannel,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Chat } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -6,7 +7,6 @@ import {
|
|||
InputFileLike,
|
||||
InputPeerLike,
|
||||
isUploadedFile,
|
||||
MtArgumentError,
|
||||
MtInvalidPeerTypeError,
|
||||
} from '../../types'
|
||||
import {
|
||||
|
@ -37,14 +37,18 @@ export async function setChatPhoto(
|
|||
): Promise<void> {
|
||||
const chat = await this.resolvePeer(chatId)
|
||||
|
||||
if (!(isInputPeerChannel(chat) || isInputPeerChat(chat))) { throw new MtInvalidPeerTypeError(chatId, 'chat or channel') }
|
||||
if (!(isInputPeerChannel(chat) || isInputPeerChat(chat))) {
|
||||
throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||
}
|
||||
|
||||
let photo: tl.TypeInputChatPhoto | undefined = undefined
|
||||
|
||||
let inputFile: tl.TypeInputFile
|
||||
|
||||
if (tdFileId.isFileIdLike(media)) {
|
||||
if (typeof media === 'string' && media.match(/^https?:\/\//)) { throw new MtArgumentError("Chat photo can't be external") }
|
||||
if (typeof media === 'string' && media.match(/^https?:\/\//)) {
|
||||
throw new MtArgumentError("Chat photo can't be external")
|
||||
}
|
||||
if (typeof media === 'string' && media.match(/^file:/)) {
|
||||
const uploaded = await this.uploadFile({
|
||||
file: media.substring(5),
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get list of contacts from your Telegram contacts list.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../../types'
|
||||
|
||||
/**
|
||||
* Edit a folder with given modification
|
||||
|
@ -31,7 +31,9 @@ export async function editFolder(
|
|||
(it.id === folder || it.title === folder),
|
||||
)
|
||||
|
||||
if (!found) { throw new MtArgumentError(`Could not find a folder ${folder}`) }
|
||||
if (!found) {
|
||||
throw new MtArgumentError(`Could not find a folder ${folder}`)
|
||||
}
|
||||
|
||||
folder = found as tl.RawDialogFilter
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../../types'
|
||||
|
||||
/**
|
||||
* Find a folder by its parameter.
|
||||
|
@ -21,7 +21,9 @@ export async function findFolder(
|
|||
id?: number
|
||||
},
|
||||
): Promise<tl.RawDialogFilter | null> {
|
||||
if (!params.title && !params.emoji && !params.id) { throw new MtArgumentError('One of search parameters must be passed') }
|
||||
if (!params.title && !params.emoji && !params.id) {
|
||||
throw new MtArgumentError('One of search parameters must be passed')
|
||||
}
|
||||
|
||||
const folders = await this.getFolders()
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Dialog, MtArgumentError } from '../../types'
|
||||
import { Dialog } from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
|
||||
/**
|
||||
|
@ -233,10 +234,11 @@ export async function* getDialogs(
|
|||
}
|
||||
}
|
||||
|
||||
const filterFolder = filters ? // if pinned is `only`, this wouldn't be reached
|
||||
// if pinned is `only`, this wouldn't be reached
|
||||
// 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 `keep`, we want to keep them
|
||||
const filterFolder = filters ?
|
||||
Dialog.filterFolder(filters, pinned !== 'keep') :
|
||||
undefined
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { getMarkedPeerId, MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Dialog, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { Dialog, PeersIndex } from '../../types'
|
||||
|
||||
/** @internal */
|
||||
export function _parseDialogs(
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
FileDownloadParameters,
|
||||
FileLocation,
|
||||
MtUnsupportedError,
|
||||
} from '../../types'
|
||||
import { MtUnsupportedError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { FileDownloadParameters, FileLocation } from '../../types'
|
||||
let fs: typeof import('fs') | null = null
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { ConnectionKind } from '@mtcute/core'
|
||||
import {
|
||||
ConnectionKind,
|
||||
MtArgumentError,
|
||||
MtUnsupportedError,
|
||||
} from '@mtcute/core'
|
||||
import { ConditionVariable } from '@mtcute/core/utils'
|
||||
import {
|
||||
fileIdToInputFileLocation,
|
||||
|
@ -8,12 +12,7 @@ import {
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
FileDownloadParameters,
|
||||
FileLocation,
|
||||
MtArgumentError,
|
||||
MtUnsupportedError,
|
||||
} from '../../types'
|
||||
import { FileDownloadParameters, FileLocation } from '../../types'
|
||||
import { determinePartSize } from '../../utils/file-utils'
|
||||
|
||||
// small files (less than 128 kb) are downloaded using the "downloadSmall" pool
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputFileLike } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tdFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputFileLike, isUploadedFile, MtArgumentError } from '../../types'
|
||||
import { InputFileLike, isUploadedFile } from '../../types'
|
||||
|
||||
/**
|
||||
* Normalize a {@link InputFileLike} to `InputFile`,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import {
|
||||
fileIdToInputDocument,
|
||||
fileIdToInputPhoto,
|
||||
|
@ -12,7 +13,6 @@ import { TelegramClient } from '../../client'
|
|||
import { InputMediaLike, isUploadedFile, UploadFileLike } from '../../types'
|
||||
import { extractFileName } from '../../utils/file-utils'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { encodeWaveform } from '../../utils/voice-utils'
|
||||
|
||||
/**
|
||||
|
@ -267,8 +267,8 @@ export async function _normalizeInputMedia(
|
|||
)
|
||||
assertTypeIs(
|
||||
'normalizeInputMedia (@ messages.uploadMedia)',
|
||||
res.document!,
|
||||
'document',
|
||||
res.document!,
|
||||
'document',
|
||||
)
|
||||
|
||||
return {
|
||||
|
@ -377,7 +377,9 @@ export async function _normalizeInputMedia(
|
|||
roundMessage: media.isRound,
|
||||
})
|
||||
|
||||
if (media.isAnimated) { attributes.push({ _: 'documentAttributeAnimated' }) }
|
||||
if (media.isAnimated) {
|
||||
attributes.push({ _: 'documentAttributeAnimated' })
|
||||
}
|
||||
}
|
||||
|
||||
if (media.type === 'audio' || media.type === 'voice') {
|
||||
|
|
|
@ -2,11 +2,12 @@ import { fromBuffer as fileTypeFromBuffer } from 'file-type'
|
|||
import type { ReadStream } from 'fs'
|
||||
import { Readable } from 'stream'
|
||||
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { AsyncLock, randomLong } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError, UploadedFile, UploadFileLike } from '../../types'
|
||||
import { UploadedFile, UploadFileLike } from '../../types'
|
||||
import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils'
|
||||
import {
|
||||
bufferToStream,
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import { assertNever } from '@mtcute/core'
|
||||
import {
|
||||
assertNever,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
} from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
MessageMedia,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
Photo,
|
||||
RawDocument,
|
||||
} from '../../types'
|
||||
import { parseDocument } from '../../types/media/document-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Upload a media to Telegram servers, without actually
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
ChatInviteLink,
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
ChatInviteLink,
|
||||
InputPeerLike,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get primary invite link of a chat
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
Poll,
|
||||
} from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { InputPeerLike, PeersIndex, Poll } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { Message, PeersIndex } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/** @internal */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MaybeArray } from '@mtcute/core'
|
||||
import { MaybeArray, MtArgumentError } from '@mtcute/core'
|
||||
import { randomLong } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -8,7 +8,6 @@ import {
|
|||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, Message, MtArgumentError } from '../../types'
|
||||
import { InputPeerLike, Message } from '../../types'
|
||||
import { isInputPeerChannel } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MessageReactions, PeersIndex } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { MaybeArray } from '@mtcute/core'
|
||||
import { MaybeArray, MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { Message, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get a single message from PM or legacy group by its ID.
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
import { MaybeArray } from '@mtcute/core'
|
||||
import { MaybeArray, MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
import {
|
||||
isInputPeerChannel,
|
||||
normalizeToInputChannel,
|
||||
|
@ -105,7 +100,9 @@ export async function getMessages(
|
|||
msg.peerId._ === 'peerUser' &&
|
||||
msg.peerId.userId === this._userId
|
||||
)
|
||||
) { return null }
|
||||
) {
|
||||
return null
|
||||
}
|
||||
break
|
||||
case 'inputPeerUser':
|
||||
case 'inputPeerUserFromMessage':
|
||||
|
@ -114,7 +111,9 @@ export async function getMessages(
|
|||
msg.peerId._ === 'peerUser' &&
|
||||
msg.peerId.userId === peer.userId
|
||||
)
|
||||
) { return null }
|
||||
) {
|
||||
return null
|
||||
}
|
||||
break
|
||||
case 'inputPeerChat':
|
||||
if (
|
||||
|
@ -122,7 +121,9 @@ export async function getMessages(
|
|||
msg.peerId._ === 'peerChat' &&
|
||||
msg.peerId.chatId === peer.chatId
|
||||
)
|
||||
) { return null }
|
||||
) {
|
||||
return null
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import { MaybeArray } from '@mtcute/core'
|
||||
import { MaybeArray, MtTypeAssertionError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get a single scheduled message in chat by its ID
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { FormattedString, MtClientError } from '../../types'
|
||||
import { FormattedString } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
|
||||
const empty: [string, undefined] = ['', undefined]
|
||||
|
@ -33,7 +34,7 @@ export async function _parseEntities(
|
|||
const modeImpl = this._parseModes.get(mode)
|
||||
|
||||
if (!modeImpl) {
|
||||
throw new MtClientError(`Parse mode ${mode} is not registered.`)
|
||||
throw new MtArgumentError(`Parse mode ${mode} is not registered.`)
|
||||
}
|
||||
|
||||
[text, entities] = modeImpl.parse(text)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Message, MtTypeAssertionError, PeersIndex, SearchFilters } from '../../types'
|
||||
import { Message, PeersIndex, SearchFilters } from '../../types'
|
||||
|
||||
/**
|
||||
* Search for messages globally from all of your chats
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
SearchFilters } from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex, SearchFilters } from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { getMarkedPeerId, MtArgumentError } from '@mtcute/core'
|
||||
import { randomLong } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -8,7 +8,6 @@ import {
|
|||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
MtMessageNotFoundError,
|
||||
PeersIndex,
|
||||
ReplyMarkup,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { getMarkedPeerId, MtArgumentError } from '@mtcute/core'
|
||||
import { randomLong } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -9,7 +9,6 @@ import {
|
|||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
MtMessageNotFoundError,
|
||||
ReplyMarkup,
|
||||
} from '../../types'
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import {
|
||||
getMarkedPeerId,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
} from '@mtcute/core'
|
||||
import { randomLong } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -8,9 +12,7 @@ import {
|
|||
FormattedString,
|
||||
InputPeerLike,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
MtMessageNotFoundError,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
ReplyMarkup,
|
||||
} from '../../types'
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
getMarkedPeerId,
|
||||
MaybeArray,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
} from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
MtArgumentError,
|
||||
MtMessageNotFoundError,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
Poll,
|
||||
} from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { IMessageEntityParser, MtClientError } from '../../types'
|
||||
import { IMessageEntityParser } from '../../types'
|
||||
|
||||
/**
|
||||
* Register a given {@link IMessageEntityParser} as a parse mode
|
||||
|
@ -17,7 +19,7 @@ export function registerParseMode(
|
|||
const name = parseMode.name
|
||||
|
||||
if (this._parseModes.has(name)) {
|
||||
throw new MtClientError(
|
||||
throw new MtArgumentError(
|
||||
`Parse mode ${name} is already registered. Unregister it first!`,
|
||||
)
|
||||
}
|
||||
|
@ -60,7 +62,7 @@ export function getParseMode(
|
|||
): IMessageEntityParser {
|
||||
if (!name) {
|
||||
if (!this._defaultParseMode) {
|
||||
throw new MtClientError('There is no default parse mode')
|
||||
throw new MtArgumentError('There is no default parse mode')
|
||||
}
|
||||
|
||||
name = this._defaultParseMode
|
||||
|
@ -69,7 +71,7 @@ export function getParseMode(
|
|||
const mode = this._parseModes.get(name)
|
||||
|
||||
if (!mode) {
|
||||
throw new MtClientError(`Parse mode ${name} is not registered.`)
|
||||
throw new MtArgumentError(`Parse mode ${name} is not registered.`)
|
||||
}
|
||||
|
||||
return mode
|
||||
|
@ -84,7 +86,7 @@ export function getParseMode(
|
|||
*/
|
||||
export function setDefaultParseMode(this: TelegramClient, name: string): void {
|
||||
if (!this._parseModes.has(name)) {
|
||||
throw new MtClientError(`Parse mode ${name} is not registered.`)
|
||||
throw new MtArgumentError(`Parse mode ${name} is not registered.`)
|
||||
}
|
||||
|
||||
this._defaultParseMode = name
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { computeNewPasswordHash, computeSrpParams } from '@mtcute/core/utils'
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import {
|
||||
assertTypeIs,
|
||||
computeNewPasswordHash,
|
||||
computeSrpParams,
|
||||
} from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Change your 2FA password
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { computeNewPasswordHash } from '@mtcute/core/utils'
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { assertTypeIs, computeNewPasswordHash } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Enable 2FA password on your account
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { computeSrpParams } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../../types'
|
||||
|
||||
/**
|
||||
* Remove 2FA password from your account
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
|
@ -5,7 +6,6 @@ import {
|
|||
InputFileLike,
|
||||
InputPeerLike,
|
||||
InputStickerSetItem,
|
||||
MtArgumentError,
|
||||
StickerSet,
|
||||
StickerSourceType,
|
||||
StickerType,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtTypeAssertionError, Sticker } from '../../types'
|
||||
import { Sticker } from '../../types'
|
||||
import { parseDocument } from '../../types/media/document-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get custom emoji stickers by their IDs
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { StickerSet } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get a list of all installed sticker packs
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable max-depth */
|
||||
import { assertNever } from '@mtcute/core'
|
||||
import { assertNever, MtArgumentError } from '@mtcute/core'
|
||||
import {
|
||||
AsyncLock,
|
||||
ConditionVariable,
|
||||
|
@ -14,7 +14,7 @@ import {
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../client'
|
||||
import { MtArgumentError, PeersIndex } from '../types'
|
||||
import { PeersIndex } from '../types'
|
||||
import { _parseUpdate } from '../types/updates/parse-update'
|
||||
import { extractChannelIdFromUpdate } from '../utils/misc-utils'
|
||||
import { normalizeToInputChannel } from '../utils/peer-utils'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get currently authorized user's full information
|
||||
|
|
|
@ -3,18 +3,15 @@ import Long from 'long'
|
|||
import {
|
||||
getBasicPeerType,
|
||||
getMarkedPeerId,
|
||||
MtTypeAssertionError,
|
||||
toggleChannelIdMark,
|
||||
} from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
InputPeerLike,
|
||||
MtPeerNotFoundError,
|
||||
MtTypeAssertionError,
|
||||
} from '../../types'
|
||||
import { InputPeerLike, MtPeerNotFoundError } from '../../types'
|
||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get the `InputPeer` of a known peer id.
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputFileLike, MtArgumentError, Photo } from '../../types'
|
||||
import { InputFileLike, Photo } from '../../types'
|
||||
|
||||
/**
|
||||
* Set a new profile photo or video.
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { BasicPeerType, getBasicPeerType, getMarkedPeerId } from '@mtcute/core'
|
||||
import {
|
||||
BasicPeerType,
|
||||
getBasicPeerType,
|
||||
getMarkedPeerId,
|
||||
MtArgumentError,
|
||||
} from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { encodeInlineMessageId } from '../../utils/inline-utils'
|
||||
import { MtArgumentError, MtMessageNotFoundError } from '../errors'
|
||||
import { MtMessageNotFoundError } from '../errors'
|
||||
import { Message } from '../messages'
|
||||
import { PeersIndex, User } from '../peers'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { fileIdToInputDocument, fileIdToInputPhoto } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../../client'
|
||||
import { extractFileName } from '../../../utils/file-utils'
|
||||
import { MtArgumentError } from '../../errors'
|
||||
import { BotInlineMessage, InputInlineMessage } from './input-inline-message'
|
||||
|
||||
export interface BaseInputInlineResult {
|
||||
|
@ -903,8 +903,8 @@ export namespace BotInline {
|
|||
}
|
||||
} else if (
|
||||
obj.type === 'video' &&
|
||||
obj.isEmbed &&
|
||||
typeof obj.media === 'string'
|
||||
obj.isEmbed &&
|
||||
typeof obj.media === 'string'
|
||||
) {
|
||||
sendMessage = {
|
||||
_: 'inputBotInlineMessageText',
|
||||
|
@ -956,8 +956,9 @@ export namespace BotInline {
|
|||
|
||||
let mime: string
|
||||
if (obj.type === 'video') mime = 'video/mp4'
|
||||
else if (obj.type === 'audio') { mime = obj.mime ?? 'audio/mpeg' } else if (obj.type === 'gif') mime = obj.mime ?? 'video/mp4'
|
||||
else if (obj.type === 'voice') mime = 'audio/ogg'
|
||||
else if (obj.type === 'audio') {
|
||||
mime = obj.mime ?? 'audio/mpeg'
|
||||
} else if (obj.type === 'gif') { mime = obj.mime ?? 'video/mp4' } else if (obj.type === 'voice') mime = 'audio/ogg'
|
||||
else if (obj.type === 'file') {
|
||||
if (!obj.mime) {
|
||||
throw new MtArgumentError(
|
||||
|
@ -991,7 +992,10 @@ export namespace BotInline {
|
|||
h: obj.height,
|
||||
})
|
||||
}
|
||||
} else if (obj.type === 'audio' || obj.type === 'voice') {
|
||||
} else if (
|
||||
obj.type === 'audio' ||
|
||||
obj.type === 'voice'
|
||||
) {
|
||||
attributes.push({
|
||||
_: 'documentAttributeAudio',
|
||||
voice: obj.type === 'voice',
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/* eslint-disable dot-notation */
|
||||
import { getMarkedPeerId, MaybeAsync } from '@mtcute/core'
|
||||
import {
|
||||
getMarkedPeerId,
|
||||
MaybeAsync,
|
||||
MtArgumentError,
|
||||
MtTimeoutError,
|
||||
} from '@mtcute/core'
|
||||
import {
|
||||
AsyncLock,
|
||||
ControllablePromise,
|
||||
|
@ -9,7 +14,6 @@ import {
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../client'
|
||||
import { MtArgumentError, MtTimeoutError } from './errors'
|
||||
import { InputMediaLike } from './media'
|
||||
import { Message } from './messages'
|
||||
import { FormattedString } from './parser'
|
||||
|
|
|
@ -1,25 +1,16 @@
|
|||
/**
|
||||
* Base class for all `@mtcute/client` errors
|
||||
*/
|
||||
import { MtcuteError } from '@mtcute/core'
|
||||
|
||||
import { InputPeerLike } from './peers'
|
||||
|
||||
export class MtClientError extends Error {}
|
||||
|
||||
/**
|
||||
* Method invocation was invalid because some argument
|
||||
* passed was invalid.
|
||||
*/
|
||||
export class MtArgumentError extends MtClientError {}
|
||||
|
||||
/**
|
||||
* Could not find a peer by the provided information
|
||||
*/
|
||||
export class MtPeerNotFoundError extends MtClientError {}
|
||||
export class MtPeerNotFoundError extends MtcuteError {}
|
||||
|
||||
/**
|
||||
* Could not find a message by the provided information
|
||||
*/
|
||||
export class MtMessageNotFoundError extends MtClientError {
|
||||
export class MtMessageNotFoundError extends MtcuteError {
|
||||
constructor(
|
||||
readonly peerId: number,
|
||||
readonly messageId: number,
|
||||
|
@ -33,46 +24,6 @@ export class MtMessageNotFoundError extends MtClientError {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Either you requested or the server returned something
|
||||
* that is not (yet) supported.
|
||||
*
|
||||
* Stay tuned for future updates!
|
||||
*/
|
||||
export class MtUnsupportedError extends MtClientError {}
|
||||
|
||||
/**
|
||||
* Server returned something of an unexpected type.
|
||||
*
|
||||
* This is usually a problem on library side.
|
||||
* Feel free to open an issue about this!
|
||||
*/
|
||||
export class MtTypeAssertionError extends MtClientError {
|
||||
/**
|
||||
* Context at which the error occurred.
|
||||
* Usually a user-friendly string containing name
|
||||
* of the high-level API method, name of the TL
|
||||
* RPC method, and path of the entity,
|
||||
* like this: `signIn (@ auth.signIn -> user)`
|
||||
*/
|
||||
context: string
|
||||
|
||||
/** Expected TL type */
|
||||
expected: string
|
||||
|
||||
/** Actual TL type */
|
||||
actual: string
|
||||
|
||||
constructor(context: string, expected: string, actual: string) {
|
||||
super(
|
||||
`Type assertion error at ${context}: expected ${expected}, but got ${actual}`,
|
||||
)
|
||||
this.context = context
|
||||
this.expected = expected
|
||||
this.actual = actual
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some method that requires a particular type of peer
|
||||
* is called, but the resolved peer type is invalid.
|
||||
|
@ -80,7 +31,7 @@ export class MtTypeAssertionError extends MtClientError {
|
|||
* For example, when trying to get common chats
|
||||
* while providing another chat as `userId`
|
||||
*/
|
||||
export class MtInvalidPeerTypeError extends MtClientError {
|
||||
export class MtInvalidPeerTypeError extends MtcuteError {
|
||||
constructor(peer: InputPeerLike, expected: string) {
|
||||
super(
|
||||
`Provided identifier ${JSON.stringify(peer)} is not a ${expected}`,
|
||||
|
@ -92,14 +43,8 @@ export class MtInvalidPeerTypeError extends MtClientError {
|
|||
* Trying to access to some property on an object that does not
|
||||
* contain that information.
|
||||
*/
|
||||
export class MtEmptyError extends MtClientError {
|
||||
export class MtEmptyError extends MtcuteError {
|
||||
constructor() {
|
||||
super('Property is not available on an empty object')
|
||||
}
|
||||
}
|
||||
|
||||
export class MtTimeoutError extends MtClientError {
|
||||
constructor(readonly timeout?: number) {
|
||||
super(`Request timed out${timeout ? ` after ${timeout}ms` : ''}`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { FileLocation } from './file-location'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { WebDocument } from '../files/web-document'
|
||||
import { _messageMediaFromTl, MessageMedia } from '../messages'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
@ -146,7 +146,9 @@ export class Invoice {
|
|||
get extendedMediaState(): InvoiceExtendedMediaState {
|
||||
if (!this.raw.extendedMedia) return 'none'
|
||||
|
||||
if (this.raw.extendedMedia._ === 'messageExtendedMediaPreview') { return 'preview' }
|
||||
if (this.raw.extendedMedia._ === 'messageExtendedMediaPreview') {
|
||||
return 'preview'
|
||||
}
|
||||
|
||||
return 'full'
|
||||
}
|
||||
|
@ -158,7 +160,9 @@ export class Invoice {
|
|||
* Otherwise, throws an error.
|
||||
*/
|
||||
get extendedMediaPreview(): InvoiceExtendedMediaPreview {
|
||||
if (this.raw.extendedMedia?._ !== 'messageExtendedMediaPreview') { throw new MtArgumentError('No extended media preview available') }
|
||||
if (this.raw.extendedMedia?._ !== 'messageExtendedMediaPreview') {
|
||||
throw new MtArgumentError('No extended media preview available')
|
||||
}
|
||||
|
||||
return (this._extendedMediaPreview ??= new InvoiceExtendedMediaPreview(
|
||||
this.client,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { FileLocation } from '../files'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { Thumbnail } from './thumbnail'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tdFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { StickerSet } from '../misc'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { RawDocument } from './document'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
|
@ -9,8 +11,6 @@ import {
|
|||
strippedPhotoToJpg,
|
||||
svgPathToFile,
|
||||
} from '../../utils/file-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { MtArgumentError, MtTypeAssertionError } from '../errors'
|
||||
import { FileLocation } from '../files'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
|
@ -182,8 +182,12 @@ export class Thumbnail extends FileLocation {
|
|||
* Thumbnail type
|
||||
*/
|
||||
get type(): string {
|
||||
if (this.raw._ === 'videoSizeEmojiMarkup') { return Thumbnail.THUMB_EMOJI_MARKUP }
|
||||
if (this.raw._ === 'videoSizeStickerMarkup') { return Thumbnail.THUMB_STICKER_MARKUP }
|
||||
if (this.raw._ === 'videoSizeEmojiMarkup') {
|
||||
return Thumbnail.THUMB_EMOJI_MARKUP
|
||||
}
|
||||
if (this.raw._ === 'videoSizeStickerMarkup') {
|
||||
return Thumbnail.THUMB_STICKER_MARKUP
|
||||
}
|
||||
|
||||
return this.raw.type
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { Location } from './location'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { RawDocument } from './document'
|
||||
import { parseDocument } from './document-utils'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtTypeAssertionError } from '../errors'
|
||||
import {
|
||||
Audio,
|
||||
Contact,
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { assertNever, getMarkedPeerId, toggleChannelIdMark } from '@mtcute/core'
|
||||
import {
|
||||
assertNever,
|
||||
getMarkedPeerId,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
toggleChannelIdMark,
|
||||
} from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { BotKeyboard, ReplyMarkup } from '../bots'
|
||||
import { MtArgumentError, MtTypeAssertionError } from '../errors'
|
||||
import { InputMediaLike, Sticker, WebPage } from '../media'
|
||||
import { FormattedString } from '../parser'
|
||||
import { Chat, InputPeerLike, PeersIndex, User } from '../peers'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { PeersIndex, User } from '../peers'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { LongMap } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtEmptyError, MtTypeAssertionError } from '../errors'
|
||||
import { MtEmptyError } from '../errors'
|
||||
import { InputFileLike } from '../files'
|
||||
import {
|
||||
MaskPosition,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtTypeAssertionError } from '../errors'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { PeersIndex } from './index'
|
||||
import { User } from './user'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { ChatPermissions } from './chat-permissions'
|
||||
import { PeersIndex } from './index'
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import Long from 'long'
|
||||
|
||||
import { toggleChannelIdMark } from '@mtcute/core'
|
||||
import { MtArgumentError, toggleChannelIdMark } from '@mtcute/core'
|
||||
import { tdFileId, toFileId, toUniqueFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { strippedPhotoToJpg } from '../../utils/file-utils'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { FileLocation } from '../files'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
getMarkedPeerId,
|
||||
MaybeArray,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
} from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MtArgumentError, MtTypeAssertionError } from '../errors'
|
||||
import { InputMediaLike } from '../media'
|
||||
import { FormattedString } from '../parser'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtArgumentError } from '../errors'
|
||||
|
||||
const ERROR_MSG =
|
||||
'Given peer is not available in this index. This is most likely an internal library error.'
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import { InputMediaLike } from '../media'
|
||||
import { FormattedString } from '../parser'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { encodeInlineMessageId } from '../../utils/inline-utils'
|
||||
import { Location, MtArgumentError, PeersIndex, User } from '../'
|
||||
import { Location, PeersIndex, User } from '../'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MtUnsupportedError } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { Chat, MtUnsupportedError, PeersIndex, User } from '../'
|
||||
import { Chat, PeersIndex, User } from '../'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import { getBarePeerId, toggleChannelIdMark } from '@mtcute/core'
|
||||
import {
|
||||
getBarePeerId,
|
||||
MtUnsupportedError,
|
||||
toggleChannelIdMark,
|
||||
} from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
BasicPeerType,
|
||||
Chat,
|
||||
MtUnsupportedError,
|
||||
TypingStatus,
|
||||
User,
|
||||
} from '../'
|
||||
import { BasicPeerType, Chat, TypingStatus, User } from '../'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MtArgumentError } from '../types'
|
||||
import { MtArgumentError } from '@mtcute/core'
|
||||
|
||||
/**
|
||||
* Given file size, determine the appropriate chunk size (in KB)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { MtArgumentError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MaybeDynamic, Message, MtClientError } from '../types'
|
||||
import { MaybeDynamic, Message } from '../types'
|
||||
|
||||
/**
|
||||
* Normalize phone number by stripping formatting
|
||||
|
@ -8,7 +9,7 @@ import { MaybeDynamic, Message, MtClientError } from '../types'
|
|||
*/
|
||||
export function normalizePhoneNumber(phone: string): string {
|
||||
phone = phone.trim().replace(/[+()\s-]/g, '')
|
||||
if (!phone.match(/^\d+$/)) throw new MtClientError('Invalid phone number')
|
||||
if (!phone.match(/^\d+$/)) throw new MtArgumentError('Invalid phone number')
|
||||
|
||||
return phone
|
||||
}
|
||||
|
@ -25,7 +26,13 @@ export function extractChannelIdFromUpdate(
|
|||
|
||||
if ('channelId' in upd) {
|
||||
res = upd.channelId
|
||||
} else if ('message' in upd && typeof upd.message !== 'string' && 'peerId' in upd.message && upd.message.peerId && 'channelId' in upd.message.peerId) {
|
||||
} else if (
|
||||
'message' in upd &&
|
||||
typeof upd.message !== 'string' &&
|
||||
'peerId' in upd.message &&
|
||||
upd.message.peerId &&
|
||||
'channelId' in upd.message.peerId
|
||||
) {
|
||||
res = upd.message.peerId.channelId
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtTypeAssertionError } from '../types'
|
||||
|
||||
export function assertTypeIs<T extends tl.TlObject, K extends T['_']>(
|
||||
context: string,
|
||||
obj: T,
|
||||
expected: K,
|
||||
): asserts obj is tl.FindByName<T, K> {
|
||||
if (obj._ !== expected) {
|
||||
throw new MtTypeAssertionError(context, expected, obj._)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { MtTypeAssertionError } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtTypeAssertionError } from '../types'
|
||||
|
||||
// dummy updates which are used for methods that return messages.affectedHistory.
|
||||
// that is not an update, but it carries info about pts, and we need to handle it
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import Long from 'long'
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { TlBinaryReader, TlReaderMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { MtcuteError } from '../types'
|
||||
import { buffersEqual, ICryptoProvider, Logger, randomBytes } from '../utils'
|
||||
import { createAesIgeForMessage } from '../utils/crypto/mtproto'
|
||||
|
||||
|
@ -41,7 +42,7 @@ export class AuthKey {
|
|||
serverSalt: Long,
|
||||
sessionId: Long,
|
||||
): Promise<Buffer> {
|
||||
if (!this.ready) throw new Error('Keys are not set up!')
|
||||
if (!this.ready) throw new MtcuteError('Keys are not set up!')
|
||||
|
||||
let padding =
|
||||
(16 /* header size */ + message.length + 12) /* min padding */ % 16
|
||||
|
|
|
@ -9,6 +9,11 @@ import {
|
|||
TlSerializationCounter,
|
||||
} from '@mtcute/tl-runtime'
|
||||
|
||||
import {
|
||||
MtArgumentError,
|
||||
MtSecurityError,
|
||||
MtTypeAssertionError,
|
||||
} from '../types'
|
||||
import {
|
||||
bigIntToBuffer,
|
||||
bufferToBigInt,
|
||||
|
@ -24,6 +29,7 @@ import {
|
|||
import { findKeyByFingerprints } from '../utils/crypto/keys'
|
||||
import { millerRabin } from '../utils/crypto/miller-rabin'
|
||||
import { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto'
|
||||
import { mtpAssertTypeIs } from '../utils/type-assertions'
|
||||
import { SessionConnection } from './session-connection'
|
||||
|
||||
// Heavily based on code from https://github.com/LonamiWebs/Telethon/blob/master/telethon/network/authenticator.py
|
||||
|
@ -57,14 +63,16 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {
|
|||
dhPrime.lesserOrEquals(TWO_POW_2047) ||
|
||||
dhPrime.greaterOrEquals(TWO_POW_2048)
|
||||
) {
|
||||
throw new Error('Step 3: dh_prime is not in the 2048-bit range')
|
||||
throw new MtSecurityError(
|
||||
'Step 3: dh_prime is not in the 2048-bit range',
|
||||
)
|
||||
}
|
||||
|
||||
if (!millerRabin(dhPrime)) {
|
||||
throw new Error('Step 3: dh_prime is not prime')
|
||||
throw new MtSecurityError('Step 3: dh_prime is not prime')
|
||||
}
|
||||
if (!millerRabin(dhPrime.minus(1).divide(2))) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'Step 3: dh_prime is not a safe prime - (dh_prime-1)/2 is not prime',
|
||||
)
|
||||
}
|
||||
|
@ -91,12 +99,16 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {
|
|||
switch (g) {
|
||||
case 2:
|
||||
if (dhPrime.mod(8).notEquals(7)) {
|
||||
throw new Error('Step 3: ivalid g - dh_prime mod 8 != 7')
|
||||
throw new MtSecurityError(
|
||||
'Step 3: ivalid g - dh_prime mod 8 != 7',
|
||||
)
|
||||
}
|
||||
break
|
||||
case 3:
|
||||
if (dhPrime.mod(3).notEquals(2)) {
|
||||
throw new Error('Step 3: ivalid g - dh_prime mod 3 != 2')
|
||||
throw new MtSecurityError(
|
||||
'Step 3: ivalid g - dh_prime mod 3 != 2',
|
||||
)
|
||||
}
|
||||
break
|
||||
case 4:
|
||||
|
@ -105,7 +117,7 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {
|
|||
const mod = dhPrime.mod(5)
|
||||
|
||||
if (mod.notEquals(1) && mod.notEquals(4)) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'Step 3: ivalid g - dh_prime mod 5 != 1 && dh_prime mod 5 != 4',
|
||||
)
|
||||
}
|
||||
|
@ -115,7 +127,7 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {
|
|||
const mod = dhPrime.mod(24)
|
||||
|
||||
if (mod.notEquals(19) && mod.notEquals(23)) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'Step 3: ivalid g - dh_prime mod 24 != 19 && dh_prime mod 24 != 23',
|
||||
)
|
||||
}
|
||||
|
@ -125,14 +137,14 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {
|
|||
const mod = dhPrime.mod(7)
|
||||
|
||||
if (mod.notEquals(3) && mod.notEquals(5) && mod.notEquals(6)) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'Step 3: ivalid g - dh_prime mod 7 != 3 && dh_prime mod 7 != 5 && dh_prime mod 7 != 6',
|
||||
)
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
throw new Error(`Step 3: ivalid g - unknown g = ${g}`)
|
||||
throw new MtSecurityError(`Step 3: ivalid g - unknown g = ${g}`)
|
||||
}
|
||||
|
||||
checkedPrime.generators.push(g)
|
||||
|
@ -151,7 +163,7 @@ async function rsaPad(
|
|||
const keyExponent = bigInt(key.exponent, 16)
|
||||
|
||||
if (data.length > 144) {
|
||||
throw new Error('Failed to pad: too big data')
|
||||
throw new MtArgumentError('Failed to pad: too big data')
|
||||
}
|
||||
|
||||
data = Buffer.concat([data, randomBytes(192 - data.length)])
|
||||
|
@ -265,10 +277,10 @@ export async function doAuthorization(
|
|||
await sendPlainMessage({ _: 'mt_req_pq_multi', nonce })
|
||||
const resPq = await readNext()
|
||||
|
||||
if (resPq._ !== 'mt_resPQ') throw new Error('Step 1: answer was ' + resPq._)
|
||||
mtpAssertTypeIs('auth step 1', resPq, 'mt_resPQ')
|
||||
|
||||
if (!buffersEqual(resPq.nonce, nonce)) {
|
||||
throw new Error('Step 1: invalid nonce from server')
|
||||
throw new MtSecurityError('Step 1: invalid nonce from server')
|
||||
}
|
||||
|
||||
const serverKeys = resPq.serverPublicKeyFingerprints.map((it) =>
|
||||
|
@ -280,7 +292,7 @@ export async function doAuthorization(
|
|||
const publicKey = findKeyByFingerprints(serverKeys)
|
||||
|
||||
if (!publicKey) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'Step 2: Could not find server public key with any of these fingerprints: ' +
|
||||
serverKeys.join(', '),
|
||||
)
|
||||
|
@ -330,19 +342,13 @@ export async function doAuthorization(
|
|||
})
|
||||
const serverDhParams = await readNext()
|
||||
|
||||
if (!mtp.isAnyServer_DH_Params(serverDhParams)) {
|
||||
throw new Error('Step 2.1: answer was ' + serverDhParams._)
|
||||
}
|
||||
|
||||
if (serverDhParams._ !== 'mt_server_DH_params_ok') {
|
||||
throw new Error('Step 2.1: answer was ' + serverDhParams._)
|
||||
}
|
||||
mtpAssertTypeIs('auth step 2', serverDhParams, 'mt_server_DH_params_ok')
|
||||
|
||||
if (!buffersEqual(serverDhParams.nonce, nonce)) {
|
||||
throw Error('Step 2: invalid nonce from server')
|
||||
throw new MtSecurityError('Step 2: invalid nonce from server')
|
||||
}
|
||||
if (!buffersEqual(serverDhParams.serverNonce, resPq.serverNonce)) {
|
||||
throw Error('Step 2: invalid server nonce from server')
|
||||
throw new MtSecurityError('Step 2: invalid server nonce from server')
|
||||
}
|
||||
|
||||
// type was removed from schema in July 2021
|
||||
|
@ -350,14 +356,14 @@ export async function doAuthorization(
|
|||
// // why would i want to do that? we are gonna fail anyways.
|
||||
// // let expectedNnh = (await crypto.sha1(newNonce)).slice(4, 20)
|
||||
// // if (!buffersEqual(serverDhParams.newNonceHash, expectedNnh))
|
||||
// // throw new Error('Step 2: invalid DH fail nonce from server')
|
||||
// throw new Error('Step 2: server DH failed')
|
||||
// // throw new MtSecurityError('Step 2: invalid DH fail nonce from server')
|
||||
// throw new MtSecurityError('Step 2: server DH failed')
|
||||
// }
|
||||
|
||||
log.debug('server DH ok')
|
||||
|
||||
if (serverDhParams.encryptedAnswer.length % 16 !== 0) {
|
||||
throw new Error('Step 2: AES block size is invalid')
|
||||
throw new MtSecurityError('Step 2: AES block size is invalid')
|
||||
}
|
||||
|
||||
// Step 3: complete DH exchange
|
||||
|
@ -385,12 +391,11 @@ export async function doAuthorization(
|
|||
),
|
||||
)
|
||||
) {
|
||||
throw new Error('Step 3: invalid inner data hash')
|
||||
throw new MtSecurityError('Step 3: invalid inner data hash')
|
||||
}
|
||||
|
||||
if (serverDhInner._ !== 'mt_server_DH_inner_data') {
|
||||
throw Error('Step 3: inner data was ' + serverDhInner._)
|
||||
}
|
||||
mtpAssertTypeIs('auth step 3', serverDhInner, 'mt_server_DH_inner_data')
|
||||
|
||||
if (!buffersEqual(serverDhInner.nonce, nonce)) {
|
||||
throw Error('Step 3: invalid nonce from server')
|
||||
}
|
||||
|
@ -424,28 +429,28 @@ export async function doAuthorization(
|
|||
g.lesserOrEquals(1) ||
|
||||
g.greaterOrEquals(dhPrime.minus(bigInt.one))
|
||||
) {
|
||||
throw new Error('g is not within (1, dh_prime - 1)')
|
||||
throw new MtSecurityError('g is not within (1, dh_prime - 1)')
|
||||
}
|
||||
if (
|
||||
gA.lesserOrEquals(1) ||
|
||||
gA.greaterOrEquals(dhPrime.minus(bigInt.one))
|
||||
) {
|
||||
throw new Error('g_a is not within (1, dh_prime - 1)')
|
||||
throw new MtSecurityError('g_a is not within (1, dh_prime - 1)')
|
||||
}
|
||||
if (
|
||||
gB.lesserOrEquals(1) ||
|
||||
gB.greaterOrEquals(dhPrime.minus(bigInt.one))
|
||||
) {
|
||||
throw new Error('g_b is not within (1, dh_prime - 1)')
|
||||
throw new MtSecurityError('g_b is not within (1, dh_prime - 1)')
|
||||
}
|
||||
|
||||
if (gA.lt(DH_SAFETY_RANGE) || gA.gt(dhPrime.minus(DH_SAFETY_RANGE))) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'g_a is not within (2^{2048-64}, dh_prime - 2^{2048-64})',
|
||||
)
|
||||
}
|
||||
if (gB.lt(DH_SAFETY_RANGE) || gB.gt(dhPrime.minus(DH_SAFETY_RANGE))) {
|
||||
throw new Error(
|
||||
throw new MtSecurityError(
|
||||
'g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64})',
|
||||
)
|
||||
}
|
||||
|
@ -488,7 +493,11 @@ export async function doAuthorization(
|
|||
const dhGen = await readNext()
|
||||
|
||||
if (!mtp.isAnySet_client_DH_params_answer(dhGen)) {
|
||||
throw new Error('Step 4: answer was ' + dhGen._)
|
||||
throw new MtTypeAssertionError(
|
||||
'auth step 4',
|
||||
'set_client_DH_params_answer',
|
||||
dhGen._,
|
||||
)
|
||||
}
|
||||
|
||||
if (!buffersEqual(dhGen.nonce, nonce)) {
|
||||
|
@ -502,7 +511,11 @@ export async function doAuthorization(
|
|||
|
||||
if (dhGen._ === 'mt_dh_gen_fail') {
|
||||
// in theory i would be supposed to calculate newNonceHash, but why, we are failing anyway
|
||||
throw new Error('Step 4: server DH returned failure')
|
||||
throw new MtTypeAssertionError(
|
||||
'auth step 4',
|
||||
'!mt_dh_gen_fail',
|
||||
dhGen._,
|
||||
)
|
||||
}
|
||||
|
||||
if (dhGen._ === 'mt_dh_gen_retry') {
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
TlWriterMap,
|
||||
} from '@mtcute/tl-runtime'
|
||||
|
||||
import { MtcuteError } from '../types'
|
||||
import {
|
||||
ControllablePromise,
|
||||
Deque,
|
||||
|
@ -183,7 +184,7 @@ export class MtprotoSession {
|
|||
if (!keepPending) {
|
||||
for (const info of this.pendingMessages.values()) {
|
||||
if (info._ === 'rpc') {
|
||||
info.rpc.promise.reject(new Error('Session is reset'))
|
||||
info.rpc.promise.reject(new MtcuteError('Session is reset'))
|
||||
}
|
||||
}
|
||||
this.pendingMessages.clear()
|
||||
|
@ -197,7 +198,7 @@ export class MtprotoSession {
|
|||
const rpc = this.queuedRpc.popFront()!
|
||||
|
||||
if (rpc.sent === false) {
|
||||
rpc.promise.reject(new Error('Session is reset'))
|
||||
rpc.promise.reject(new MtcuteError('Session is reset'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,7 +265,7 @@ export class MtprotoSession {
|
|||
data: Buffer,
|
||||
callback: Parameters<AuthKey['decryptMessage']>[2],
|
||||
): Promise<void> {
|
||||
if (!this._authKey.ready) throw new Error('Keys are not set up!')
|
||||
if (!this._authKey.ready) throw new MtcuteError('Keys are not set up!')
|
||||
|
||||
const authKeyId = data.slice(0, 8)
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@ import { tl } from '@mtcute/tl'
|
|||
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { ITelegramStorage } from '../storage'
|
||||
import { MtArgumentError, MtcuteError } from '../types'
|
||||
import {
|
||||
createControllablePromise,
|
||||
ICryptoProvider,
|
||||
Logger,
|
||||
sleep,
|
||||
} from '../utils'
|
||||
import { assertTypeIs } from '../utils/type-assertions'
|
||||
import { ConfigManager } from './config-manager'
|
||||
import { MultiSessionConnection } from './multi-session-connection'
|
||||
import { PersistentConnectionParams } from './persistent-connection'
|
||||
|
@ -500,7 +502,7 @@ export class NetworkManager {
|
|||
})
|
||||
|
||||
if (!main || !media) {
|
||||
throw new Error(`Could not find DC ${dcId}`)
|
||||
throw new MtArgumentError(`Could not find DC ${dcId}`)
|
||||
}
|
||||
|
||||
return { main, media }
|
||||
|
@ -586,12 +588,12 @@ export class NetworkManager {
|
|||
*/
|
||||
async connect(defaultDcs: ITelegramStorage.DcOptions): Promise<void> {
|
||||
if (defaultDcs.main.id !== defaultDcs.media.id) {
|
||||
throw new Error('Default DCs must be the same')
|
||||
throw new MtArgumentError('Default DCs must be the same')
|
||||
}
|
||||
|
||||
if (this._dcConnections.has(defaultDcs.main.id)) {
|
||||
// shouldn't happen
|
||||
throw new Error('DC manager already exists')
|
||||
throw new MtArgumentError('DC manager already exists')
|
||||
}
|
||||
|
||||
const dc = new DcConnectionManager(this, defaultDcs.main.id, defaultDcs)
|
||||
|
@ -626,11 +628,7 @@ export class NetworkManager {
|
|||
{ manager },
|
||||
)
|
||||
|
||||
if (res._ !== 'auth.authorization') {
|
||||
throw new Error(
|
||||
`Unexpected response from auth.importAuthorization: ${res._}`,
|
||||
)
|
||||
}
|
||||
assertTypeIs('auth.importAuthorization', res, 'auth.authorization')
|
||||
|
||||
promise.resolve()
|
||||
delete this._pendingExports[manager.dcId]
|
||||
|
@ -713,7 +711,7 @@ export class NetworkManager {
|
|||
stack?: string,
|
||||
): Promise<tl.RpcCallReturn[T['_']]> {
|
||||
if (!this._primaryDc) {
|
||||
throw new Error('Not connected to any DC')
|
||||
throw new MtcuteError('Not connected to any DC')
|
||||
}
|
||||
|
||||
const floodSleepThreshold =
|
||||
|
@ -860,7 +858,7 @@ export class NetworkManager {
|
|||
|
||||
if (!dc) {
|
||||
if (!this._primaryDc) {
|
||||
throw new Error('Not connected to any DC')
|
||||
throw new MtcuteError('Not connected to any DC')
|
||||
}
|
||||
|
||||
// guess based on the provided delegate. it is most likely correct,
|
||||
|
@ -876,7 +874,7 @@ export class NetworkManager {
|
|||
}
|
||||
|
||||
getPrimaryDcId() {
|
||||
if (!this._primaryDc) throw new Error('Not connected to any DC')
|
||||
if (!this._primaryDc) throw new MtcuteError('Not connected to any DC')
|
||||
|
||||
return this._primaryDc.dcId
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import EventEmitter from 'events'
|
|||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtcuteError } from '../types'
|
||||
import { ICryptoProvider, Logger } from '../utils'
|
||||
import { ReconnectionStrategy } from './reconnection'
|
||||
import {
|
||||
|
@ -166,9 +167,9 @@ export abstract class PersistentConnection extends EventEmitter {
|
|||
|
||||
connect(): void {
|
||||
if (this.isConnected) {
|
||||
throw new Error('Connection is already opened!')
|
||||
throw new MtcuteError('Connection is already opened!')
|
||||
}
|
||||
if (this._destroyed) throw new Error('Connection is already destroyed!')
|
||||
if (this._destroyed) { throw new MtcuteError('Connection is already destroyed!') }
|
||||
|
||||
if (this._reconnectionTimeout != null) {
|
||||
clearTimeout(this._reconnectionTimeout)
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
} from '@mtcute/tl-runtime'
|
||||
import { gzipDeflate, gzipInflate } from '@mtcute/tl-runtime/src/platform/gzip'
|
||||
|
||||
import { MtArgumentError, MtcuteError, MtTimeoutError } from '../types'
|
||||
import {
|
||||
ControllablePromise,
|
||||
createCancellablePromise,
|
||||
|
@ -123,7 +124,7 @@ export class SessionConnection extends PersistentConnection {
|
|||
|
||||
Object.values(this._pendingWaitForUnencrypted).forEach(
|
||||
([prom, timeout]) => {
|
||||
prom.reject(new Error('Connection closed'))
|
||||
prom.reject(new MtcuteError('Connection closed'))
|
||||
clearTimeout(timeout)
|
||||
},
|
||||
)
|
||||
|
@ -456,7 +457,7 @@ export class SessionConnection extends PersistentConnection {
|
|||
res.errorCode,
|
||||
res.errorMessage,
|
||||
)
|
||||
throw new Error('Failed to bind temporary key')
|
||||
throw new MtcuteError('Failed to bind temporary key')
|
||||
}
|
||||
|
||||
// now we can swap the keys (secondary becomes primary,
|
||||
|
@ -506,7 +507,7 @@ export class SessionConnection extends PersistentConnection {
|
|||
waitForUnencryptedMessage(timeout = 5000): Promise<Buffer> {
|
||||
const promise = createControllablePromise<Buffer>()
|
||||
const timeoutId = setTimeout(() => {
|
||||
promise.reject(new Error('Timeout'))
|
||||
promise.reject(new MtTimeoutError(timeout))
|
||||
this._pendingWaitForUnencrypted =
|
||||
this._pendingWaitForUnencrypted.filter(
|
||||
(it) => it[0] !== promise,
|
||||
|
@ -1453,7 +1454,9 @@ export class SessionConnection extends PersistentConnection {
|
|||
// and since we resend them, it will get resent after reconnection and
|
||||
// that will be an endless loop of reconnections. we don't want that,
|
||||
// and payloads this large are usually a sign of an error in the code.
|
||||
throw new Error(`Payload is too big (${content.length} > 1044404)`)
|
||||
throw new MtArgumentError(
|
||||
`Payload is too big (${content.length} > 1044404)`,
|
||||
)
|
||||
}
|
||||
|
||||
// gzip
|
||||
|
@ -1533,7 +1536,7 @@ export class SessionConnection extends PersistentConnection {
|
|||
|
||||
private _cancelRpc(rpc: PendingRpc, onTimeout = false): void {
|
||||
if (rpc.cancelled && !onTimeout) {
|
||||
throw new Error('RPC was already cancelled')
|
||||
throw new MtcuteError('RPC was already cancelled')
|
||||
}
|
||||
|
||||
if (!onTimeout && rpc.timeout) {
|
||||
|
|
|
@ -3,6 +3,7 @@ import { connect, Socket } from 'net'
|
|||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtcuteError } from '../../types'
|
||||
import { ICryptoProvider, Logger } from '../../utils'
|
||||
import { IPacketCodec, ITelegramTransport, TransportState } from './abstract'
|
||||
import { IntermediatePacketCodec } from './intermediate'
|
||||
|
@ -49,7 +50,7 @@ export abstract class BaseTcpTransport
|
|||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
connect(dc: tl.RawDcOption, testMode: boolean): void {
|
||||
if (this._state !== TransportState.Idle) {
|
||||
throw new Error('Transport is not IDLE')
|
||||
throw new MtcuteError('Transport is not IDLE')
|
||||
}
|
||||
|
||||
if (!this.packetCodecInitialized) {
|
||||
|
@ -125,7 +126,7 @@ export abstract class BaseTcpTransport
|
|||
|
||||
async send(bytes: Buffer): Promise<void> {
|
||||
if (this._state !== TransportState.Ready) {
|
||||
throw new Error('Transport is not READY')
|
||||
throw new MtcuteError('Transport is not READY')
|
||||
}
|
||||
|
||||
const framed = await this._packetCodec.encode(bytes)
|
||||
|
|
|
@ -2,6 +2,7 @@ import EventEmitter from 'events'
|
|||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtcuteError, MtUnsupportedError } from '../../types'
|
||||
import { ICryptoProvider, Logger, typedArrayToBuffer } from '../../utils'
|
||||
import { IPacketCodec, ITelegramTransport, TransportState } from './abstract'
|
||||
import { IntermediatePacketCodec } from './intermediate'
|
||||
|
@ -57,7 +58,7 @@ export abstract class BaseWebSocketTransport
|
|||
super()
|
||||
|
||||
if (!ws) {
|
||||
throw new Error(
|
||||
throw new MtUnsupportedError(
|
||||
'To use WebSocket transport with NodeJS, install `ws` package.',
|
||||
)
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ export abstract class BaseWebSocketTransport
|
|||
|
||||
connect(dc: tl.RawDcOption, testMode: boolean): void {
|
||||
if (this._state !== TransportState.Idle) {
|
||||
throw new Error('Transport is not IDLE')
|
||||
throw new MtcuteError('Transport is not IDLE')
|
||||
}
|
||||
|
||||
if (!this.packetCodecInitialized) {
|
||||
|
@ -164,7 +165,7 @@ export abstract class BaseWebSocketTransport
|
|||
|
||||
async send(bytes: Buffer): Promise<void> {
|
||||
if (this._state !== TransportState.Ready) {
|
||||
throw new Error('Transport is not READY')
|
||||
throw new MtcuteError('Transport is not READY')
|
||||
}
|
||||
|
||||
const framed = await this._packetCodec.encode(bytes)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import type * as exitHookNs from 'exit-hook'
|
||||
import type * as fsNs from 'fs'
|
||||
|
||||
import { MtUnsupportedError } from '../types'
|
||||
import { JsonMemoryStorage } from './json'
|
||||
|
||||
type fs = typeof fsNs
|
||||
|
@ -52,7 +53,7 @@ export class JsonFileStorage extends JsonMemoryStorage {
|
|||
super()
|
||||
|
||||
if (!fs || !fs.readFile) {
|
||||
throw new Error('Node fs module is not available!')
|
||||
throw new MtUnsupportedError('Node fs module is not available!')
|
||||
}
|
||||
|
||||
this._filename = filename
|
||||
|
@ -60,7 +61,7 @@ export class JsonFileStorage extends JsonMemoryStorage {
|
|||
this._cleanup = params?.cleanup ?? Boolean(exitHook)
|
||||
|
||||
if (this._cleanup && !exitHook) {
|
||||
throw new Error(
|
||||
throw new MtUnsupportedError(
|
||||
'Cleanup on exit is supported through `exit-hook` library, install it first!',
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { MtUnsupportedError } from '../types'
|
||||
import { JsonMemoryStorage } from './json'
|
||||
|
||||
export class LocalstorageStorage extends JsonMemoryStorage {
|
||||
|
@ -7,7 +8,7 @@ export class LocalstorageStorage extends JsonMemoryStorage {
|
|||
super()
|
||||
|
||||
if (typeof localStorage === 'undefined') {
|
||||
throw new Error('localStorage is not available!')
|
||||
throw new MtUnsupportedError('localStorage is not available!')
|
||||
}
|
||||
|
||||
this._key = key
|
||||
|
|
|
@ -151,7 +151,9 @@ export class MemoryStorage implements ITelegramStorage, IStateStorage {
|
|||
(ent: ITelegramStorage.PeerInfo) => {
|
||||
if (ent.phone) obj.phoneIndex.set(ent.phone, ent.id)
|
||||
|
||||
if (ent.username) { obj.usernameIndex.set(ent.username, ent.id) }
|
||||
if (ent.username) {
|
||||
obj.usernameIndex.set(ent.username, ent.id)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -291,8 +293,6 @@ export class MemoryStorage implements ITelegramStorage, IStateStorage {
|
|||
accessHash: peerInfo.accessHash,
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Invalid peer type: ${peerInfo.type}`)
|
||||
}
|
||||
|
||||
getPeerById(peerId: number): tl.TypeInputPeer | null {
|
||||
|
|
65
packages/core/src/types/errors.ts
Normal file
65
packages/core/src/types/errors.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* Base class for all mtcute errors
|
||||
*/
|
||||
export class MtcuteError extends Error {}
|
||||
|
||||
/**
|
||||
* Method invocation was invalid because some argument
|
||||
* passed was invalid.
|
||||
*/
|
||||
export class MtArgumentError extends MtcuteError {}
|
||||
|
||||
/**
|
||||
* Something isn't right with security of the connection.
|
||||
*/
|
||||
export class MtSecurityError extends MtcuteError {}
|
||||
|
||||
/**
|
||||
* Either you requested or the server returned something
|
||||
* that is not (yet) supported.
|
||||
*
|
||||
* Stay tuned for future updates!
|
||||
*
|
||||
* In some cases, this error may mean that you are missing some
|
||||
* optional peer dependencies, or that the feature is not supported
|
||||
* in the current environment.
|
||||
*/
|
||||
export class MtUnsupportedError extends MtcuteError {}
|
||||
|
||||
/**
|
||||
* Server returned something of an unexpected type.
|
||||
*
|
||||
* This is usually a problem on library side.
|
||||
* Feel free to open an issue about this!
|
||||
*/
|
||||
export class MtTypeAssertionError extends MtcuteError {
|
||||
/**
|
||||
* Context at which the error occurred.
|
||||
* Usually a user-friendly string containing name
|
||||
* of the high-level API method, name of the TL
|
||||
* RPC method, and path of the entity,
|
||||
* like this: `signIn (@ auth.signIn -> user)`
|
||||
*/
|
||||
context: string
|
||||
|
||||
/** Expected TL type */
|
||||
expected: string
|
||||
|
||||
/** Actual TL type */
|
||||
actual: string
|
||||
|
||||
constructor(context: string, expected: string, actual: string) {
|
||||
super(
|
||||
`Type assertion error at ${context}: expected ${expected}, but got ${actual}`,
|
||||
)
|
||||
this.context = context
|
||||
this.expected = expected
|
||||
this.actual = actual
|
||||
}
|
||||
}
|
||||
|
||||
export class MtTimeoutError extends MtcuteError {
|
||||
constructor(readonly timeout?: number) {
|
||||
super(`Request timed out${timeout ? ` after ${timeout}ms` : ''}`)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue