Compare commits

...

2 commits

Author SHA1 Message Date
93fe673d2e
feat(tl)!: updated to layer 198
All checks were successful
Tests / test-deno (push) Successful in 1m43s
Tests / test-bun (push) Successful in 1m51s
Tests / test-node (node18) (push) Successful in 2m1s
Tests / test-node (node20) (push) Successful in 2m1s
Tests / test-node (node22) (push) Successful in 2m0s
Tests / test-web (chromium) (push) Successful in 2m3s
Tests / test-web (firefox) (push) Successful in 2m13s
Build and deploy typedoc / build (push) Successful in 5m54s
Tests / lint (push) Successful in 6m36s
Tests / e2e (push) Successful in 50s
Tests / e2e-deno (push) Successful in 54s
2025-01-25 08:41:54 +03:00
9f4578dbef
feat(tl): compat schema generation 2025-01-25 08:41:54 +03:00
33 changed files with 694 additions and 55 deletions

View file

@ -24,7 +24,7 @@ import type { QuoteParamsFrom } from './methods/messages/send-quote.js'
import type { CanApplyBoostResult } from './methods/premium/can-apply-boost.js'
import type { CanSendStoryResult } from './methods/stories/can-send-story.js'
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, FullUser, 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, StarGiftUnique, 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, FullUser, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputFileLike, InputInlineResult, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStarGift, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, PeerReaction, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SavedStarGift, SentCode, StarGift, StarGiftUnique, 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 { RawUpdateInfo } from './updates/types.js'
import type { InputStringSessionData } from './utils/string-session.js'
@ -211,6 +211,7 @@ import { changeCloudPassword } from './methods/password/change-cloud-password.js
import { enableCloudPassword } from './methods/password/enable-cloud-password.js'
import { cancelPasswordEmail, resendPasswordEmail, verifyPasswordEmail } from './methods/password/password-email.js'
import { removeCloudPassword } from './methods/password/remove-cloud-password.js'
import { _normalizeInputStarGift } from './methods/premium/_normalize-input-star-gift.js'
import { acceptStarGift } from './methods/premium/accept-star-gift.js'
import { applyBoost } from './methods/premium/apply-boost.js'
import { canApplyBoost } from './methods/premium/can-apply-boost.js'
@ -221,11 +222,15 @@ import { getBoosts } from './methods/premium/get-boosts.js'
import { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
import { getBusinessConnection } from './methods/premium/get-business-connection.js'
import { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
import { getSavedStarGiftsById } from './methods/premium/get-saved-star-gifts-by-id.js'
import { getSavedStarGifts } from './methods/premium/get-saved-star-gifts.js'
import { getStarGiftOptions } from './methods/premium/get-star-gift-options.js'
import { getStarGiftWithdrawalUrl } from './methods/premium/get-star-gift-withdrawal-url.js'
import { getStarGifts } from './methods/premium/get-star-gifts.js'
import { getStarsTransactions } from './methods/premium/get-stars-transactions.js'
import { getUniqueStarGift } from './methods/premium/get-unique-star-gift.js'
import { iterBoosters } from './methods/premium/iter-boosters.js'
import { iterSavedStarGifts } from './methods/premium/iter-saved-star-gifts.js'
import { iterStarGifts } from './methods/premium/iter-star-gifts.js'
import { iterStarsTransactions } from './methods/premium/iter-stars-transactions.js'
import { sendStarGift } from './methods/premium/send-star-gift.js'
@ -4545,6 +4550,9 @@ export interface TelegramClient extends ITelegramClient {
*/
removeCloudPassword(password: string): Promise<void>
_normalizeInputStarGift(
gift: InputStarGift): Promise<tl.TypeInputSavedStarGift>
/**
* Accept, hide or convert a star gift.
*
@ -4554,8 +4562,9 @@ export interface TelegramClient extends ITelegramClient {
*/
acceptStarGift(
params: {
/** ID of the message containing the gift */
message: number | Message
/** Input star gift to accept */
gift: InputStarGift
/**
* Action to perform on the gift.
* - `save` - save the gift to your profile
@ -4681,6 +4690,34 @@ export interface TelegramClient extends ITelegramClient {
*
*/
getMyBoostSlots(): Promise<BoostSlot[]>
/** Get one or more saved star gifts by their IDs */
getSavedStarGiftsById(
gifts: MaybeArray<InputStarGift>): Promise<SavedStarGift[]>
/** Get a list of saved star gifts of a user */
getSavedStarGifts(
params: {
/** Peer to get saved gifts from */
owner: InputPeerLike
/** Whether to exclude hidden gifts */
excludeHidden?: boolean
/** Whether to exclude publicly visible gifts */
excludePublic?: boolean
/** Whether to exclude gifts with unlimited availability */
excludeUnlimited?: boolean
/** Whether to exclude gifts with limited availability */
excludeLimited?: boolean
/** Whether to exclude unique gifts */
excludeUnique?: boolean
/** Whether to sort by value */
sortByValue?: boolean
/** Offset for pagination */
offset?: string
/** Limit for pagination */
limit?: number
}): Promise<ArrayPaginated<SavedStarGift, string>>
/**
* Get the list of available star gifts.
@ -4689,6 +4726,15 @@ export interface TelegramClient extends ITelegramClient {
*/
getStarGiftOptions(): Promise<StarGift[]>
getStarGiftWithdrawalUrl(
params: {
/** The star gift to withdraw */
gift: InputStarGift
/** 2FA password */
password: string
}): Promise<string>
/**
* Get a list of gifts sent to a user.
*
@ -4777,6 +4823,34 @@ export interface TelegramClient extends ITelegramClient {
*/
chunkSize?: number
}): AsyncIterableIterator<Boost>
/**
* Iterate over saved star gifts of a user,
* wrapper over {@link getSavedStarGifts}
*/
iterSavedStarGifts(
params: {
/** Peer to get saved gifts from */
owner: InputPeerLike
/** Whether to exclude unsaved gifts */
excludeUnsaved?: boolean
/** Whether to exclude saved gifts */
excludeSaved?: boolean
/** Whether to exclude gifts with unlimited availability */
excludeUnlimited?: boolean
/** Whether to exclude gifts with limited availability */
excludeLimited?: boolean
/** Whether to exclude unique gifts */
excludeUnique?: boolean
/** Whether to sort by value */
sortByValue?: boolean
/** Offset for pagination */
offset?: string
/** Limit for pagination */
limit?: number
}): AsyncIterableIterator<SavedStarGift>
/**
* Iterate over gifts sent to a given user.
@ -4851,8 +4925,8 @@ export interface TelegramClient extends ITelegramClient {
*/
sendStarGift(
params: {
/** ID of the user to send the gift to */
userId: InputPeerLike
/** ID of the peer to send the gift to */
peerId: InputPeerLike
/** ID of the gift to send */
gift: Long | StarGift
@ -4939,8 +5013,8 @@ export interface TelegramClient extends ITelegramClient {
*/
transferStarGift(
params: {
/** ID of the message containing the gift */
message: number | Message
/** Star gift to transfer */
gift: InputStarGift
/** ID of the user to transfer the gift to */
recepient: InputPeerLike
@ -4965,8 +5039,7 @@ export interface TelegramClient extends ITelegramClient {
*/
upgradeStarGift(
params: {
/** ID of the message containing the gift */
message: number | Message
gift: InputStarGift
/**
* Whether to retain the original details of the gift
@ -5879,6 +5952,8 @@ export interface TelegramClient extends ITelegramClient {
peerId: InputPeerLike
/** Custom emoji ID or `null` to remove the emoji */
emoji: tl.Long | null
/** When true, `emoji` is the ID of the collectible emoji */
isCollectible?: boolean
/**
* Date when the emoji status should expire (only if `emoji` is not `null`)
*/
@ -6752,6 +6827,9 @@ TelegramClient.prototype.cancelPasswordEmail = function (...args) {
TelegramClient.prototype.removeCloudPassword = function (...args) {
return removeCloudPassword(this._client, ...args)
}
TelegramClient.prototype._normalizeInputStarGift = function (...args) {
return _normalizeInputStarGift(this._client, ...args)
}
TelegramClient.prototype.acceptStarGift = function (...args) {
return acceptStarGift(this._client, ...args)
}
@ -6785,9 +6863,18 @@ TelegramClient.prototype.getBusinessConnection = function (...args) {
TelegramClient.prototype.getMyBoostSlots = function (...args) {
return getMyBoostSlots(this._client, ...args)
}
TelegramClient.prototype.getSavedStarGiftsById = function (...args) {
return getSavedStarGiftsById(this._client, ...args)
}
TelegramClient.prototype.getSavedStarGifts = function (...args) {
return getSavedStarGifts(this._client, ...args)
}
TelegramClient.prototype.getStarGiftOptions = function (...args) {
return getStarGiftOptions(this._client, ...args)
}
TelegramClient.prototype.getStarGiftWithdrawalUrl = function (...args) {
return getStarGiftWithdrawalUrl(this._client, ...args)
}
TelegramClient.prototype.getStarGifts = function (...args) {
return getStarGifts(this._client, ...args)
}
@ -6800,6 +6887,9 @@ TelegramClient.prototype.getUniqueStarGift = function (...args) {
TelegramClient.prototype.iterBoosters = function (...args) {
return iterBoosters(this._client, ...args)
}
TelegramClient.prototype.iterSavedStarGifts = function (...args) {
return iterSavedStarGifts(this._client, ...args)
}
TelegramClient.prototype.iterStarGifts = function (...args) {
return iterStarGifts(this._client, ...args)
}

View file

@ -209,6 +209,7 @@ export { verifyPasswordEmail } from './methods/password/password-email.js'
export { resendPasswordEmail } from './methods/password/password-email.js'
export { cancelPasswordEmail } from './methods/password/password-email.js'
export { removeCloudPassword } from './methods/password/remove-cloud-password.js'
export { _normalizeInputStarGift } from './methods/premium/_normalize-input-star-gift.js'
export { acceptStarGift } from './methods/premium/accept-star-gift.js'
export { applyBoost } from './methods/premium/apply-boost.js'
export { canApplyBoost } from './methods/premium/can-apply-boost.js'
@ -221,11 +222,15 @@ export { getBoosts } from './methods/premium/get-boosts.js'
export { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
export { getBusinessConnection } from './methods/premium/get-business-connection.js'
export { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
export { getSavedStarGiftsById } from './methods/premium/get-saved-star-gifts-by-id.js'
export { getSavedStarGifts } from './methods/premium/get-saved-star-gifts.js'
export { getStarGiftOptions } from './methods/premium/get-star-gift-options.js'
export { getStarGiftWithdrawalUrl } from './methods/premium/get-star-gift-withdrawal-url.js'
export { getStarGifts } from './methods/premium/get-star-gifts.js'
export { getStarsTransactions } from './methods/premium/get-stars-transactions.js'
export { getUniqueStarGift } from './methods/premium/get-unique-star-gift.js'
export { iterBoosters } from './methods/premium/iter-boosters.js'
export { iterSavedStarGifts } from './methods/premium/iter-saved-star-gifts.js'
export { iterStarGifts } from './methods/premium/iter-star-gifts.js'
export { iterStarsTransactions } from './methods/premium/iter-stars-transactions.js'
export { sendStarGift } from './methods/premium/send-star-gift.js'

View file

@ -67,6 +67,7 @@ import {
InputPeerLike,
InputPrivacyRule,
InputReaction,
InputStarGift,
InputStickerSet,
InputStickerSetItem,
InputText,
@ -88,6 +89,7 @@ import {
PreCheckoutQuery,
RawDocument,
ReplyMarkup,
SavedStarGift,
SentCode,
StarGift,
StarGiftUnique,

View file

@ -263,6 +263,14 @@ export async function _normalizeInputMedia(
mime = uploaded.mime
}
let videoCover: tl.TypeInputPhoto | undefined
if (media.type === 'video' && media.cover) {
const inputMedia = await _normalizeInputMedia(client, media.cover)
assertTypeIs('uploadMediaIfNeeded', inputMedia, 'inputMediaPhoto')
videoCover = inputMedia.id
}
const uploadPeer = params.uploadPeer ?? { _: 'inputPeerSelf' }
const uploadMediaIfNeeded = async (inputMedia: tl.TypeInputMedia, photo: boolean): Promise<tl.TypeInputMedia> => {
@ -304,6 +312,8 @@ export async function _normalizeInputMedia(
},
ttlSeconds: media.ttlSeconds,
spoiler: media.type === 'video' && media.spoiler,
videoCover,
videoTimestamp: media.type === 'video' ? media.timestamp : undefined,
}
}
@ -431,6 +441,8 @@ export async function _normalizeInputMedia(
attributes,
ttlSeconds: media.ttlSeconds,
spoiler: media.type === 'video' && media.spoiler,
videoTimestamp: media.type === 'video' ? media.timestamp : undefined,
videoCover,
},
false,
)

View file

@ -78,6 +78,9 @@ export interface ForwardMessageOptions {
* The Stars will be withdrawn from the bot's balance.
*/
allowPaidFloodskip?: boolean
/** Video timestamp to use for the forwarded video */
videoTimestamp?: number
}
/**
@ -110,6 +113,7 @@ export async function forwardMessagesById(
noAuthor,
noCaption,
allowPaidFloodskip,
videoTimestamp,
} = params
// sending more than 100 will not result in a server-sent
@ -137,6 +141,7 @@ export async function forwardMessagesById(
sendAs: sendAs ? await resolvePeer(client, sendAs) : undefined,
quickReplyShortcut: _normalizeQuickReplyShortcut(params.quickReply),
allowPaidFloodskip,
videoTimestamp,
})
assertIsUpdatesGroup('messages.forwardMessages', res)

View file

@ -0,0 +1,22 @@
import type { tl } from '@mtcute/tl'
import type { ITelegramClient } from '../../client.types.js'
import type { InputStarGift } from '../../types/index.js'
import { resolvePeer } from '../users/resolve-peer.js'
export async function _normalizeInputStarGift(
client: ITelegramClient,
gift: InputStarGift,
): Promise<tl.TypeInputSavedStarGift> {
if ('message' in gift) {
return {
_: 'inputSavedStarGiftUser',
msgId: typeof gift.message === 'number' ? gift.message : gift.message.id,
}
} else {
return {
_: 'inputSavedStarGiftChat',
peer: await resolvePeer(client, gift.owner),
savedId: gift.savedId,
}
}
}

View file

@ -1,5 +1,6 @@
import type { ITelegramClient } from '../../client.types.js'
import type { Message } from '../../types/messages/message.js'
import type { InputStarGift } from '../../types/index.js'
import { _normalizeInputStarGift } from './_normalize-input-star-gift.js'
// @available=user
/**
@ -10,8 +11,9 @@ import type { Message } from '../../types/messages/message.js'
export async function acceptStarGift(
client: ITelegramClient,
params: {
/** ID of the message containing the gift */
message: number | Message
/** Input star gift to accept */
gift: InputStarGift
/**
* Action to perform on the gift.
* - `save` - save the gift to your profile
@ -22,18 +24,17 @@ export async function acceptStarGift(
},
): Promise<boolean> {
const { action } = params
const message = typeof params.message === 'number' ? params.message : params.message.id
const inputStarGift = await _normalizeInputStarGift(client, params.gift)
return client.call(
action === 'convert'
? {
_: 'payments.convertStarGift',
msgId: message,
stargift: inputStarGift,
}
: {
_: 'payments.saveStarGift',
unsave: action === 'hide',
msgId: message,
stargift: inputStarGift,
},
)
}

View file

@ -0,0 +1,21 @@
import type { ITelegramClient } from '../../client.types.js'
import type { InputStarGift } from '../../types/premium/stars-gift.js'
import { type MaybeArray, parallelMap } from '@fuman/utils'
import { PeersIndex, SavedStarGift } from '../../types/index.js'
import { _normalizeInputStarGift } from './_normalize-input-star-gift.js'
/** Get one or more saved star gifts by their IDs */
export async function getSavedStarGiftsById(
client: ITelegramClient,
gifts: MaybeArray<InputStarGift>,
): Promise<SavedStarGift[]> {
if (!Array.isArray(gifts)) gifts = [gifts]
const res = await client.call({
_: 'payments.getSavedStarGift',
stargift: await parallelMap(gifts, it => _normalizeInputStarGift(client, it), { limit: 10 }),
})
const peers = PeersIndex.from(res)
return res.gifts.map(it => new SavedStarGift(it, peers))
}

View file

@ -0,0 +1,55 @@
import type { ITelegramClient } from '../../client.types.js'
import type { ArrayPaginated, InputPeerLike } from '../../types/index.js'
import { PeersIndex } from '../../types/index.js'
import { SavedStarGift } from '../../types/premium/saved-star-gift.js'
import { makeArrayPaginated } from '../../utils/misc-utils.js'
import { resolvePeer } from '../users/resolve-peer.js'
/** Get a list of saved star gifts of a user */
export async function getSavedStarGifts(
client: ITelegramClient,
params: {
/** Peer to get saved gifts from */
owner: InputPeerLike
/** Whether to exclude hidden gifts */
excludeHidden?: boolean
/** Whether to exclude publicly visible gifts */
excludePublic?: boolean
/** Whether to exclude gifts with unlimited availability */
excludeUnlimited?: boolean
/** Whether to exclude gifts with limited availability */
excludeLimited?: boolean
/** Whether to exclude unique gifts */
excludeUnique?: boolean
/** Whether to sort by value */
sortByValue?: boolean
/** Offset for pagination */
offset?: string
/** Limit for pagination */
limit?: number
},
): Promise<ArrayPaginated<SavedStarGift, string>> {
const res = await client.call({
_: 'payments.getSavedStarGifts',
peer: await resolvePeer(client, params.owner),
excludeUnsaved: params.excludeHidden,
excludeSaved: params.excludePublic,
excludeUnlimited: params.excludeUnlimited,
excludeLimited: params.excludeLimited,
excludeUnique: params.excludeUnique,
sortByValue: params.sortByValue,
offset: params.offset ?? '',
limit: params.limit ?? 100,
})
const peers = PeersIndex.from(res)
return makeArrayPaginated(
res.gifts.map(it => new SavedStarGift(it, peers)),
res.count,
res.nextOffset,
)
}

View file

@ -0,0 +1,29 @@
import type { ITelegramClient } from '../../client.types.js'
import type { InputStarGift } from '../../types/index.js'
import { _normalizeInputStarGift } from './_normalize-input-star-gift.js'
export async function getStarGiftWithdrawalUrl(
client: ITelegramClient,
params: {
/** The star gift to withdraw */
gift: InputStarGift
/** 2FA password */
password: string
},
): Promise<string> {
const password = await client.computeSrpParams(
await client.call({
_: 'account.getPassword',
}),
params.password,
)
const res = await client.call({
_: 'payments.getStarGiftWithdrawalUrl',
stargift: await _normalizeInputStarGift(client, params.gift),
password,
})
return res.url
}

View file

@ -0,0 +1,61 @@
import type { ITelegramClient } from '../../client.types.js'
import type { InputPeerLike } from '../../types/index.js'
import { PeersIndex } from '../../types/index.js'
import { SavedStarGift } from '../../types/premium/saved-star-gift.js'
import { resolvePeer } from '../users/resolve-peer.js'
/**
* Iterate over saved star gifts of a user,
* wrapper over {@link getSavedStarGifts}
*/
export async function* iterSavedStarGifts(
client: ITelegramClient,
params: {
/** Peer to get saved gifts from */
owner: InputPeerLike
/** Whether to exclude unsaved gifts */
excludeUnsaved?: boolean
/** Whether to exclude saved gifts */
excludeSaved?: boolean
/** Whether to exclude gifts with unlimited availability */
excludeUnlimited?: boolean
/** Whether to exclude gifts with limited availability */
excludeLimited?: boolean
/** Whether to exclude unique gifts */
excludeUnique?: boolean
/** Whether to sort by value */
sortByValue?: boolean
/** Offset for pagination */
offset?: string
/** Limit for pagination */
limit?: number
},
): AsyncIterableIterator<SavedStarGift> {
const owner = await resolvePeer(client, params.owner)
let offset = ''
while (true) {
const res = await client.call({
_: 'payments.getSavedStarGifts',
peer: owner,
excludeUnsaved: params.excludeUnsaved,
excludeSaved: params.excludeSaved,
excludeUnlimited: params.excludeUnlimited,
excludeLimited: params.excludeLimited,
excludeUnique: params.excludeUnique,
sortByValue: params.sortByValue,
offset,
limit: params.limit ?? 100,
})
const peers = PeersIndex.from(res)
yield * res.gifts.map(it => new SavedStarGift(it, peers))
if (!res.nextOffset) break
offset = res.nextOffset
}
}

View file

@ -8,7 +8,7 @@ import Long from 'long'
import { assertTypeIs } from '../../../utils/type-assertions.js'
import { type InputText, inputTextToTl } from '../../types/misc/entities.js'
import { _findMessageInUpdate } from '../messages/find-in-update.js'
import { resolveUser } from '../users/resolve-peer.js'
import { resolvePeer } from '../users/resolve-peer.js'
/**
* Send a star gift to a user.
@ -23,8 +23,8 @@ import { resolveUser } from '../users/resolve-peer.js'
export async function sendStarGift(
client: ITelegramClient,
params: {
/** ID of the user to send the gift to */
userId: InputPeerLike
/** ID of the peer to send the gift to */
peerId: InputPeerLike
/** ID of the gift to send */
gift: Long | StarGift
@ -50,7 +50,7 @@ export async function sendStarGift(
},
): Promise<Message> {
const {
userId,
peerId,
gift,
anonymous,
message,
@ -61,7 +61,7 @@ export async function sendStarGift(
const invoice: tl.TypeInputInvoice = {
_: 'inputInvoiceStarGift',
hideName: anonymous,
userId: await resolveUser(client, userId),
peer: await resolvePeer(client, peerId),
giftId: Long.isLong(gift) ? gift : gift.id,
message: message ? inputTextToTl(message) : undefined,
includeUpgrade: withUpgrade,

View file

@ -1,11 +1,12 @@
import type { tl } from '@mtcute/tl'
import type { ITelegramClient } from '../../client.types.js'
import type { InputPeerLike } from '../../types/index.js'
import type { InputPeerLike, InputStarGift } from '../../types/index.js'
import type { Message } from '../../types/messages/message.js'
import { assertTypeIs } from '../../../utils/type-assertions.js'
import { _findMessageInUpdate } from '../messages/find-in-update.js'
import { resolveUser } from '../users/resolve-peer.js'
import { resolvePeer } from '../users/resolve-peer.js'
import { _normalizeInputStarGift } from './_normalize-input-star-gift.js'
/**
* Transfer a unique star gift.
@ -20,8 +21,8 @@ import { resolveUser } from '../users/resolve-peer.js'
export async function transferStarGift(
client: ITelegramClient,
params: {
/** ID of the message containing the gift */
message: number | Message
/** Star gift to transfer */
gift: InputStarGift
/** ID of the user to transfer the gift to */
recepient: InputPeerLike
@ -33,13 +34,12 @@ export async function transferStarGift(
shouldDispatch?: true
},
): Promise<Message> {
const { message, recepient, shouldDispatch } = params
const { gift, recepient, shouldDispatch } = params
const msgId = typeof message === 'number' ? message : message.id
const invoice: tl.TypeInputInvoice = {
_: 'inputInvoiceStarGiftTransfer',
msgId,
toId: await resolveUser(client, recepient),
stargift: await _normalizeInputStarGift(client, gift),
toId: await resolvePeer(client, recepient),
}
const form = await client.call({

View file

@ -1,9 +1,11 @@
import type { tl } from '@mtcute/tl'
import type { ITelegramClient } from '../../client.types.js'
import type { InputStarGift } from '../../types/index.js'
import type { Message } from '../../types/messages/message.js'
import { assertTypeIs } from '../../../utils/type-assertions.js'
import { _findMessageInUpdate } from '../messages/find-in-update.js'
import { _normalizeInputStarGift } from './_normalize-input-star-gift.js'
/**
* Upgrades a star gift to a unique gift.
@ -18,8 +20,7 @@ import { _findMessageInUpdate } from '../messages/find-in-update.js'
export async function upgradeStarGift(
client: ITelegramClient,
params: {
/** ID of the message containing the gift */
message: number | Message
gift: InputStarGift
/**
* Whether to retain the original details of the gift
@ -34,12 +35,11 @@ export async function upgradeStarGift(
shouldDispatch?: true
},
): Promise<Message> {
const { message, keepOriginalDetails, shouldDispatch } = params
const { gift, keepOriginalDetails, shouldDispatch } = params
const msgId = typeof message === 'number' ? message : message.id
const invoice: tl.TypeInputInvoice = {
_: 'inputInvoiceStarGiftUpgrade',
msgId,
stargift: await _normalizeInputStarGift(client, gift),
keepOriginalDetails,
}

View file

@ -46,6 +46,8 @@ export async function setEmojiStatus(
peerId: InputPeerLike
/** Custom emoji ID or `null` to remove the emoji */
emoji: tl.Long | null
/** When true, `emoji` is the ID of the collectible emoji */
isCollectible?: boolean
/**
* Date when the emoji status should expire (only if `emoji` is not `null`)
*/
@ -56,6 +58,7 @@ export async function setEmojiStatus(
peerId,
emoji,
until,
isCollectible,
} = params
const peer = await resolvePeer(client, peerId)
@ -70,6 +73,12 @@ export async function setEmojiStatus(
documentId: emoji,
until: normalizeDate(until),
}
} else if (isCollectible) {
emojiStatus = {
_: 'inputEmojiStatusCollectible',
collectibleId: emoji,
until: normalizeDate(until),
}
} else {
emojiStatus = {
_: 'emojiStatus',

View file

@ -243,6 +243,12 @@ export interface InputMediaVideo extends FileMixin, CaptionMixin {
* Whether this video should be hidden with a spoiler
*/
spoiler?: boolean
/** Cover for the video */
cover?: InputMediaPhoto
/** Timestamp for the auto-generated cover (?) */
timestamp?: number
}
/**

View file

@ -5,6 +5,7 @@ import { makeInspectable } from '../../utils/index.js'
import { memoizeGetters } from '../../utils/memoize.js'
import { RawDocument } from './document.js'
import { Photo } from './photo.js'
/**
* A video, round video message or GIF animation.
@ -94,6 +95,16 @@ export class Video extends RawDocument {
get codec(): string | null {
return this.attr._ === 'documentAttributeVideo' ? this.attr.videoCodec ?? null : null
}
get videoCover(): Photo | null {
if (!this.media || this.media.videoCover?._ !== 'photo') return null
return new Photo(this.media.videoCover)
}
get videoTimestamp(): number | null {
return this.media?.videoTimestamp ?? null
}
}
memoizeGetters(Video, ['fileName', 'thumbnails', 'fileId', 'uniqueFileId', 'isAnimation'])

View file

@ -565,6 +565,10 @@ export interface ActionStarGift {
gift: StarGift | StarGiftUnique
/** Message attached to the gift */
message: TextWithEntities | null
fromId?: number
toId?: number
savedId?: Long
}
export type MessageAction =
@ -924,6 +928,31 @@ export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction):
upgraded: act.upgraded!,
upgradeStars: act.upgradeStars ?? Long.ZERO,
upgradeMsgId: act.upgradeMsgId ?? null,
fromId: act.fromId ? getMarkedPeerId(act.fromId) : undefined,
toId: act.peer ? getMarkedPeerId(act.peer) : undefined,
savedId: act.savedId,
}
case 'messageActionStarGiftUnique':
return {
type: 'stars_gift',
nameHidden: false,
saved: act.saved!,
converted: false,
convertStars: Long.ZERO,
refunded: act.refunded!,
gift: act.gift._ === 'starGift'
? new StarGift(act.gift)
: new StarGiftUnique(act.gift, this._peers),
message: null,
canUpgrade: false,
upgraded: true,
upgradeStars: Long.ZERO,
upgradeMsgId: null,
fromId: act.fromId ? getMarkedPeerId(act.fromId) : undefined,
toId: act.peer ? getMarkedPeerId(act.peer) : undefined,
savedId: act.savedId,
}
default:
return null

View file

@ -404,7 +404,12 @@ export class Chat {
*/
get emojiStatus(): EmojiStatus | null {
if (this.raw._ !== 'channel') return null
if (!this.raw.emojiStatus || this.raw.emojiStatus._ === 'emojiStatusEmpty') return null
if (
!this.raw.emojiStatus
|| this.raw.emojiStatus._ === 'emojiStatusEmpty'
|| this.raw.emojiStatus._ === 'inputEmojiStatusCollectible') {
return null
}
return new EmojiStatus(this.raw.emojiStatus)
}

View file

@ -364,6 +364,16 @@ export class FullChat extends Chat {
return new BotVerification(this.full.botVerification)
}
/** Whether star gifts are available in this chat */
get starGiftsAvailable(): boolean {
return this.full._ === 'channelFull' && this.full.stargiftsAvailable!
}
/** Number of star gifts available in this chat */
get starGiftsCount(): number {
return this.full._ === 'channelFull' ? this.full.stargiftsCount ?? 0 : 0
}
}
memoizeGetters(FullChat, [

View file

@ -408,7 +408,12 @@ export class User {
* User's emoji status, if any.
*/
get emojiStatus(): EmojiStatus | null {
if (!this.raw.emojiStatus || this.raw.emojiStatus._ === 'emojiStatusEmpty') return null
if (
!this.raw.emojiStatus
|| this.raw.emojiStatus._ === 'emojiStatusEmpty'
|| this.raw.emojiStatus._ === 'inputEmojiStatusCollectible') {
return null
}
return new EmojiStatus(this.raw.emojiStatus)
}

View file

@ -7,6 +7,7 @@ export * from './business-connection.js'
export * from './business-intro.js'
export * from './business-location.js'
export * from './business-work-hours.js'
export * from './saved-star-gift.js'
export * from './stars-gift-unique.js'
export * from './stars-gift.js'
export * from './stars-status.js'

View file

@ -0,0 +1,93 @@
import type { tl } from '@mtcute/tl'
import type { TextWithEntities } from '../misc/entities.js'
import type { Peer } from '../peers/peer.js'
import type { PeersIndex } from '../peers/peers-index.js'
import { makeInspectable } from '../../utils/inspectable.js'
import { memoizeGetters } from '../../utils/memoize.js'
import { parsePeer } from '../peers/peer.js'
import { StarGiftUnique } from './stars-gift-unique.js'
import { StarGift } from './stars-gift.js'
export class SavedStarGift {
constructor(
readonly raw: tl.RawSavedStarGift,
readonly _peers: PeersIndex,
) {}
/** Whether the sender name is hidden */
get nameHidden(): boolean {
return this.raw.nameHidden!
}
/** Whether this gift was not saved yet */
get unsaved(): boolean {
return this.raw.unsaved!
}
/** Whether this gift was refunded */
get refunded(): boolean {
return this.raw.refunded!
}
/** Whether this gift can be upgraded to a unique gift */
get canUpgrade(): boolean {
return this.raw.canUpgrade!
}
/** Sender of the gift */
get sender(): Peer | null {
return this.raw.fromId ? parsePeer(this.raw.fromId, this._peers) : null
}
/** Date when the gift was sent */
get date(): Date {
return new Date(this.raw.date * 1000)
}
/** The gift itself */
get gift(): StarGift | StarGiftUnique {
if (this.raw.gift._ === 'starGift') {
return new StarGift(this.raw.gift)
}
return new StarGiftUnique(this.raw.gift, this._peers)
}
/** The attached message */
get message(): TextWithEntities | null {
return this.raw.message ?? null
}
/** ID of the message where the gift was originally sent (if available) */
get messageId(): number | null {
return this.raw.msgId ?? null
}
/** ID of the saved gift */
get savedId(): tl.Long | null {
return this.raw.savedId ?? null
}
/** Amount of stars the gift can be converted to by the recipient */
get convertStars(): tl.Long | null {
return this.raw.convertStars ?? null
}
/** Amount of stars needed to upgrade the gift to a unique gift */
get upgradeStars(): tl.Long | null {
return this.raw.upgradeStars ?? null
}
/** Amount of stars needed to transfer the gift */
get transferStars(): tl.Long | null {
return this.raw.transferStars ?? null
}
/** Date when the gift can be exported to blockchain */
get canExportAt(): Date | null {
return this.raw.canExportAt ? new Date(this.raw.canExportAt * 1000) : null
}
}
makeInspectable(SavedStarGift)
memoizeGetters(SavedStarGift, ['sender', 'gift'])

View file

@ -1,12 +1,13 @@
import type { tl } from '@mtcute/tl'
import type { Sticker } from '../media/sticker.js'
import type { TextWithEntities } from '../misc/entities.js'
import type { Peer } from '../peers/peer.js'
import type { PeersIndex } from '../peers/peers-index.js'
import { assert } from '@fuman/utils'
import { makeInspectable } from '../../utils/inspectable.js'
import { memoizeGetters } from '../../utils/memoize.js'
import { parseDocument } from '../media/document-utils.js'
import { User } from '../peers/user.js'
import { parsePeer } from '../peers/peer.js'
/** An attribute of a unique star gift containing a sticker */
export class StarGiftUniqueAttribute {
@ -78,13 +79,13 @@ export class StarGiftUniqueOriginalDetails {
) {}
/** ID of the user who sent the original star gift */
get sender(): User | null {
return this.raw.senderId ? new User(this._peers.user(this.raw.senderId)) : null
get sender(): Peer | null {
return this.raw.senderId ? parsePeer(this.raw.senderId, this._peers) : null
}
/** ID of the user who received the original star gift */
get recipient(): User {
return new User(this._peers.user(this.raw.recipientId))
get recipient(): Peer {
return parsePeer(this.raw.recipientId, this._peers)
}
/** Date when the original star gift was sent */
@ -144,10 +145,10 @@ export class StarGiftUnique {
return this.raw.slug
}
/** ID of the user who owns this gift, if available */
get owner(): User | null {
/** ID of the peer who owns this gift, if available */
get owner(): Peer | null {
if (!this.raw.ownerId) return null
return new User(this._peers.user(this.raw.ownerId))
return parsePeer(this.raw.ownerId, this._peers)
}
/** Name of the user who owns this gift, if available */
@ -183,6 +184,11 @@ export class StarGiftUnique {
if (!this._originalDetails) return null
return new StarGiftUniqueOriginalDetails(this._originalDetails, this._peers)
}
/** TON address of the owner of the unique star gift */
get ownerAddress(): string | null {
return this.raw.ownerAddress ?? null
}
}
makeInspectable(StarGiftUnique)

View file

@ -1,7 +1,9 @@
import type { tl } from '@mtcute/tl'
import type { Sticker } from '../media/sticker.js'
import type { Message } from '../messages/message.js'
import type { TextWithEntities } from '../misc/entities.js'
import type { InputPeerLike } from '../peers/peer.js'
import type { PeersIndex } from '../peers/peers-index.js'
import Long from 'long'
import { MtTypeAssertionError } from '../../../types/errors.js'
@ -12,8 +14,20 @@ import { parseDocument } from '../media/document-utils.js'
import { User } from '../peers/user.js'
import { StarGiftUnique } from './stars-gift-unique.js'
export type InputStarGift =
| {
/** ID of the message containing the gift */
message: number | Message
}
| {
/** Owner of the gift */
owner: InputPeerLike
/** ID of the gift */
savedId: tl.Long
}
/**
* A gift with stars attached to it.
* A gift bought with stars
*/
export class StarGift {
constructor(readonly raw: tl.RawStarGift) {}

View file

@ -2,11 +2,54 @@ import type { tl } from '@mtcute/tl'
import { makeInspectable } from '../../utils/index.js'
export class EmojiStatusCollectible {
constructor(readonly raw: tl.RawEmojiStatusCollectible) {}
/** ID of the collectible */
get id(): tl.Long {
return this.raw.collectibleId
}
/** Title of the collectible */
get title(): string {
return this.raw.title
}
/** Slug of the collectible */
get slug(): string {
return this.raw.slug
}
/** Pattern emoji ID of the collectible */
get patternEmojiId(): tl.Long {
return this.raw.patternDocumentId
}
/** Colors of the collectible */
get colors(): {
center: number
edge: number
pattern: number
text: number
} {
return {
center: this.raw.centerColor,
edge: this.raw.edgeColor,
pattern: this.raw.patternColor,
text: this.raw.textColor,
}
}
}
makeInspectable(EmojiStatusCollectible)
/**
* Information about user's emoji status
*/
export class EmojiStatus {
constructor(readonly raw: Exclude<tl.TypeEmojiStatus, tl.RawEmojiStatusEmpty>) {}
constructor(
readonly raw: Exclude<tl.TypeEmojiStatus, tl.RawEmojiStatusEmpty | tl.RawInputEmojiStatusCollectible>,
) {}
/** ID of the custom emoji */
get emoji(): tl.Long {
@ -15,10 +58,17 @@ export class EmojiStatus {
/** This status is valid at most until this date */
get expireDate(): Date | null {
if (this.raw._ === 'emojiStatus') return null
if (!this.raw.until) return null
return new Date(this.raw.until * 1000)
}
/** If this is a collectible emoji status, information about it */
get collectible(): EmojiStatusCollectible | null {
if (this.raw._ !== 'emojiStatusCollectible') return null
return new EmojiStatusCollectible(this.raw)
}
}
makeInspectable(EmojiStatus)

View file

@ -2,7 +2,7 @@
TL schema and related utils used for mtcute.
Generated from TL layer **197** (last updated on 22.01.2025).
Generated from TL layer **198** (last updated on 25.01.2025).
## About

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,7 @@
// LAYER 197
starGiftUnique_layer197#3482f322 flags:# id:long title:string slug:string num:int owner_id:flags.0?int53 owner_name:flags.1?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int = StarGift;
emojiStatus_layer197#929b619d document_id:long = EmojiStatus;
messageMediaDocument_layer197#dd570bd5 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> ttl_seconds:flags.2?int = MessageMedia;
channelFull_layer197#9ff3b858 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true id:int53 about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int53 location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<int53> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification = ChatFull;
messageActionStarGiftUnique_layer197#26077b99 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long = MessageAction;
messageActionStarGift_layer197#d8f4f0a7 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long = MessageAction;

View file

@ -103,8 +103,6 @@
"requestedPeerChat": ["chat_id"],
"requestedPeerUser": ["user_id"],
"starRefProgram": ["bot_id"],
"starGiftUnique": ["owner_id"],
"starGiftAttributeOriginalDetails": ["sender_id", "recipient_id"],
"secureFile": ["size"],
"statsGroupTopAdmin": ["user_id"],
"statsGroupTopInviter": ["user_id"],

View file

@ -1,6 +1,6 @@
{
"name": "@mtcute/tl",
"version": "197.0.0",
"version": "198.0.0",
"description": "TL schema used for mtcute",
"author": "alina sireneva <alina@tei.su>",
"license": "MIT",

View file

@ -10,6 +10,7 @@ export const API_SCHEMA_DIFF_JSON_FILE: string = join(__dirname, '../diff.json')
export const MTP_SCHEMA_JSON_FILE: string = join(__dirname, '../mtp-schema.json')
export const ERRORS_JSON_FILE: string = join(__dirname, '../raw-errors.json')
export const APP_CONFIG_JSON_FILE: string = join(__dirname, '../app-config.json')
export const COMPAT_TL_FILE: string = join(__dirname, '../data/compat.tl')
export const CORE_DOMAIN = 'https://core.telegram.org'
export const COREFORK_DOMAIN = 'https://corefork.telegram.org'
@ -28,3 +29,14 @@ export const ESM_PRELUDE = `// This file is auto-generated. Do not edit.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
`
export const TYPES_FOR_COMPAT: string[] = [
'message',
'messageService',
'channel',
'channelFull',
'chat',
'chatFull',
'user',
'userFull',
]

View file

@ -7,10 +7,12 @@
import type {
TlEntry,
TlFullSchema,
TlSchemaDiff,
} from '@mtcute/tl-utils'
import type { TlPackedSchema } from './schema.js'
import { readFile, writeFile } from 'node:fs/promises'
import { createWriteStream } from 'node:fs'
import { readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import * as readline from 'node:readline'
import { ffetchBase as ffetch } from '@fuman/fetch'
@ -21,21 +23,24 @@ import {
mergeTlSchemas,
parseFullTlSchema,
parseTlToEntries,
TL_PRIMITIVES,
writeTlEntryToString,
} from '@mtcute/tl-utils'
import { parseTlEntriesFromJson } from '@mtcute/tl-utils/json.js'
import { parseTlEntriesFromJson } from '@mtcute/tl-utils/json.js'
import * as cheerio from 'cheerio'
import {
__dirname,
API_SCHEMA_DIFF_JSON_FILE,
API_SCHEMA_JSON_FILE,
BLOGFORK_DOMAIN,
COMPAT_TL_FILE,
CORE_DOMAIN,
COREFORK_DOMAIN,
TDESKTOP_LAYER,
TDESKTOP_SCHEMA,
TDLIB_SCHEMA,
TYPES_FOR_COMPAT,
WEBA_LAYER,
WEBA_SCHEMA,
WEBK_SCHEMA,
@ -225,6 +230,77 @@ async function overrideInt53(schema: TlFullSchema): Promise<void> {
})
}
async function generateCompatSchema(oldLayer: number, oldSchema: TlFullSchema, diff: TlSchemaDiff) {
// generate list of all types that need to be added to compat.tl
const typesToAdd = new Set<string>()
const diffedTypes = new Set<string>()
for (const { name } of diff.classes.removed) {
diffedTypes.add(name)
}
for (const { name, id } of diff.classes.modified) {
if (id && id.old !== id.new) {
// no point in adding this type if there wasn't a change in constructor ID
diffedTypes.add(name)
}
}
const processedTypes = new Set<string>()
const queue = [...TYPES_FOR_COMPAT]
while (queue.length) {
const it = queue.pop()!
processedTypes.add(it)
const entry = oldSchema.classes[it]
if (!entry) {
console.log(`[warn] Cannot find ${it} in old schema`)
continue
}
if (diffedTypes.has(it)) {
typesToAdd.add(it)
continue
}
for (const arg of entry.arguments) {
const type = arg.type
if (type in TL_PRIMITIVES || type === '#') continue
const typeEntry = oldSchema.unions[type]
if (!typeEntry) {
console.log(`[warn] Cannot find ${type} in old schema`)
continue
}
for (const { name } of typeEntry.classes) {
if (!processedTypes.has(name)) {
queue.push(name)
}
}
}
}
const compatWs = createWriteStream(COMPAT_TL_FILE, { flags: 'a' })
compatWs.write(`// LAYER ${oldLayer}\n`)
for (const type of typesToAdd) {
const entry = oldSchema.classes[type]
if (!entry) {
console.log(`[warn] Cannot find ${type} in old schema`)
continue
}
const entryMod: TlEntry = {
...entry,
name: `${entry.name}_layer${oldLayer}`,
}
compatWs.write(`${writeTlEntryToString(entryMod)}\n`)
}
compatWs.close()
}
async function main() {
console.log('Loading schemas...')
@ -351,18 +427,22 @@ async function main() {
console.log('Writing diff to file...')
const oldSchema = unpackTlSchema(JSON.parse(await readFile(API_SCHEMA_JSON_FILE, 'utf8')) as TlPackedSchema)
const diff = generateTlSchemasDifference(oldSchema[0], resultSchema)
await writeFile(
API_SCHEMA_DIFF_JSON_FILE,
JSON.stringify(
{
layer: [oldSchema[1], resultLayer],
diff: generateTlSchemasDifference(oldSchema[0], resultSchema),
diff,
},
null,
4,
),
)
console.log('Generating compat.tl...')
await generateCompatSchema(oldSchema[1], oldSchema[0], diff)
console.log('Writing result to file...')
await writeFile(API_SCHEMA_JSON_FILE, JSON.stringify(packTlSchema(resultSchema, resultLayer)))