feat(core): simplify importSession interface

This commit is contained in:
alina 🌸 2024-12-04 18:00:46 +03:00
parent a07b6673dc
commit 4a7479561b
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
7 changed files with 60 additions and 50 deletions

View file

@ -74,18 +74,14 @@ export default antfu({
'jsdoc/check-param-names': 'off', // todo: will fix in another iteration 'jsdoc/check-param-names': 'off', // todo: will fix in another iteration
'jsdoc/require-returns-description': 'off', // todo: will fix in another iteration 'jsdoc/require-returns-description': 'off', // todo: will fix in another iteration
'ts/no-unsafe-member-access': 'off', 'ts/no-unsafe-member-access': 'off',
'ts/no-dynamic-delete': 'off',
'ts/strict-boolean-expressions': 'off',
'ts/unbound-method': 'off', 'ts/unbound-method': 'off',
'ts/no-invalid-void-type': 'off', 'ts/strict-boolean-expressions': 'off',
'ts/no-unsafe-enum-comparison': 'off',
'ts/promise-function-async': 'off', 'ts/promise-function-async': 'off',
'dot-notation': 'off', 'dot-notation': 'off',
'ts/dot-notation': 'off', 'ts/dot-notation': 'off',
'ts/switch-exhaustiveness-check': 'off', 'ts/switch-exhaustiveness-check': 'off',
'ts/restrict-template-expressions': 'off', 'ts/restrict-template-expressions': 'off',
'ts/method-signature-style': 'off', 'ts/method-signature-style': 'off',
'style/indent-binary-ops': 'off',
'antfu/no-top-level-await': 'off', 'antfu/no-top-level-await': 'off',
'import/extensions': ['error', 'always', { 'import/extensions': ['error', 'always', {
ignorePackages: true, ignorePackages: true,

View file

@ -8,8 +8,8 @@ import type { ICorePlatform } from '../types/platform.js'
import type { MustEqual } from '../types/utils.js' import type { MustEqual } from '../types/utils.js'
import type { import type {
ICryptoProvider, ICryptoProvider,
InputStringSessionData,
Logger, Logger,
StringSessionData,
} from '../utils/index.js' } from '../utils/index.js'
import type { ConnectionState, ITelegramClient } from './client.types.js' import type { ConnectionState, ITelegramClient } from './client.types.js'
import type { ITelegramStorageProvider } from './storage/provider.js' import type { ITelegramStorageProvider } from './storage/provider.js'
@ -234,14 +234,14 @@ export class BaseTelegramClient implements ITelegramClient {
* @param session Session string to import * @param session Session string to import
* @param force Whether to overwrite existing session * @param force Whether to overwrite existing session
*/ */
async importSession(session: string | StringSessionData, force = false): Promise<void> { async importSession(session: string | InputStringSessionData, force = false): Promise<void> {
await this.prepare() await this.prepare()
const defaultDcAuthKey = await this.mt.storage.provider.authKeys.get(this.mt._defaultDcs.main.id) const defaultDcAuthKey = await this.mt.storage.provider.authKeys.get(this.mt._defaultDcs.main.id)
if (defaultDcAuthKey && !force) return if (defaultDcAuthKey && !force) return
const data = typeof session === 'string' ? readStringSession(session) : session const data = readStringSession(session)
const testMode = data.primaryDcs.main.testMode const testMode = data.primaryDcs.main.testMode
if (testMode && !this.params.testMode) { if (testMode && !this.params.testMode) {

View file

@ -3,11 +3,9 @@ import type { tdFileId } from '@mtcute/file-id'
import type { tl } from '@mtcute/tl' import type { tl } from '@mtcute/tl'
import type Long from 'long' import type Long from 'long'
import type { RpcCallOptions } from '../network/index.js' import type { RpcCallOptions } from '../network/index.js'
import type { MaybeArray, MaybePromise, PartialExcept, PartialOnly } from '../types/index.js' import type { MaybeArray, MaybePromise, PartialExcept, PartialOnly } from '../types/index.js'
import type { BaseTelegramClientOptions } from './base.js' import type { BaseTelegramClientOptions } from './base.js'
import type { ITelegramClient } from './client.types.js' import type { ITelegramClient } from './client.types.js'
import type { LogOutResult } from './methods/auth/log-out.js' import type { LogOutResult } from './methods/auth/log-out.js'
import type { CreateGroupResult } from './methods/chats/create-group.js' import type { CreateGroupResult } from './methods/chats/create-group.js'
import type { GetForumTopicsOffset } from './methods/forums/get-forum-topics.js' import type { GetForumTopicsOffset } from './methods/forums/get-forum-topics.js'
@ -29,7 +27,7 @@ import type { ITelegramStorageProvider } from './storage/provider.js'
import type { AllStories, ArrayPaginated, ArrayWithTotal, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputFileLike, InputInlineResult, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, PeerReaction, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SentCode, StarGift, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStarGift, UserStatusUpdate, UserTypingUpdate, WebviewResult } from './types/index.js' import type { AllStories, ArrayPaginated, ArrayWithTotal, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputFileLike, InputInlineResult, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, PeerReaction, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SentCode, StarGift, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStarGift, UserStatusUpdate, UserTypingUpdate, WebviewResult } from './types/index.js'
import type { ParsedUpdateHandlerParams } from './updates/parsed.js' import type { ParsedUpdateHandlerParams } from './updates/parsed.js'
import type { RawUpdateInfo } from './updates/types.js' import type { RawUpdateInfo } from './updates/types.js'
import type { StringSessionData } from './utils/string-session.js' import type { InputStringSessionData } from './utils/string-session.js'
/* THIS FILE WAS AUTO-GENERATED */ /* THIS FILE WAS AUTO-GENERATED */
import { Emitter } from '@fuman/utils' import { Emitter } from '@fuman/utils'
import { MtUnsupportedError } from '../types/index.js' import { MtUnsupportedError } from '../types/index.js'
@ -620,7 +618,7 @@ export interface TelegramClient extends ITelegramClient {
* Note that passed session will be ignored in case storage already * Note that passed session will be ignored in case storage already
* contains authorization. * contains authorization.
*/ */
session?: string | StringSessionData session?: string | InputStringSessionData
/** /**
* Whether to overwrite existing session. * Whether to overwrite existing session.
@ -1059,12 +1057,12 @@ export interface TelegramClient extends ITelegramClient {
* - `unigram` - Unigram * - `unigram` - Unigram
*/ */
platform: platform:
| 'android' | 'android'
| 'ios' | 'ios'
| 'tdesktop' | 'tdesktop'
| 'macos' | 'macos'
| 'unigram' | 'unigram'
| (string & {}) | (string & {})
}): Promise<WebviewResult> }): Promise<WebviewResult>
/** /**
* Close a webview previously opened by {@link openWebview} method. * Close a webview previously opened by {@link openWebview} method.
@ -2448,7 +2446,7 @@ export interface TelegramClient extends ITelegramClient {
location: FileDownloadLocation, location: FileDownloadLocation,
params?: FileDownloadParameters): import('node:stream').Readable params?: FileDownloadParameters): import('node:stream').Readable
/** /**
* Download a file and return it as a readable stream, * Download a file and return it as a `@fuman/io` stream,
* streaming file contents. * streaming file contents.
* *
* **Available**: both users and bots * **Available**: both users and bots
@ -3362,13 +3360,13 @@ export interface TelegramClient extends ITelegramClient {
*/ */
getCallbackQueryMessage( getCallbackQueryMessage(
id: id:
| CallbackQuery | CallbackQuery
| tl.RawUpdateBotCallbackQuery | tl.RawUpdateBotCallbackQuery
| { | {
messageId: number messageId: number
queryId: tl.Long queryId: tl.Long
peer: InputPeerLike peer: InputPeerLike
}): Promise<Message | null> }): Promise<Message | null>
// public version of the same method because why not // public version of the same method because why not
/** /**
* Get discussion message for some channel post. * Get discussion message for some channel post.
@ -4040,14 +4038,14 @@ export interface TelegramClient extends ITelegramClient {
*/ */
sendCopyGroup( sendCopyGroup(
params: SendCopyGroupParams & params: SendCopyGroupParams &
( (
| { | {
/** Source chat ID */ /** Source chat ID */
fromChatId: InputPeerLike fromChatId: InputPeerLike
/** Message IDs to forward */ /** Message IDs to forward */
messages: number[] messages: number[]
} }
| { messages: Message[] } | { messages: Message[] }
)): Promise<Message[]> )): Promise<Message[]>
/** /**
* Copy a message (i.e. send the same message, but do not forward it). * Copy a message (i.e. send the same message, but do not forward it).
@ -4061,14 +4059,14 @@ export interface TelegramClient extends ITelegramClient {
*/ */
sendCopy( sendCopy(
params: SendCopyParams & params: SendCopyParams &
( (
| { | {
/** Source chat ID */ /** Source chat ID */
fromChatId: InputPeerLike fromChatId: InputPeerLike
/** Message ID to forward */ /** Message ID to forward */
message: number message: number
} }
| { message: Message } | { message: Message }
)): Promise<Message> )): Promise<Message>
/** /**
* Send a group of media. * Send a group of media.

View file

@ -11,7 +11,7 @@ import type { AppConfigManager } from './managers/app-config-manager.js'
import type { TimersManager } from './managers/timers.js' import type { TimersManager } from './managers/timers.js'
import type { TelegramStorageManager } from './storage/storage.js' import type { TelegramStorageManager } from './storage/storage.js'
import type { RawUpdateInfo } from './updates/types.js' import type { RawUpdateInfo } from './updates/types.js'
import type { StringSessionData } from './utils/string-session.js' import type { InputStringSessionData } from './utils/string-session.js'
/** /**
* Connection state of the client * Connection state of the client
@ -52,7 +52,7 @@ export interface ITelegramClient {
message: MustEqual<T, tl.RpcMethod>, message: MustEqual<T, tl.RpcMethod>,
params?: RpcCallOptions, params?: RpcCallOptions,
): Promise<tl.RpcCallReturn[T['_']]> ): Promise<tl.RpcCallReturn[T['_']]>
importSession(session: string | StringSessionData, force?: boolean): Promise<void> importSession(session: string | InputStringSessionData, force?: boolean): Promise<void>
exportSession(): Promise<string> exportSession(): Promise<string>
handleClientUpdate(updates: tl.TypeUpdates, noDispatch?: boolean): void handleClientUpdate(updates: tl.TypeUpdates, noDispatch?: boolean): void

View file

@ -115,4 +115,4 @@ import {
// @copy // @copy
import { RawUpdateInfo } from '../updates/types.js' import { RawUpdateInfo } from '../updates/types.js'
// @copy // @copy
import { StringSessionData } from '../utils/string-session.js' import { InputStringSessionData } from '../utils/string-session.js'

View file

@ -5,12 +5,12 @@ import type { ITelegramClient } from '../../client.types.js'
import type { SentCode } from '../../types/auth/sent-code.js' import type { SentCode } from '../../types/auth/sent-code.js'
import type { User } from '../../types/peers/user.js' import type { User } from '../../types/peers/user.js'
import type { MaybeDynamic } from '../../types/utils.js' import type { MaybeDynamic } from '../../types/utils.js'
import type { StringSessionData } from '../../utils/string-session.js' import type { InputStringSessionData } from '../../utils/string-session.js'
import { tl } from '@mtcute/tl' import { tl } from '@mtcute/tl'
import { MtArgumentError, MtcuteError } from '../../../types/errors.js' import { MtArgumentError, MtcuteError } from '../../../types/errors.js'
import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils.js' import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils.js'
import { getMe } from '../users/get-me.js'
import { getMe } from '../users/get-me.js'
import { checkPassword } from './check-password.js' import { checkPassword } from './check-password.js'
import { resendCode } from './resend-code.js' import { resendCode } from './resend-code.js'
import { sendCode } from './send-code.js' import { sendCode } from './send-code.js'
@ -43,7 +43,7 @@ export async function start(
* Note that passed session will be ignored in case storage already * Note that passed session will be ignored in case storage already
* contains authorization. * contains authorization.
*/ */
session?: string | StringSessionData session?: string | InputStringSessionData
/** /**
* Whether to overwrite existing session. * Whether to overwrite existing session.

View file

@ -4,7 +4,14 @@ import type { CurrentUserInfo } from '../storage/service/current-user.js'
import { base64 } from '@fuman/utils' import { base64 } from '@fuman/utils'
import { TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime' import { TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime'
import { MtArgumentError } from '../../types/index.js' import { MtArgumentError } from '../../types/index.js'
import { parseBasicDcOption, serializeBasicDcOption } from '../../utils/dcs.js' import { defaultProductionDc, defaultTestDc, parseBasicDcOption, serializeBasicDcOption } from '../../utils/dcs.js'
export interface InputStringSessionData {
primaryDcs?: DcOptions
testMode?: boolean
self?: CurrentUserInfo | null
authKey: Uint8Array
}
export interface StringSessionData { export interface StringSessionData {
version: number version: number
@ -77,7 +84,16 @@ export function writeStringSession(data: StringSessionData): string {
return base64.encode(writer.result(), true) return base64.encode(writer.result(), true)
} }
export function readStringSession(data: string): StringSessionData { export function readStringSession(data: string | InputStringSessionData): StringSessionData {
if (typeof data !== 'string') {
return {
version: 3,
primaryDcs: data.primaryDcs ?? (data.testMode ? defaultTestDc : defaultProductionDc),
self: data.self ?? null,
authKey: data.authKey,
}
}
const buf = base64.decode(data, true) const buf = base64.decode(data, true)
const version = buf[0] const version = buf[0]