@mtcute/core 0.16.9 → 0.16.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import Long from "long";
3
3
  import { LruMap, getAllPeersFrom, toggleChannelIdMark, longToFastString, extractUsernames, parseMarkedPeerId, longFromFastString, Deque, AsyncLock, getMarkedPeerId, setTimeoutWrap, clearTimeoutWrap, makeInspectable, getBarePeerId, encodeInlineMessageId, assertNever, ConditionVariable, clearIntervalWrap, setIntervalWrap, toInputChannel, sleepWithAbort, buffersEqual, dataViewFromBuffer, concatBuffers, randomLong, LongMap, compareLongs, getRandomInt, longFromBuffer, removeFromLongArray } from "./DY1E3mHM.js";
4
4
  import { MtArgumentError, MtTimeoutError, getPlatform, MtUnsupportedError, MtcuteError, MtSecurityError, MtTypeAssertionError } from "./DBMBgE7t.js";
5
5
  import { createControllablePromise, assertTypeIs, isTlRpcError, mtpAssertTypeIs } from "./BN3qj7tU.js";
6
- import { resolvePeer, getPeerDialogs, sendText, sendMedia, sendMediaGroup, readHistory, memoizeGetters, Chat$2, User$2, ChatInviteLink$2, Message$2, ChatMember$2, Location$1, parsePeer, toReactionEmoji, ReactionCount$1, Poll$2, Story$2, toPendingUpdate, messageToUpdate, isMessageEmpty, createDummyUpdatesContainer, extractChannelIdFromUpdate } from "./CPnecqvf.js";
6
+ import { resolvePeer, getPeerDialogs, sendText, sendMedia, sendMediaGroup, readHistory, memoizeGetters, Chat$2, User$2, ChatInviteLink$2, Message$2, ChatMember$2, Location$1, parsePeer, toReactionEmoji, ReactionCount$1, Poll$2, Story$2, toPendingUpdate, messageToUpdate, isMessageEmpty, createDummyUpdatesContainer, extractChannelIdFromUpdate, _getChannelsBatched } from "./Btmu4f4t.js";
7
7
  import { TlBinaryWriter, TlBinaryReader, TlSerializationCounter } from "@mtcute/tl-runtime";
8
8
  import { tl, mtp } from "@mtcute/tl";
9
9
  import { PeersIndex } from "./N3PMYmCL.js";
@@ -46,14 +46,17 @@ class PeersService extends BaseService {
46
46
  _pendingWrites = /* @__PURE__ */ new Map();
47
47
  async updatePeersFrom(obj) {
48
48
  let count = 0;
49
+ let minCount = 0;
49
50
  for (const peer of getAllPeersFrom(obj)) {
50
- if (peer.min) continue;
51
+ if (peer.min) {
52
+ minCount += 1;
53
+ }
51
54
  count += 1;
52
55
  await this.store(peer);
53
56
  }
54
57
  if (count > 0) {
55
58
  await this._driver.save?.();
56
- this._log.debug("cached %d peers", count);
59
+ this._log.debug("cached %d peers (%d min)", count, minCount);
57
60
  return true;
58
61
  }
59
62
  return false;
@@ -70,6 +73,7 @@ class PeersService extends BaseService {
70
73
  dto = {
71
74
  id: peer.id,
72
75
  accessHash: longToFastString(peer.accessHash),
76
+ isMin: peer.min && !(peer.phone !== void 0 && peer.phone.length === 0),
73
77
  phone: peer.phone,
74
78
  usernames: extractUsernames(peer),
75
79
  updated: Date.now(),
@@ -83,6 +87,8 @@ class PeersService extends BaseService {
83
87
  dto = {
84
88
  id: -peer.id,
85
89
  accessHash: "",
90
+ isMin: false,
91
+ // chats can't be "min"
86
92
  updated: Date.now(),
87
93
  complete: this._serializeTl(peer),
88
94
  usernames: []
@@ -99,6 +105,7 @@ class PeersService extends BaseService {
99
105
  dto = {
100
106
  id: toggleChannelIdMark(peer.id),
101
107
  accessHash: longToFastString(peer.accessHash),
108
+ isMin: peer._ === "channel" ? peer.min : false,
102
109
  usernames: extractUsernames(peer),
103
110
  updated: Date.now(),
104
111
  complete: this._serializeTl(peer)
@@ -118,10 +125,73 @@ class PeersService extends BaseService {
118
125
  return;
119
126
  }
120
127
  }
128
+ let newComplete = peer;
129
+ if (peer.min) {
130
+ const existing = this._cache.get(peer.id)?.complete ?? await this.getCompleteById(peer.id);
131
+ if (existing && !existing.min) {
132
+ if (existing._ === "channel" && peer._ === "channel") {
133
+ newComplete = {
134
+ ...existing,
135
+ title: peer.title,
136
+ megagroup: peer.megagroup,
137
+ color: peer.color,
138
+ photo: peer.photo,
139
+ username: peer.username,
140
+ usernames: peer.usernames,
141
+ hasGeo: peer.hasGeo,
142
+ noforwards: peer.noforwards,
143
+ emojiStatus: peer.emojiStatus,
144
+ hasLink: peer.hasLink,
145
+ slowmodeEnabled: peer.slowmodeEnabled,
146
+ scam: peer.scam,
147
+ fake: peer.fake,
148
+ gigagroup: peer.gigagroup,
149
+ forum: peer.forum,
150
+ level: peer.level,
151
+ restricted: peer.restricted,
152
+ restrictionReason: peer.restrictionReason,
153
+ joinToSend: peer.joinToSend,
154
+ joinRequest: peer.joinRequest,
155
+ verified: peer.verified,
156
+ defaultBannedRights: peer.defaultBannedRights
157
+ };
158
+ } else if (existing._ === "user" && peer._ === "user") {
159
+ newComplete = {
160
+ ...existing,
161
+ deleted: peer.deleted,
162
+ bot: peer.bot,
163
+ botChatHistory: peer.botChatHistory,
164
+ botNochats: peer.botNochats,
165
+ verified: peer.verified,
166
+ restricted: peer.restricted,
167
+ botInlineGeo: peer.botInlineGeo,
168
+ support: peer.support,
169
+ scam: peer.scam,
170
+ fake: peer.fake,
171
+ botAttachMenu: peer.botAttachMenu,
172
+ premium: peer.premium,
173
+ storiesUnavailable: peer.storiesUnavailable,
174
+ contactRequirePremium: peer.contactRequirePremium,
175
+ botBusiness: peer.botBusiness,
176
+ botHasMainApp: peer.botHasMainApp,
177
+ photo: peer.applyMinPhoto ? peer.photo : existing.photo,
178
+ status: !existing.status || existing.status._ === "userStatusEmpty" ? peer.status : existing.status,
179
+ botInfoVersion: peer.botInfoVersion,
180
+ restrictionReason: peer.restrictionReason,
181
+ botInlinePlaceholder: peer.botInlinePlaceholder,
182
+ langCode: peer.langCode,
183
+ emojiStatus: peer.emojiStatus,
184
+ color: peer.color,
185
+ profileColor: peer.profileColor,
186
+ botActiveUsers: peer.botActiveUsers
187
+ };
188
+ }
189
+ }
190
+ }
121
191
  await this._peers.store(dto);
122
192
  this._cache.set(peer.id, {
123
193
  peer: getInputPeer(dto),
124
- complete: peer
194
+ complete: newComplete
125
195
  });
126
196
  await this._refs.deleteByPeer(peer.id);
127
197
  }
@@ -137,7 +207,7 @@ class PeersService extends BaseService {
137
207
  async getById(id, allowRefs = true) {
138
208
  const cached = this._cache.get(id);
139
209
  if (cached) return cached.peer;
140
- const dto = await this._peers.getById(id);
210
+ const dto = await this._peers.getById(id, false);
141
211
  if (dto) {
142
212
  return this._returnCaching(id, dto);
143
213
  }
@@ -177,10 +247,10 @@ class PeersService extends BaseService {
177
247
  }
178
248
  return this._returnCaching(dto.id, dto);
179
249
  }
180
- async getCompleteById(id) {
250
+ async getCompleteById(id, allowMin = false) {
181
251
  const cached = this._cache.get(id);
182
252
  if (cached) return cached.complete;
183
- const dto = await this._peers.getById(id);
253
+ const dto = await this._peers.getById(id, allowMin);
184
254
  if (!dto) return null;
185
255
  const cacheItem = {
186
256
  peer: getInputPeer(dto),
@@ -883,10 +953,10 @@ class ChatJoinRequestUpdate {
883
953
  // in this update, peers index only contains
884
954
  // recent requesters, not the chat
885
955
  /**
886
- * ID of the chat/channel
956
+ * Marked ID of the chat/channel
887
957
  */
888
958
  get chatId() {
889
- return getBarePeerId(this.raw.peer);
959
+ return getMarkedPeerId(this.raw.peer);
890
960
  }
891
961
  /**
892
962
  * IDs of the users who recently requested to join the chat
@@ -2151,20 +2221,33 @@ class UpdatesManager {
2151
2221
  assertNever();
2152
2222
  }
2153
2223
  }
2154
- async _fetchMissingPeers(upd, peers, allowMissing = false) {
2155
- const { client } = this;
2224
+ async _fetchMissingPeers(upd, peers, fromDifference = false) {
2225
+ const { client, log } = this;
2156
2226
  const missing = /* @__PURE__ */ new Set();
2157
- async function fetchPeer(peer) {
2227
+ async function fetchPeer(peer, allowZeroHash = false) {
2158
2228
  if (!peer) return true;
2159
2229
  const bare = typeof peer === "number" ? parseMarkedPeerId(peer)[1] : getBarePeerId(peer);
2160
2230
  const marked = typeof peer === "number" ? peer : getMarkedPeerId(peer);
2161
2231
  const index = marked > 0 ? peers.users : peers.chats;
2162
- if (index.has(bare)) return true;
2232
+ const fromIndex = index.get(bare);
2233
+ if (fromIndex && !fromIndex.min) return true;
2163
2234
  if (missing.has(marked)) return false;
2164
2235
  const cached = await client.storage.peers.getCompleteById(marked);
2165
2236
  if (!cached) {
2237
+ if (fromDifference && allowZeroHash && parseMarkedPeerId(marked)[0] === "channel") {
2238
+ log.debug("trying to fetch peer %d with zero access hash", marked);
2239
+ const fetched = await _getChannelsBatched(client, {
2240
+ _: "inputChannel",
2241
+ channelId: bare,
2242
+ accessHash: Long.ZERO
2243
+ });
2244
+ if (fetched?._ === "channel" && !fetched.min) {
2245
+ index.set(bare, fetched);
2246
+ return true;
2247
+ }
2248
+ }
2166
2249
  missing.add(marked);
2167
- return allowMissing;
2250
+ return fromDifference;
2168
2251
  }
2169
2252
  index.set(bare, cached);
2170
2253
  return true;
@@ -2176,7 +2259,7 @@ class UpdatesManager {
2176
2259
  case "updateEditChannelMessage": {
2177
2260
  const msg = upd.message;
2178
2261
  if (msg._ === "messageEmpty") return missing;
2179
- if (!await fetchPeer(msg.peerId)) return missing;
2262
+ if (!await fetchPeer(msg.peerId, true)) return missing;
2180
2263
  if (!await fetchPeer(msg.fromId)) return missing;
2181
2264
  if (msg.replyTo) {
2182
2265
  if (msg.replyTo._ === "messageReplyHeader" && !await fetchPeer(msg.replyTo.replyToPeerId)) {
@@ -2187,7 +2270,7 @@ class UpdatesManager {
2187
2270
  }
2188
2271
  }
2189
2272
  if (msg._ !== "messageService") {
2190
- if (msg.fwdFrom && (!await fetchPeer(msg.fwdFrom.fromId) || !await fetchPeer(msg.fwdFrom.savedFromPeer))) {
2273
+ if (msg.fwdFrom && (!await fetchPeer(msg.fwdFrom.fromId) || !await fetchPeer(msg.fwdFrom.savedFromPeer, true))) {
2191
2274
  return missing;
2192
2275
  }
2193
2276
  if (!await fetchPeer(msg.viaBotId)) return missing;
@@ -2224,7 +2307,7 @@ class UpdatesManager {
2224
2307
  if (!await fetchPeer(msg.action.userId)) return missing;
2225
2308
  break;
2226
2309
  case "messageActionChatMigrateTo":
2227
- if (!await fetchPeer(toggleChannelIdMark(msg.action.channelId))) {
2310
+ if (!await fetchPeer(toggleChannelIdMark(msg.action.channelId), true)) {
2228
2311
  return missing;
2229
2312
  }
2230
2313
  break;
@@ -6126,7 +6209,7 @@ class NetworkManager {
6126
6209
  _: "initConnection",
6127
6210
  deviceModel,
6128
6211
  systemVersion: "1.0",
6129
- appVersion: "0.16.9",
6212
+ appVersion: "0.16.13",
6130
6213
  systemLangCode: "en",
6131
6214
  langPack: "",
6132
6215
  // "langPacks are for official apps only"
package/client.cjs CHANGED
@@ -7,7 +7,7 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
7
7
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
8
  const EventEmitter = require("node:events");
9
9
  const tl = require("@mtcute/tl");
10
- const client = require("./chunks/cjs/CS5mxbeO.js");
10
+ const client = require("./chunks/cjs/BO3RV06t.js");
11
11
  const platform = require("./chunks/cjs/j7rWn_1y.js");
12
12
  const sortedArray = require("./chunks/cjs/C1cFqHcW.js");
13
13
  const logger = require("./chunks/cjs/D4qcXFYA.js");
@@ -15,8 +15,8 @@ const controllablePromise = require("./chunks/cjs/CZAB54t2.js");
15
15
  require("@mtcute/tl-runtime");
16
16
  const tlJson = require("./chunks/cjs/BQETTb_8.js");
17
17
  const conditionVariable = require("./chunks/cjs/eX3zeDAz.js");
18
- const storyViewer = require("./chunks/cjs/UVFvMVPt.js");
19
- const updateProfile = require("./chunks/cjs/jFPoDILV.js");
18
+ const storyViewer = require("./chunks/cjs/chPq0GcA.js");
19
+ const updateProfile = require("./chunks/cjs/CntZHjXA.js");
20
20
  function reportUnknownError(log, error, method) {
21
21
  if (typeof fetch !== "function") return;
22
22
  fetch(`https://rpc.pwrtelegram.xyz/?code=${error.code}&method=${method}&error=${error.text}`).then((r) => r.json()).then((r) => {
@@ -1257,6 +1257,9 @@ TelegramClient.prototype.getProfilePhotos = function(...args) {
1257
1257
  TelegramClient.prototype.getUsers = function(...args) {
1258
1258
  return updateProfile.getUsers(this._client, ...args);
1259
1259
  };
1260
+ TelegramClient.prototype.isPeerAvailable = function(...args) {
1261
+ return updateProfile.isPeerAvailable(this._client, ...args);
1262
+ };
1260
1263
  TelegramClient.prototype.iterProfilePhotos = function(...args) {
1261
1264
  return updateProfile.iterProfilePhotos(this._client, ...args);
1262
1265
  };
package/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import EventEmitter from "node:events";
2
2
  import { tl } from "@mtcute/tl";
3
- import { Reloadable, MtClient, UpdatesManager, TelegramStorageManager, BusinessCallbackQuery$2, DeleteBusinessMessageUpdate$2, BusinessMessage, BotReactionCountUpdate$2, BotReactionUpdate$2, DeleteStoryUpdate$2, StoryUpdate$2, PreCheckoutQuery$2, ChatJoinRequestUpdate$2, BotChatJoinRequestUpdate$2, BotStoppedUpdate$2, HistoryReadUpdate$1, DeleteMessageUpdate$1, UserTypingUpdate$1, UserStatusUpdate$2, PollVoteUpdate$2, PollUpdate$2, InlineCallbackQuery$2, CallbackQuery$2, ChosenInlineResult$2, InlineQuery$2, ChatMemberUpdate$2, Conversation } from "./chunks/es/BbjNWA_t.js";
3
+ import { Reloadable, MtClient, UpdatesManager, TelegramStorageManager, BusinessCallbackQuery$2, DeleteBusinessMessageUpdate$2, BusinessMessage, BotReactionCountUpdate$2, BotReactionUpdate$2, DeleteStoryUpdate$2, StoryUpdate$2, PreCheckoutQuery$2, ChatJoinRequestUpdate$2, BotChatJoinRequestUpdate$2, BotStoppedUpdate$2, HistoryReadUpdate$1, DeleteMessageUpdate$1, UserTypingUpdate$1, UserStatusUpdate$2, PollVoteUpdate$2, PollUpdate$2, InlineCallbackQuery$2, CallbackQuery$2, ChosenInlineResult$2, InlineQuery$2, ChatMemberUpdate$2, Conversation } from "./chunks/es/xihQcMp0.js";
4
4
  import { MtTypeAssertionError, MtArgumentError, MtUnsupportedError } from "./chunks/es/DBMBgE7t.js";
5
5
  import { asyncResettable } from "./chunks/es/CO4G3ySK.js";
6
6
  import { LogManager } from "./chunks/es/BRgz_-S8.js";
@@ -8,8 +8,8 @@ import { isTlRpcError } from "./chunks/es/BN3qj7tU.js";
8
8
  import "@mtcute/tl-runtime";
9
9
  import { tlJsonToJson, readStringSession, writeStringSession, computeSrpParams, computeNewPasswordHash } from "./chunks/es/hecWgeql.js";
10
10
  import { setTimeoutWrap } from "./chunks/es/DY1E3mHM.js";
11
- import { BusinessConnection$2, Message$2, getPeerDialogs, _normalizeInputFile, _normalizeInputMedia, uploadFile, getDiscussionMessage, getMessages, readHistory, sendMediaGroup, sendMedia, sendText, getBusinessConnection, resolvePeerMany, resolvePeer, resolveUser, resolveChannel } from "./chunks/es/CPnecqvf.js";
12
- import { checkPassword, getPasswordHint, logOut, recoverPassword, resendCode, run, sendCode, sendRecoveryCode, signInBot, signInQr, signIn, startTest, start, isSelfPeer, answerCallbackQuery, answerInlineQuery, answerPreCheckoutQuery, deleteMyCommands, getBotInfo, getBotMenuButton, getCallbackAnswer, getGameHighScores, getInlineGameHighScores, getMyCommands, setBotInfo, setBotMenuButton, setGameScore, setInlineGameScore, setMyCommands, setMyDefaultRights, addChatMembers, archiveChats, banChatMember, createChannel, createGroup, createSupergroup, deleteChannel, deleteChatPhoto, deleteGroup, deleteHistory, deleteUserHistory, editAdminRights, getChatEventLog, getChatMember, getChatMembers, getChatPreview, getChat, getFullChat, getNearbyChats, getSimilarChannels, iterChatEventLog, iterChatMembers, joinChat, kickChatMember, leaveChat, markChatUnread, openChat, closeChat, reorderUsernames, restrictChatMember, saveDraft, setChatColor, setChatDefaultPermissions, setChatDescription, setChatPhoto, setChatTitle, setChatTtl, setChatUsername, setSlowMode, toggleContentProtection, toggleFragmentUsername, toggleJoinRequests, toggleJoinToSend, unarchiveChats, unbanChatMember, addContact, deleteContacts, getContacts, importContacts, createFolder, deleteFolder, editFolder, findDialogs, findFolder, getChatlistPreview, getFolders, iterDialogs, joinChatlist, setFoldersOrder, downloadAsBuffer, downloadAsIterable, downloadAsStream, uploadMedia, createForumTopic, deleteForumTopicHistory, editForumTopic, getForumTopicsById, getForumTopics, iterForumTopics, reorderPinnedForumTopics, toggleForumTopicClosed, toggleForumTopicPinned, toggleForum, toggleGeneralTopicHidden, createInviteLink, editInviteLink, exportInviteLink, getInviteLinkMembers, getInviteLink, getInviteLinks, getPrimaryInviteLink, hideAllJoinRequests, hideJoinRequest, iterInviteLinkMembers, iterInviteLinks, revokeInviteLink, closePoll, deleteMessagesById, deleteMessages, deleteScheduledMessages, editInlineMessage, editMessage, forwardMessagesById, forwardMessages, getAllScheduledMessages, getAvailableMessageEffects, getCallbackQueryMessage, getFactCheck, getHistory, getMessageByLink, getMessageGroup, getMessageReactionsById, getMessageReactions, getMessagesUnsafe, getReactionUsers, getReplyTo, getScheduledMessages, iterHistory, iterReactionUsers, iterSearchGlobal, iterSearchMessages, pinMessage, readReactions, searchGlobal, searchHashtag, iterSearchHashtag, searchMessages, answerText, answerMedia, answerMediaGroup, commentText, commentMedia, commentMediaGroup, sendCopyGroup, sendCopy, sendPaidReaction, quoteWithText, quoteWithMedia, quoteWithMediaGroup, sendReaction, replyText, replyMedia, replyMediaGroup, sendScheduled, sendTyping, sendVote, translateMessage, translateText, unpinAllMessages, unpinMessage, getCollectibleInfo, initTakeoutSession, _normalizePrivacyRules, changeCloudPassword, enableCloudPassword, verifyPasswordEmail, resendPasswordEmail, cancelPasswordEmail, removeCloudPassword, applyBoost, canApplyBoost, createBusinessChatLink, editBusinessChatLink, deleteBusinessChatLink, getBoostStats, getBoosts, getBusinessChatLinks, getMyBoostSlots, getStarsTransactions, iterBoosters, iterStarsTransactions, setBusinessIntro, setBusinessWorkHours, addStickerToSet, createStickerSet, deleteStickerFromSet, getCustomEmojis, getCustomEmojisFromMessages, getInstalledStickers, getMyStickerSets, getStickerSet, moveStickerInSet, replaceStickerInSet, setChatStickerSet, setStickerSetThumb, canSendStory, deleteStories, editStory, getAllStories, getPeerStories, getProfileStories, getStoriesById, getStoriesInteractions, getStoryLink, getStoryViewers, hideMyStoriesViews, incrementStoriesViews, iterAllStories, iterProfileStories, iterStoryViewers, readStories, reportStory, sendStoryReaction, sendStory, togglePeerStoriesArchived, toggleStoriesPinned, blockUser, deleteProfilePhotos, editCloseFriendsRaw, editCloseFriends, getCommonChats, getGlobalTtl, getMe, getMyUsername, getProfilePhoto, getProfilePhotos, getUsers, iterProfilePhotos, setGlobalTtl, setMyBirthday, setMyEmojiStatus, setMyProfilePhoto, setMyUsername, setOffline, unblockUser, updateProfile } from "./chunks/es/D_f8sDLe.js";
11
+ import { BusinessConnection$2, Message$2, getPeerDialogs, _normalizeInputFile, _normalizeInputMedia, uploadFile, getDiscussionMessage, getMessages, readHistory, sendMediaGroup, sendMedia, sendText, getBusinessConnection, resolvePeerMany, resolvePeer, resolveUser, resolveChannel } from "./chunks/es/Btmu4f4t.js";
12
+ import { checkPassword, getPasswordHint, logOut, recoverPassword, resendCode, run, sendCode, sendRecoveryCode, signInBot, signInQr, signIn, startTest, start, isSelfPeer, answerCallbackQuery, answerInlineQuery, answerPreCheckoutQuery, deleteMyCommands, getBotInfo, getBotMenuButton, getCallbackAnswer, getGameHighScores, getInlineGameHighScores, getMyCommands, setBotInfo, setBotMenuButton, setGameScore, setInlineGameScore, setMyCommands, setMyDefaultRights, addChatMembers, archiveChats, banChatMember, createChannel, createGroup, createSupergroup, deleteChannel, deleteChatPhoto, deleteGroup, deleteHistory, deleteUserHistory, editAdminRights, getChatEventLog, getChatMember, getChatMembers, getChatPreview, getChat, getFullChat, getNearbyChats, getSimilarChannels, iterChatEventLog, iterChatMembers, joinChat, kickChatMember, leaveChat, markChatUnread, openChat, closeChat, reorderUsernames, restrictChatMember, saveDraft, setChatColor, setChatDefaultPermissions, setChatDescription, setChatPhoto, setChatTitle, setChatTtl, setChatUsername, setSlowMode, toggleContentProtection, toggleFragmentUsername, toggleJoinRequests, toggleJoinToSend, unarchiveChats, unbanChatMember, addContact, deleteContacts, getContacts, importContacts, createFolder, deleteFolder, editFolder, findDialogs, findFolder, getChatlistPreview, getFolders, iterDialogs, joinChatlist, setFoldersOrder, downloadAsBuffer, downloadAsIterable, downloadAsStream, uploadMedia, createForumTopic, deleteForumTopicHistory, editForumTopic, getForumTopicsById, getForumTopics, iterForumTopics, reorderPinnedForumTopics, toggleForumTopicClosed, toggleForumTopicPinned, toggleForum, toggleGeneralTopicHidden, createInviteLink, editInviteLink, exportInviteLink, getInviteLinkMembers, getInviteLink, getInviteLinks, getPrimaryInviteLink, hideAllJoinRequests, hideJoinRequest, iterInviteLinkMembers, iterInviteLinks, revokeInviteLink, closePoll, deleteMessagesById, deleteMessages, deleteScheduledMessages, editInlineMessage, editMessage, forwardMessagesById, forwardMessages, getAllScheduledMessages, getAvailableMessageEffects, getCallbackQueryMessage, getFactCheck, getHistory, getMessageByLink, getMessageGroup, getMessageReactionsById, getMessageReactions, getMessagesUnsafe, getReactionUsers, getReplyTo, getScheduledMessages, iterHistory, iterReactionUsers, iterSearchGlobal, iterSearchMessages, pinMessage, readReactions, searchGlobal, searchHashtag, iterSearchHashtag, searchMessages, answerText, answerMedia, answerMediaGroup, commentText, commentMedia, commentMediaGroup, sendCopyGroup, sendCopy, sendPaidReaction, quoteWithText, quoteWithMedia, quoteWithMediaGroup, sendReaction, replyText, replyMedia, replyMediaGroup, sendScheduled, sendTyping, sendVote, translateMessage, translateText, unpinAllMessages, unpinMessage, getCollectibleInfo, initTakeoutSession, _normalizePrivacyRules, changeCloudPassword, enableCloudPassword, verifyPasswordEmail, resendPasswordEmail, cancelPasswordEmail, removeCloudPassword, applyBoost, canApplyBoost, createBusinessChatLink, editBusinessChatLink, deleteBusinessChatLink, getBoostStats, getBoosts, getBusinessChatLinks, getMyBoostSlots, getStarsTransactions, iterBoosters, iterStarsTransactions, setBusinessIntro, setBusinessWorkHours, addStickerToSet, createStickerSet, deleteStickerFromSet, getCustomEmojis, getCustomEmojisFromMessages, getInstalledStickers, getMyStickerSets, getStickerSet, moveStickerInSet, replaceStickerInSet, setChatStickerSet, setStickerSetThumb, canSendStory, deleteStories, editStory, getAllStories, getPeerStories, getProfileStories, getStoriesById, getStoriesInteractions, getStoryLink, getStoryViewers, hideMyStoriesViews, incrementStoriesViews, iterAllStories, iterProfileStories, iterStoryViewers, readStories, reportStory, sendStoryReaction, sendStory, togglePeerStoriesArchived, toggleStoriesPinned, blockUser, deleteProfilePhotos, editCloseFriendsRaw, editCloseFriends, getCommonChats, getGlobalTtl, getMe, getMyUsername, getProfilePhoto, getProfilePhotos, getUsers, isPeerAvailable, iterProfilePhotos, setGlobalTtl, setMyBirthday, setMyEmojiStatus, setMyProfilePhoto, setMyUsername, setOffline, unblockUser, updateProfile } from "./chunks/es/Jz_hDg6M.js";
13
13
  function reportUnknownError(log, error, method) {
14
14
  if (typeof fetch !== "function") return;
15
15
  fetch(`https://rpc.pwrtelegram.xyz/?code=${error.code}&method=${method}&error=${error.text}`).then((r) => r.json()).then((r) => {
@@ -1250,6 +1250,9 @@ TelegramClient.prototype.getProfilePhotos = function(...args) {
1250
1250
  TelegramClient.prototype.getUsers = function(...args) {
1251
1251
  return getUsers(this._client, ...args);
1252
1252
  };
1253
+ TelegramClient.prototype.isPeerAvailable = function(...args) {
1254
+ return isPeerAvailable(this._client, ...args);
1255
+ };
1253
1256
  TelegramClient.prototype.iterProfilePhotos = function(...args) {
1254
1257
  return iterProfilePhotos(this._client, ...args);
1255
1258
  };
@@ -4722,6 +4722,26 @@ export interface TelegramClient extends ITelegramClient {
4722
4722
  * @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object
4723
4723
  */
4724
4724
  getUsers(ids: MaybeArray<InputPeerLike>): Promise<(User | null)[]>;
4725
+ /**
4726
+ * Check whether a given peer ID can be used to actually
4727
+ * interact with the Telegram API.
4728
+ * This method checks the internal peers cache for the given
4729
+ * input peer, and returns `true` if it is available there.
4730
+ *
4731
+ * You can think of this method as a stripped down version of
4732
+ * {@link resolvePeer}, which only returns `true` or `false`.
4733
+ *
4734
+ * > **Note:** This method works offline and never sends any requests.
4735
+ * > This means that when passing a username or phone number, it will
4736
+ * > only return `true` if the user with that username/phone number
4737
+ * > is cached in the storage, and will not try to resolve the peer by calling the API,
4738
+ * > which *may* lead to false negatives.
4739
+ *
4740
+ * **Available**: ✅ both users and bots
4741
+ *
4742
+ * @returns
4743
+ */
4744
+ isPeerAvailable(peerId: InputPeerLike): Promise<boolean>;
4725
4745
  /**
4726
4746
  * Iterate over profile photos
4727
4747
  *
@@ -0,0 +1,20 @@
1
+ import { ITelegramClient } from '../../client.types.js';
2
+ import { InputPeerLike } from '../../types/index.js';
3
+ /**
4
+ * Check whether a given peer ID can be used to actually
5
+ * interact with the Telegram API.
6
+ * This method checks the internal peers cache for the given
7
+ * input peer, and returns `true` if it is available there.
8
+ *
9
+ * You can think of this method as a stripped down version of
10
+ * {@link resolvePeer}, which only returns `true` or `false`.
11
+ *
12
+ * > **Note:** This method works offline and never sends any requests.
13
+ * > This means that when passing a username or phone number, it will
14
+ * > only return `true` if the user with that username/phone number
15
+ * > is cached in the storage, and will not try to resolve the peer by calling the API,
16
+ * > which *may* lead to false negatives.
17
+ *
18
+ * @returns
19
+ */
20
+ export declare function isPeerAvailable(client: ITelegramClient, peerId: InputPeerLike): Promise<boolean>;
@@ -1,6 +1,7 @@
1
1
  import { tl } from '@mtcute/tl';
2
2
  import { ITelegramClient } from '../../client.types.js';
3
3
  import { InputPeerLike } from '../../types/peers/index.js';
4
+ export declare function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer;
4
5
  /**
5
6
  * Get the `InputPeer` of a known peer id.
6
7
  * Useful when an `InputPeer` is needed in Raw API.
@@ -262,6 +262,7 @@ export { getMyUsername } from './methods/users/get-my-username.js';
262
262
  export { getProfilePhoto } from './methods/users/get-profile-photo.js';
263
263
  export { getProfilePhotos } from './methods/users/get-profile-photos.js';
264
264
  export { getUsers } from './methods/users/get-users.js';
265
+ export { isPeerAvailable } from './methods/users/is-peer-available.js';
265
266
  export { iterProfilePhotos } from './methods/users/iter-profile-photos.js';
266
267
  export { resolvePeerMany } from './methods/users/resolve-peer-many.js';
267
268
  export { resolvePeer } from './methods/users/resolve-peer.js';
@@ -6,6 +6,8 @@ export declare namespace IPeersRepository {
6
6
  id: number;
7
7
  /** Peer access hash, as a fast string representation */
8
8
  accessHash: string;
9
+ /** Whether the peer is a "min" peer */
10
+ isMin: boolean;
9
11
  /** Peer usernames, if any */
10
12
  usernames: string[];
11
13
  /** Timestamp (in seconds) when the peer was last updated */
@@ -22,11 +24,21 @@ export declare namespace IPeersRepository {
22
24
  export interface IPeersRepository {
23
25
  /** Store the given peer */
24
26
  store: (peer: IPeersRepository.PeerInfo) => MaybePromise<void>;
25
- /** Find a peer by their `id` */
26
- getById: (id: number) => MaybePromise<IPeersRepository.PeerInfo | null>;
27
- /** Find a peer by their username (where `usernames` includes `username`) */
27
+ /**
28
+ * Find a peer by their `id`.
29
+ *
30
+ * @param allowMin Whether to allow "min" peers to be returned
31
+ */
32
+ getById: (id: number, allowMin: boolean) => MaybePromise<IPeersRepository.PeerInfo | null>;
33
+ /**
34
+ * Find a peer by their username (where `usernames` includes `username`).
35
+ * Should never return "min" peers
36
+ */
28
37
  getByUsername: (username: string) => MaybePromise<IPeersRepository.PeerInfo | null>;
29
- /** Find a peer by their `phone` */
38
+ /**
39
+ * Find a peer by their `phone`.
40
+ * Should never return "min" peers
41
+ */
30
42
  getByPhone: (phone: string) => MaybePromise<IPeersRepository.PeerInfo | null>;
31
43
  deleteAll: () => MaybePromise<void>;
32
44
  }
@@ -19,5 +19,5 @@ export declare class PeersService extends BaseService {
19
19
  getById(id: number, allowRefs?: boolean): Promise<tl.TypeInputPeer | null>;
20
20
  getByPhone(phone: string): Promise<tl.TypeInputPeer | null>;
21
21
  getByUsername(username: string): Promise<tl.TypeInputPeer | null>;
22
- getCompleteById(id: number): Promise<tl.TypeUser | tl.TypeChat | null>;
22
+ getCompleteById(id: number, allowMin?: boolean): Promise<tl.TypeUser | tl.TypeChat | null>;
23
23
  }
@@ -37,9 +37,9 @@ export declare class Chat {
37
37
  * are always available, but other fields may be omitted
38
38
  * despite being available.
39
39
  *
40
- * It was observed that these fields may be missing:
41
- * - `isMember`
42
- * - and probably more
40
+ * For a rough list of fields that may be missing, see the
41
+ * official docs for [channel](https://core.telegram.org/constructor/channel)
42
+ * and [user](https://core.telegram.org/constructor/user).
43
43
  *
44
44
  * This currently only ever happens for non-bot users, so if you are building
45
45
  * a normal bot, you can safely ignore this field.
@@ -39,12 +39,8 @@ export declare class User {
39
39
  * are always available, but other fields may be omitted
40
40
  * despite being available.
41
41
  *
42
- * It was observed that these fields may be missing:
43
- * - `username, usernames`
44
- * - `status, lastOnline, nextOffline`
45
- * - `storiesMaxId`
46
- * - `photo` - in some cases when user has some some privacy settings
47
- * - and probably more
42
+ * For a rough list of fields that may be missing, see the
43
+ * [official docs](https://core.telegram.org/constructor/user).
48
44
  *
49
45
  * This currently only ever happens for non-bot users, so if you are building
50
46
  * a normal bot, you can safely ignore this field.
@@ -12,7 +12,7 @@ export declare class ChatJoinRequestUpdate {
12
12
  readonly _peers: PeersIndex;
13
13
  constructor(raw: tl.RawUpdatePendingJoinRequests, _peers: PeersIndex);
14
14
  /**
15
- * ID of the chat/channel
15
+ * Marked ID of the chat/channel
16
16
  */
17
17
  get chatId(): number;
18
18
  /**
@@ -112,7 +112,7 @@ export declare class UpdatesManager {
112
112
  _loadUpdatesStorage(): Promise<void>;
113
113
  _saveUpdatesStorage(save?: boolean): Promise<void>;
114
114
  _addToNoDispatchIndex(updates?: tl.TypeUpdates): void;
115
- _fetchMissingPeers(upd: tl.TypeUpdate, peers: PeersIndex, allowMissing?: boolean): Promise<Set<number>>;
115
+ _fetchMissingPeers(upd: tl.TypeUpdate, peers: PeersIndex, fromDifference?: boolean): Promise<Set<number>>;
116
116
  _storeMessageReferences(msg: tl.TypeMessage): Promise<void>;
117
117
  _fetchChannelDifference(channelId: number, fallbackPts?: number): Promise<boolean>;
118
118
  _fetchChannelDifferenceLater(requestedDiff: Map<number, Promise<void>>, channelId: number, fallbackPts?: number): void;
package/index.cjs CHANGED
@@ -8,8 +8,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
8
  const Long = require("long");
9
9
  const conditionVariable = require("./chunks/cjs/eX3zeDAz.js");
10
10
  const tl = require("@mtcute/tl");
11
- const client = require("./chunks/cjs/CS5mxbeO.js");
12
- const storyViewer = require("./chunks/cjs/UVFvMVPt.js");
11
+ const client = require("./chunks/cjs/BO3RV06t.js");
12
+ const storyViewer = require("./chunks/cjs/chPq0GcA.js");
13
13
  const controllablePromise = require("./chunks/cjs/CZAB54t2.js");
14
14
  const peersIndex = require("./chunks/cjs/ija5tZ1t.js");
15
15
  require("@mtcute/tl-runtime");
@@ -638,18 +638,24 @@ class MemoryPeersRepository {
638
638
  if (peer2.phone) this.state.phoneIndex.set(peer2.phone, peer2.id);
639
639
  this.state.entities.set(peer2.id, peer2);
640
640
  }
641
- getById(id) {
642
- return this.state.entities.get(id) ?? null;
641
+ getById(id, allowMin) {
642
+ const ent = this.state.entities.get(id);
643
+ if (!ent || ent.isMin && !allowMin) return null;
644
+ return ent;
643
645
  }
644
646
  getByUsername(username) {
645
647
  const id = this.state.usernameIndex.get(username.toLowerCase());
646
648
  if (!id) return null;
647
- return this.state.entities.get(id) ?? null;
649
+ const ent = this.state.entities.get(id);
650
+ if (!ent || ent.isMin) return null;
651
+ return ent;
648
652
  }
649
653
  getByPhone(phone) {
650
654
  const id = this.state.phoneIndex.get(phone);
651
655
  if (!id) return null;
652
- return this.state.entities.get(id) ?? null;
656
+ const ent = this.state.entities.get(id);
657
+ if (!ent || ent.isMin) return null;
658
+ return ent;
653
659
  }
654
660
  deleteAll() {
655
661
  this.state.entities.clear();
@@ -966,6 +972,7 @@ function mapPeerDto(dto) {
966
972
  return {
967
973
  id: dto.id,
968
974
  accessHash: dto.hash,
975
+ isMin: dto.isMin === 1,
969
976
  usernames: JSON.parse(dto.usernames),
970
977
  updated: dto.updated,
971
978
  phone: dto.phone || void 0,
@@ -989,16 +996,20 @@ class SqlitePeersRepository {
989
996
  create index idx_peers_phone on peers (phone);
990
997
  `);
991
998
  });
999
+ _driver.registerMigration("peers", 2, (db) => {
1000
+ db.exec("alter table peers add column isMin integer not null default false;");
1001
+ });
992
1002
  _driver.onLoad((db) => {
993
1003
  this._loaded = true;
994
1004
  this._store = db.prepare(
995
- "insert or replace into peers (id, hash, usernames, updated, phone, complete) values (?, ?, ?, ?, ?, ?)"
1005
+ "insert or replace into peers (id, hash, isMin, usernames, updated, phone, complete) values (?, ?, ?, ?, ?, ?, ?)"
996
1006
  );
997
- this._getById = db.prepare("select * from peers where id = ?");
1007
+ this._getById = db.prepare("select * from peers where id = ? and isMin = false");
1008
+ this._getByIdAllowMin = db.prepare("select * from peers where id = ?");
998
1009
  this._getByUsername = db.prepare(
999
- "select * from peers where exists (select 1 from json_each(usernames) where value = ?)"
1010
+ "select * from peers where exists (select 1 from json_each(usernames) where value = ?) and isMin = false"
1000
1011
  );
1001
- this._getByPhone = db.prepare("select * from peers where phone = ?");
1012
+ this._getByPhone = db.prepare("select * from peers where phone = ? and isMin = false");
1002
1013
  this._delAll = db.prepare("delete from peers");
1003
1014
  });
1004
1015
  _driver.registerLegacyMigration("peers", (db) => {
@@ -1016,6 +1027,7 @@ class SqlitePeersRepository {
1016
1027
  this._driver._writeLater(this._store, [
1017
1028
  peer2.id,
1018
1029
  peer2.accessHash,
1030
+ peer2.isMin ? 1 : 0,
1019
1031
  JSON.stringify(peer2.usernames),
1020
1032
  peer2.updated,
1021
1033
  peer2.phone ?? null,
@@ -1023,9 +1035,10 @@ class SqlitePeersRepository {
1023
1035
  ]);
1024
1036
  }
1025
1037
  _getById;
1026
- getById(id) {
1038
+ _getByIdAllowMin;
1039
+ getById(id, allowMin) {
1027
1040
  this._ensureLoaded();
1028
- const row = this._getById.get(id);
1041
+ const row = (allowMin ? this._getByIdAllowMin : this._getById).get(id);
1029
1042
  if (!row) return null;
1030
1043
  return mapPeerDto(row);
1031
1044
  }