refactor: moved makeInspectable to utils, also fixed ArrayWithTotal

This commit is contained in:
alina 🌸 2023-09-25 14:48:32 +03:00
parent dbcd3f0911
commit 59ac74f300
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
56 changed files with 146 additions and 134 deletions

View file

@ -5,6 +5,7 @@ import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types'
import { makeArrayWithTotal } from '../../utils'
import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils'
/**
@ -131,9 +132,8 @@ export async function getChatMembers(
const peers = PeersIndex.from(res)
const ret = res.participants.map((i) => new ChatMember(this, i, peers)) as ArrayWithTotal<ChatMember>
ret.total = res.count
return ret
return makeArrayWithTotal(ret, res.count)
}
throw new MtInvalidPeerTypeError(chatId, 'chat or channel')

View file

@ -1,6 +1,6 @@
import { tl } from '@mtcute/core'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
const sentCodeMap: Record<tl.auth.TypeSentCodeType['_'], SentCodeDeliveryType> = {
'auth.sentCodeTypeApp': 'app',

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { isPresent } from '@mtcute/core/utils'
import { makeInspectable } from '../../utils'
import { MessageEntity } from '../messages'
import { makeInspectable } from '../utils'
/**
* Telegram's Terms of Service returned by {@link TelegramClient.signIn}

View file

@ -1,11 +1,11 @@
import { BasicPeerType, getBasicPeerType, getMarkedPeerId, MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { encodeInlineMessageId } from '../../utils/inline-utils'
import { MtMessageNotFoundError } from '../errors'
import { Message } from '../messages'
import { PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
/**
* An incoming callback query, originated from a callback button

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
/**
* Game high score

View file

@ -1,9 +1,9 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Location } from '../media'
import { PeersIndex, PeerType, User } from '../peers'
import { makeInspectable } from '../utils'
import { InputInlineResult } from './input'
const PEER_TYPE_MAP: Record<tl.TypeInlineQueryPeerType['_'], PeerType> = {

View file

@ -3,7 +3,7 @@ import { Readable } from 'stream'
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { FileDownloadParameters } from './utils'
/**

View file

@ -1,7 +1,7 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { FileLocation } from './file-location'
const STUB_LOCATION = () => {

View file

@ -10,4 +10,4 @@ export * from './misc'
export * from './parser'
export * from './peers'
export * from './updates'
export { ArrayWithTotal, MaybeDynamic } from './utils'
export * from './utils'

View file

@ -2,7 +2,7 @@ import { tl } from '@mtcute/core'
import { tdFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { RawDocument } from './document'
/**

View file

@ -1,6 +1,6 @@
import { tl } from '@mtcute/core'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
/**
* A phone contact

View file

@ -1,6 +1,6 @@
import { tl } from '@mtcute/core'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
/**
* A dice or another interactive random emoji.

View file

@ -2,8 +2,8 @@ import { tl } from '@mtcute/core'
import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { FileLocation } from '../files'
import { makeInspectable } from '../utils'
import { Thumbnail } from './thumbnail'
/**

View file

@ -1,7 +1,7 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { Photo } from './photo'
import { Video } from './video'

View file

@ -1,9 +1,9 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { WebDocument } from '../files/web-document'
import { _messageMediaFromTl, MessageMedia } from '../messages'
import { makeInspectable } from '../utils'
import { Thumbnail } from './thumbnail'
/**

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { FileLocation } from '../files'
import { makeInspectable } from '../utils'
/**
* A point on the map

View file

@ -1,8 +1,8 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { FileLocation } from '../files'
import { makeInspectable } from '../utils'
import { Thumbnail } from './thumbnail'
/**

View file

@ -3,9 +3,9 @@ import Long from 'long'
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { MessageEntity } from '../messages'
import { PeersIndex } from '../peers'
import { makeInspectable } from '../utils'
export interface PollAnswer {
/**

View file

@ -2,8 +2,8 @@ import { MtArgumentError, tl } from '@mtcute/core'
import { tdFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { StickerSet } from '../misc'
import { makeInspectable } from '../utils'
import { RawDocument } from './document'
export interface MaskPosition {

View file

@ -5,9 +5,9 @@ import { assertTypeIs } from '@mtcute/core/utils'
import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { inflateSvgPath, strippedPhotoToJpg, svgPathToFile } from '../../utils/file-utils'
import { FileLocation } from '../files'
import { makeInspectable } from '../utils'
/**
* One size of some thumbnail

View file

@ -2,7 +2,7 @@ import { tl } from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { Location } from './location'
export interface VenueSource {

View file

@ -2,7 +2,7 @@ import { tl } from '@mtcute/core'
import { tdFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { RawDocument } from './document'
/**

View file

@ -2,8 +2,8 @@ import { tl } from '@mtcute/core'
import { tdFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { decodeWaveform } from '../../utils/voice-utils'
import { makeInspectable } from '../utils'
import { RawDocument } from './document'
/**

View file

@ -1,7 +1,7 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { RawDocument } from './document'
import { parseDocument } from './document-utils'
import { Photo } from './photo'

View file

@ -1,9 +1,9 @@
import { getMarkedPeerId, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { MtMessageNotFoundError } from '../errors'
import { Chat, PeersIndex } from '../peers'
import { makeInspectable } from '../utils'
import { DraftMessage } from './draft-message'
import { Message } from './message'

View file

@ -1,9 +1,9 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { InputMediaLike } from '../media'
import { InputPeerLike } from '../peers'
import { makeInspectable } from '../utils'
import { Message } from './message'
import { MessageEntity } from './message-entity'

View file

@ -1,6 +1,6 @@
import { tl } from '@mtcute/core'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
const entityToType: Partial<Record<tl.TypeMessageEntity['_'], MessageEntityType>> = {
messageEntityBlockquote: 'blockquote',

View file

@ -9,11 +9,11 @@ import {
import { assertTypeIsNot } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { BotKeyboard, ReplyMarkup } from '../bots'
import { InputMediaLike, Sticker, WebPage } from '../media'
import { FormattedString } from '../parser'
import { Chat, InputPeerLike, PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
import { _messageActionFromTl, MessageAction } from './message-action'
import { MessageEntity } from './message-entity'
import { _messageMediaFromTl, MessageMedia } from './message-media'

View file

@ -2,8 +2,8 @@ import { getMarkedPeerId, tl } from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
export class PeerReaction {
constructor(

View file

@ -2,11 +2,11 @@ import { MtTypeAssertionError, tl } from '@mtcute/core'
import { LongMap } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { MtEmptyError } from '../errors'
import { InputFileLike } from '../files'
import { MaskPosition, Sticker, StickerSourceType, StickerType, Thumbnail } from '../media'
import { parseDocument } from '../media/document-utils'
import { makeInspectable } from '../utils'
/**
* Information about one sticker inside the set

View file

@ -1,7 +1,7 @@
import { MustEqual, RpcCallOptions, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
/**
* Account takeout session

View file

@ -1,9 +1,9 @@
import { tl, toggleChannelIdMark } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Photo } from '../media'
import { Message } from '../messages'
import { makeInspectable } from '../utils'
import { ChatInviteLink } from './chat-invite-link'
import { ChatLocation } from './chat-location'
import { ChatMember } from './chat-member'

View file

@ -2,7 +2,7 @@ import { tl } from '@mtcute/core'
import { assertTypeIsNot } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { PeersIndex } from './index'
import { User } from './user'

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Location } from '../media'
import { makeInspectable } from '../utils'
/**
* Geolocation of a supergroup

View file

@ -2,7 +2,7 @@ import { tl } from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
import { ChatPermissions } from './chat-permissions'
import { PeersIndex } from './index'
import { User } from './user'

View file

@ -1,6 +1,6 @@
import { tl } from '@mtcute/core'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
/**
* Represents the permissions of a user in a {@link Chat}.

View file

@ -4,9 +4,9 @@ import { MtArgumentError, tl, toggleChannelIdMark } from '@mtcute/core'
import { tdFileId, toFileId, toUniqueFileId } from '@mtcute/file-id'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { strippedPhotoToJpg } from '../../utils/file-utils'
import { FileLocation } from '../files'
import { makeInspectable } from '../utils'
/**
* A size of a chat photo

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Photo } from '../media'
import { makeInspectable } from '../utils'
import { Chat } from './chat'
import { User } from './user'

View file

@ -1,9 +1,9 @@
import { getMarkedPeerId, MaybeArray, MtArgumentError, MtTypeAssertionError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { InputMediaLike } from '../media'
import { FormattedString } from '../parser'
import { makeInspectable } from '../utils'
import { ChatLocation } from './chat-location'
import { ChatPermissions } from './chat-permissions'
import { ChatPhoto } from './chat-photo'

View file

@ -2,9 +2,9 @@ import { MtArgumentError, tl } from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { InputMediaLike } from '../media'
import { FormattedString } from '../parser'
import { makeInspectable } from '../utils'
import { ChatPhoto } from './chat-photo'
/**

View file

@ -1,8 +1,8 @@
import { getBarePeerId, getMarkedPeerId, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Chat, ChatInviteLink, PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
/**
* This update is sent when a user requests to join a chat

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
/**
* A user has stopped or restarted the bot.

View file

@ -1,8 +1,8 @@
import { getBarePeerId, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { ChatInviteLinkJoinedMember, PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
/**
* This update is sent when a user requests to join a chat

View file

@ -3,8 +3,8 @@
import { getMarkedPeerId, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Chat, ChatInviteLink, ChatMember, PeersIndex, User } from '../'
import { makeInspectable } from '../utils'
// todo: check case when restricted user joins chat - MTQ-35
/**

View file

@ -1,9 +1,9 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { encodeInlineMessageId } from '../../utils/inline-utils'
import { Location, PeersIndex, User } from '../'
import { makeInspectable } from '../utils'
/**
* An inline result was chosen by the user and sent to some chat

View file

@ -1,7 +1,7 @@
import { tl, toggleChannelIdMark } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
/**
* One or more messages were deleted

View file

@ -1,7 +1,7 @@
import { getMarkedPeerId, tl, toggleChannelIdMark } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../utils'
import { makeInspectable } from '../../utils'
export class HistoryReadUpdate {
constructor(

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { PeersIndex, Poll } from '../'
import { makeInspectable } from '../utils'
/**
* Poll state has changed (stopped, somebody

View file

@ -2,8 +2,8 @@ import { MtUnsupportedError, tl } from '@mtcute/core'
import { assertTypeIs } from '@mtcute/core/utils'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Chat, PeersIndex, User } from '../'
import { makeInspectable } from '../utils'
/**
* Some user has voted in a public poll.

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { PeersIndex, User } from '../peers'
import { makeInspectable } from '../utils'
export class PreCheckoutQuery {
constructor(

View file

@ -1,8 +1,8 @@
import { tl } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { User, UserParsedStatus, UserStatus } from '../'
import { makeInspectable } from '../utils'
/**
* User status has changed

View file

@ -1,8 +1,8 @@
import { BasicPeerType, getBarePeerId, MtUnsupportedError, tl, toggleChannelIdMark } from '@mtcute/core'
import { TelegramClient } from '../../client'
import { makeInspectable } from '../../utils'
import { Chat, TypingStatus, User } from '../'
import { makeInspectable } from '../utils'
/**
* User's typing status has changed.

View file

@ -1,85 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-argument */
import { MaybeAsync } from '@mtcute/core'
export type MaybeDynamic<T> = MaybeAsync<T> | (() => MaybeAsync<T>)
export type ArrayWithTotal<T> = T[] & { total: number }
let util: typeof import('util') | null = null
try {
util = require('util') as typeof import('util')
} catch (e) {}
// get all property names. unlike Object.getOwnPropertyNames,
// also gets inherited property names
function getAllGettersNames(obj: object): string[] {
const getters: string[] = []
do {
Object.getOwnPropertyNames(obj).forEach((prop) => {
if (prop !== '__proto__' && Object.getOwnPropertyDescriptor(obj, prop)?.get && !getters.includes(prop)) {
getters.push(prop)
}
})
} while ((obj = Object.getPrototypeOf(obj)))
return getters
}
const bufferToJsonOriginal = Buffer.prototype.toJSON
const bufferToJsonInspect = function (this: Buffer) {
return this.toString('base64')
}
/**
* Small helper function that adds `toJSON` and `util.custom.inspect`
* methods to a given class based on its getters
*
* > **Note**: This means that all getters must be pure!
* > (getter that caches after its first invocation is also
* > considered pure in this case)
*/
export function makeInspectable(obj: new (...args: any[]) => any, props?: string[], hide?: string[]): void {
const getters: string[] = props ? props : []
for (const key of getAllGettersNames(obj.prototype)) {
if (!hide || !hide.includes(key)) getters.push(key)
}
// dirty hack to set name for inspect result
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const proto = new Function(`return function ${obj.name}(){}`)().prototype
obj.prototype.toJSON = function (nested = false) {
if (!nested) {
(Buffer as any).toJSON = bufferToJsonInspect
}
const ret: any = Object.create(proto)
getters.forEach((it) => {
try {
let val = this[it]
if (val && typeof val === 'object' && typeof val.toJSON === 'function') {
val = val.toJSON(true)
}
ret[it] = val
} catch (e: any) {
ret[it] = 'Error: ' + e.message
}
})
if (!nested) {
Buffer.prototype.toJSON = bufferToJsonOriginal
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return ret
}
if (util) {
obj.prototype[util.inspect.custom] = obj.prototype.toJSON
}
}

View file

@ -1,5 +1,6 @@
export * from './file-utils'
export * from './inline-utils'
export * from './inspectable'
export * from './misc-utils'
export * from './peer-utils'
export * from './rps-meter'

View file

@ -0,0 +1,80 @@
/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-argument */
let util: typeof import('util') | null = null
try {
util = require('util') as typeof import('util')
} catch (e) {}
// get all property names. unlike Object.getOwnPropertyNames,
// also gets inherited property names
function getAllGettersNames(obj: object): string[] {
const getters: string[] = []
do {
Object.getOwnPropertyNames(obj).forEach((prop) => {
if (prop !== '__proto__' && Object.getOwnPropertyDescriptor(obj, prop)?.get && !getters.includes(prop)) {
getters.push(prop)
}
})
} while ((obj = Object.getPrototypeOf(obj)))
return getters
}
const bufferToJsonOriginal = Buffer.prototype.toJSON
const bufferToJsonInspect = function (this: Buffer) {
return this.toString('base64')
}
/**
* Small helper function that adds `toJSON` and `util.custom.inspect`
* methods to a given class based on its getters
*
* > **Note**: This means that all getters must be pure!
* > (getter that caches after its first invocation is also
* > considered pure in this case)
*/
export function makeInspectable(obj: new (...args: any[]) => any, props?: string[], hide?: string[]): void {
const getters: string[] = props ? props : []
for (const key of getAllGettersNames(obj.prototype)) {
if (!hide || !hide.includes(key)) getters.push(key)
}
// dirty hack to set name for inspect result
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const proto = new Function(`return function ${obj.name}(){}`)().prototype
obj.prototype.toJSON = function (nested = false) {
if (!nested) {
(Buffer as any).toJSON = bufferToJsonInspect
}
const ret: any = Object.create(proto)
getters.forEach((it) => {
try {
let val = this[it]
if (val && typeof val === 'object' && typeof val.toJSON === 'function') {
val = val.toJSON(true)
}
ret[it] = val
} catch (e: any) {
ret[it] = 'Error: ' + e.message
}
})
if (!nested) {
Buffer.prototype.toJSON = bufferToJsonOriginal
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return ret
}
if (util) {
obj.prototype[util.inspect.custom] = obj.prototype.toJSON
}
}

View file

@ -1,6 +1,6 @@
import { MtArgumentError, tl } from '@mtcute/core'
import { MaybeDynamic, Message } from '../types'
import { ArrayWithTotal, MaybeDynamic, Message } from '../types'
/**
* Normalize phone number by stripping formatting
@ -17,6 +17,17 @@ export async function resolveMaybeDynamic<T>(val: MaybeDynamic<T>): Promise<T> {
return val instanceof Function ? await val() : await val
}
export function makeArrayWithTotal<T>(arr: T[], total: number): ArrayWithTotal<T> {
Object.defineProperty(arr, 'total', {
value: total,
enumerable: false,
configurable: false,
writable: false,
})
return arr as ArrayWithTotal<T>
}
export function extractChannelIdFromUpdate(upd: tl.TypeUpdate): number | undefined {
// holy shit
let res = 0