@mtcute/core 0.23.3 → 0.24.1

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.
Files changed (73) hide show
  1. package/client.cjs +9 -2
  2. package/client.js +9 -2
  3. package/highlevel/base.cjs +15 -3
  4. package/highlevel/base.d.cts +4 -1
  5. package/highlevel/base.d.ts +4 -1
  6. package/highlevel/base.js +15 -3
  7. package/highlevel/client.d.cts +12 -2
  8. package/highlevel/client.d.ts +12 -2
  9. package/highlevel/client.types.d.cts +2 -1
  10. package/highlevel/client.types.d.ts +2 -1
  11. package/highlevel/methods/files/download-iterable.cjs +1 -1
  12. package/highlevel/methods/files/download-iterable.js +1 -1
  13. package/highlevel/methods/premium/transfer-star-gift.cjs +2 -2
  14. package/highlevel/methods/premium/transfer-star-gift.d.cts +1 -1
  15. package/highlevel/methods/premium/transfer-star-gift.d.ts +1 -1
  16. package/highlevel/methods/premium/transfer-star-gift.js +2 -2
  17. package/highlevel/methods/users/resolve-peer.cjs +63 -70
  18. package/highlevel/methods/users/resolve-peer.d.cts +2 -1
  19. package/highlevel/methods/users/resolve-peer.d.ts +2 -1
  20. package/highlevel/methods/users/resolve-peer.js +61 -68
  21. package/highlevel/methods/users/resolve-phone-number.cjs +36 -0
  22. package/highlevel/methods/users/resolve-phone-number.d.cts +10 -0
  23. package/highlevel/methods/users/resolve-phone-number.d.ts +10 -0
  24. package/highlevel/methods/users/resolve-phone-number.js +31 -0
  25. package/highlevel/methods.d.cts +6 -4
  26. package/highlevel/methods.d.ts +6 -4
  27. package/highlevel/types/peers/peer.d.cts +2 -3
  28. package/highlevel/types/peers/peer.d.ts +2 -3
  29. package/highlevel/types/premium/stars-gift-unique.cjs +2 -1
  30. package/highlevel/types/premium/stars-gift-unique.d.cts +2 -2
  31. package/highlevel/types/premium/stars-gift-unique.d.ts +2 -2
  32. package/highlevel/types/premium/stars-gift-unique.js +2 -1
  33. package/highlevel/types/premium/stars-transaction.cjs +1 -1
  34. package/highlevel/types/premium/stars-transaction.d.cts +2 -2
  35. package/highlevel/types/premium/stars-transaction.d.ts +2 -2
  36. package/highlevel/types/premium/stars-transaction.js +1 -1
  37. package/highlevel/updates/manager.cjs +35 -26
  38. package/highlevel/updates/manager.d.cts +6 -6
  39. package/highlevel/updates/manager.d.ts +6 -6
  40. package/highlevel/updates/manager.js +35 -26
  41. package/highlevel/updates/types.d.cts +6 -6
  42. package/highlevel/updates/types.d.ts +6 -6
  43. package/highlevel/worker/invoker.cjs +1 -0
  44. package/highlevel/worker/invoker.js +1 -0
  45. package/highlevel/worker/port.cjs +7 -5
  46. package/highlevel/worker/port.d.cts +3 -2
  47. package/highlevel/worker/port.d.ts +3 -2
  48. package/highlevel/worker/port.js +7 -5
  49. package/methods.cjs +2 -0
  50. package/methods.js +2 -0
  51. package/network/client.cjs +12 -8
  52. package/network/client.d.cts +4 -1
  53. package/network/client.d.ts +4 -1
  54. package/network/client.js +12 -8
  55. package/network/network-manager.cjs +1 -1
  56. package/network/network-manager.js +1 -1
  57. package/network/session-connection.cjs +1 -0
  58. package/network/session-connection.js +1 -0
  59. package/package.json +1 -1
  60. package/utils/index.d.cts +0 -1
  61. package/utils/index.d.ts +0 -1
  62. package/utils/sorted-array.cjs +6 -0
  63. package/utils/sorted-array.d.cts +2 -0
  64. package/utils/sorted-array.d.ts +2 -0
  65. package/utils/sorted-array.js +6 -0
  66. package/utils.cjs +0 -2
  67. package/utils.js +0 -2
  68. package/utils/linked-list.cjs +0 -65
  69. package/utils/linked-list.d.cts +0 -21
  70. package/utils/linked-list.d.ts +0 -21
  71. package/utils/linked-list.js +0 -60
  72. package/utils/linked-list.test.d.cts +0 -1
  73. package/utils/linked-list.test.d.ts +0 -1
package/client.cjs CHANGED
@@ -263,6 +263,7 @@ const isPeerAvailable = require("./highlevel/methods/users/is-peer-available.cjs
263
263
  const iterProfilePhotos = require("./highlevel/methods/users/iter-profile-photos.cjs");
264
264
  const resolvePeerMany = require("./highlevel/methods/users/resolve-peer-many.cjs");
265
265
  const resolvePeer = require("./highlevel/methods/users/resolve-peer.cjs");
266
+ const resolvePhoneNumber = require("./highlevel/methods/users/resolve-phone-number.cjs");
266
267
  const setEmojiStatus = require("./highlevel/methods/users/set-emoji-status.cjs");
267
268
  const setGlobalTtl = require("./highlevel/methods/users/set-global-ttl.cjs");
268
269
  const setMyBirthday = require("./highlevel/methods/users/set-my-birthday.cjs");
@@ -1270,6 +1271,9 @@ TelegramClient.prototype.resolveUser = function(...args) {
1270
1271
  TelegramClient.prototype.resolveChannel = function(...args) {
1271
1272
  return resolvePeer.resolveChannel(this._client, ...args);
1272
1273
  };
1274
+ TelegramClient.prototype.resolvePhoneNumber = function(...args) {
1275
+ return resolvePhoneNumber.resolvePhoneNumber(this._client, ...args);
1276
+ };
1273
1277
  TelegramClient.prototype.setMyEmojiStatus = function(...args) {
1274
1278
  return setEmojiStatus.setMyEmojiStatus(this._client, ...args);
1275
1279
  };
@@ -1306,8 +1310,11 @@ TelegramClient.prototype.prepare = function(...args) {
1306
1310
  TelegramClient.prototype.connect = function(...args) {
1307
1311
  return this._client.connect(...args);
1308
1312
  };
1309
- TelegramClient.prototype.close = function(...args) {
1310
- return this._client.close(...args);
1313
+ TelegramClient.prototype.disconnect = function(...args) {
1314
+ return this._client.disconnect(...args);
1315
+ };
1316
+ TelegramClient.prototype.destroy = function(...args) {
1317
+ return this._client.destroy(...args);
1311
1318
  };
1312
1319
  TelegramClient.prototype.notifyLoggedIn = function(...args) {
1313
1320
  return this._client.notifyLoggedIn(...args);
package/client.js CHANGED
@@ -256,6 +256,7 @@ import { isPeerAvailable } from "./highlevel/methods/users/is-peer-available.js"
256
256
  import { iterProfilePhotos } from "./highlevel/methods/users/iter-profile-photos.js";
257
257
  import { resolvePeerMany } from "./highlevel/methods/users/resolve-peer-many.js";
258
258
  import { resolvePeer, resolveUser, resolveChannel } from "./highlevel/methods/users/resolve-peer.js";
259
+ import { resolvePhoneNumber } from "./highlevel/methods/users/resolve-phone-number.js";
259
260
  import { setMyEmojiStatus, setEmojiStatus } from "./highlevel/methods/users/set-emoji-status.js";
260
261
  import { setGlobalTtl } from "./highlevel/methods/users/set-global-ttl.js";
261
262
  import { setMyBirthday } from "./highlevel/methods/users/set-my-birthday.js";
@@ -1263,6 +1264,9 @@ TelegramClient.prototype.resolveUser = function(...args) {
1263
1264
  TelegramClient.prototype.resolveChannel = function(...args) {
1264
1265
  return resolveChannel(this._client, ...args);
1265
1266
  };
1267
+ TelegramClient.prototype.resolvePhoneNumber = function(...args) {
1268
+ return resolvePhoneNumber(this._client, ...args);
1269
+ };
1266
1270
  TelegramClient.prototype.setMyEmojiStatus = function(...args) {
1267
1271
  return setMyEmojiStatus(this._client, ...args);
1268
1272
  };
@@ -1299,8 +1303,11 @@ TelegramClient.prototype.prepare = function(...args) {
1299
1303
  TelegramClient.prototype.connect = function(...args) {
1300
1304
  return this._client.connect(...args);
1301
1305
  };
1302
- TelegramClient.prototype.close = function(...args) {
1303
- return this._client.close(...args);
1306
+ TelegramClient.prototype.disconnect = function(...args) {
1307
+ return this._client.disconnect(...args);
1308
+ };
1309
+ TelegramClient.prototype.destroy = function(...args) {
1310
+ return this._client.destroy(...args);
1304
1311
  };
1305
1312
  TelegramClient.prototype.notifyLoggedIn = function(...args) {
1306
1313
  return this._client.notifyLoggedIn(...args);
@@ -98,6 +98,7 @@ class BaseTelegramClient {
98
98
  // used in a hot path, avoid extra function calls
99
99
  _connected = false;
100
100
  _connect = functionUtils.asyncResettable(async () => {
101
+ if (this.#destroyed) throw new Error("Client is destroyed");
101
102
  await this._prepare.run();
102
103
  await this.mt.connect();
103
104
  this._connected = true;
@@ -114,14 +115,24 @@ class BaseTelegramClient {
114
115
  get isConnected() {
115
116
  return this._connected;
116
117
  }
117
- async close() {
118
- this.timers.destroy();
118
+ async disconnect() {
119
119
  this._connected = false;
120
- await this.mt.close();
120
+ this.timers.destroy();
121
121
  this.updates?.stopLoop();
122
122
  await this.storage.close();
123
123
  this._prepare.reset();
124
124
  this._connect.reset();
125
+ await this.mt.disconnect();
126
+ }
127
+ #destroyed = false;
128
+ async destroy() {
129
+ if (this.#destroyed) return;
130
+ this.#destroyed = true;
131
+ await this.disconnect();
132
+ await this.mt.destroy();
133
+ }
134
+ [Symbol.asyncDispose]() {
135
+ return this.destroy();
125
136
  }
126
137
  async notifyLoggedIn(auth) {
127
138
  const user = this.mt.network.notifyLoggedIn(auth);
@@ -202,6 +213,7 @@ class BaseTelegramClient {
202
213
  if (data.self) {
203
214
  await this.storage.self.store(data.self);
204
215
  }
216
+ await this.mt.storage.provider.authKeys.deleteAll();
205
217
  await this.mt.storage.provider.authKeys.set(data.primaryDcs.main.id, data.authKey);
206
218
  await this.mt.storage.save();
207
219
  }
@@ -20,6 +20,7 @@ export interface BaseTelegramClientOptions extends MtClientOptions {
20
20
  updates?: UpdatesManagerParams | false;
21
21
  }
22
22
  export declare class BaseTelegramClient implements ITelegramClient {
23
+ #private;
23
24
  readonly params: BaseTelegramClientOptions;
24
25
  readonly updates?: UpdatesManager;
25
26
  readonly log: Logger;
@@ -54,7 +55,9 @@ export declare class BaseTelegramClient implements ITelegramClient {
54
55
  */
55
56
  connect(): Promise<void>;
56
57
  get isConnected(): boolean;
57
- close(): Promise<void>;
58
+ disconnect(): Promise<void>;
59
+ destroy(): Promise<void>;
60
+ [Symbol.asyncDispose](): Promise<void>;
58
61
  notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser>;
59
62
  notifyLoggedOut(): Promise<void>;
60
63
  notifyChannelOpened(channelId: number, pts?: number): Promise<boolean>;
@@ -20,6 +20,7 @@ export interface BaseTelegramClientOptions extends MtClientOptions {
20
20
  updates?: UpdatesManagerParams | false;
21
21
  }
22
22
  export declare class BaseTelegramClient implements ITelegramClient {
23
+ #private;
23
24
  readonly params: BaseTelegramClientOptions;
24
25
  readonly updates?: UpdatesManager;
25
26
  readonly log: Logger;
@@ -54,7 +55,9 @@ export declare class BaseTelegramClient implements ITelegramClient {
54
55
  */
55
56
  connect(): Promise<void>;
56
57
  get isConnected(): boolean;
57
- close(): Promise<void>;
58
+ disconnect(): Promise<void>;
59
+ destroy(): Promise<void>;
60
+ [Symbol.asyncDispose](): Promise<void>;
58
61
  notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser>;
59
62
  notifyLoggedOut(): Promise<void>;
60
63
  notifyChannelOpened(channelId: number, pts?: number): Promise<boolean>;
package/highlevel/base.js CHANGED
@@ -91,6 +91,7 @@ class BaseTelegramClient {
91
91
  // used in a hot path, avoid extra function calls
92
92
  _connected = false;
93
93
  _connect = asyncResettable(async () => {
94
+ if (this.#destroyed) throw new Error("Client is destroyed");
94
95
  await this._prepare.run();
95
96
  await this.mt.connect();
96
97
  this._connected = true;
@@ -107,14 +108,24 @@ class BaseTelegramClient {
107
108
  get isConnected() {
108
109
  return this._connected;
109
110
  }
110
- async close() {
111
- this.timers.destroy();
111
+ async disconnect() {
112
112
  this._connected = false;
113
- await this.mt.close();
113
+ this.timers.destroy();
114
114
  this.updates?.stopLoop();
115
115
  await this.storage.close();
116
116
  this._prepare.reset();
117
117
  this._connect.reset();
118
+ await this.mt.disconnect();
119
+ }
120
+ #destroyed = false;
121
+ async destroy() {
122
+ if (this.#destroyed) return;
123
+ this.#destroyed = true;
124
+ await this.disconnect();
125
+ await this.mt.destroy();
126
+ }
127
+ [Symbol.asyncDispose]() {
128
+ return this.destroy();
118
129
  }
119
130
  async notifyLoggedIn(auth) {
120
131
  const user = this.mt.network.notifyLoggedIn(auth);
@@ -195,6 +206,7 @@ class BaseTelegramClient {
195
206
  if (data.self) {
196
207
  await this.storage.self.store(data.self);
197
208
  }
209
+ await this.mt.storage.provider.authKeys.deleteAll();
198
210
  await this.mt.storage.provider.authKeys.set(data.primaryDcs.main.id, data.authKey);
199
211
  await this.mt.storage.save();
200
212
  }
@@ -4246,7 +4246,7 @@ export interface TelegramClient extends ITelegramClient {
4246
4246
  /** Star gift to transfer */
4247
4247
  gift: InputStarGift;
4248
4248
  /** ID of the user to transfer the gift to */
4249
- recepient: InputPeerLike;
4249
+ recipient: InputPeerLike;
4250
4250
  /**
4251
4251
  * Whether to dispatch the new message event
4252
4252
  * to the client's update handler.
@@ -5037,7 +5037,7 @@ export interface TelegramClient extends ITelegramClient {
5037
5037
  * **Available**: ✅ both users and bots
5038
5038
  *
5039
5039
  * @param peerId The peer identifier that you want to extract the `InputPeer` from.
5040
- * @param [force=false] Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
5040
+ * @param [force=false] Whether to force re-fetch the peer from the server
5041
5041
  */
5042
5042
  resolvePeer(peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputPeer>;
5043
5043
  /**
@@ -5052,6 +5052,16 @@ export interface TelegramClient extends ITelegramClient {
5052
5052
  *
5053
5053
  */
5054
5054
  resolveChannel(peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputChannel>;
5055
+ /**
5056
+ * Get the `InputPeer` by user's phone number.
5057
+ * Useful when an `InputPeer` is needed in Raw API.
5058
+ *
5059
+ * **Available**: ✅ both users and bots
5060
+ *
5061
+ * @param phone Phone number of the user
5062
+ * @param [force=false] Whether to force re-fetch the peer from the server
5063
+ */
5064
+ resolvePhoneNumber(phone: string, force?: boolean): Promise<tl.TypeInputPeer>;
5055
5065
  /**
5056
5066
  * Set an emoji status for the current user
5057
5067
  *
@@ -4246,7 +4246,7 @@ export interface TelegramClient extends ITelegramClient {
4246
4246
  /** Star gift to transfer */
4247
4247
  gift: InputStarGift;
4248
4248
  /** ID of the user to transfer the gift to */
4249
- recepient: InputPeerLike;
4249
+ recipient: InputPeerLike;
4250
4250
  /**
4251
4251
  * Whether to dispatch the new message event
4252
4252
  * to the client's update handler.
@@ -5037,7 +5037,7 @@ export interface TelegramClient extends ITelegramClient {
5037
5037
  * **Available**: ✅ both users and bots
5038
5038
  *
5039
5039
  * @param peerId The peer identifier that you want to extract the `InputPeer` from.
5040
- * @param [force=false] Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
5040
+ * @param [force=false] Whether to force re-fetch the peer from the server
5041
5041
  */
5042
5042
  resolvePeer(peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputPeer>;
5043
5043
  /**
@@ -5052,6 +5052,16 @@ export interface TelegramClient extends ITelegramClient {
5052
5052
  *
5053
5053
  */
5054
5054
  resolveChannel(peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputChannel>;
5055
+ /**
5056
+ * Get the `InputPeer` by user's phone number.
5057
+ * Useful when an `InputPeer` is needed in Raw API.
5058
+ *
5059
+ * **Available**: ✅ both users and bots
5060
+ *
5061
+ * @param phone Phone number of the user
5062
+ * @param [force=false] Whether to force re-fetch the peer from the server
5063
+ */
5064
+ resolvePhoneNumber(phone: string, force?: boolean): Promise<tl.TypeInputPeer>;
5055
5065
  /**
5056
5066
  * Set an emoji status for the current user
5057
5067
  *
@@ -32,7 +32,8 @@ export interface ITelegramClient {
32
32
  readonly platform: ICorePlatform;
33
33
  prepare(): Promise<void>;
34
34
  connect(): Promise<void>;
35
- close(): Promise<void>;
35
+ disconnect(): Promise<void>;
36
+ destroy(): Promise<void>;
36
37
  notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser>;
37
38
  notifyLoggedOut(): Promise<void>;
38
39
  notifyChannelOpened(channelId: number, pts?: number): Promise<boolean>;
@@ -32,7 +32,8 @@ export interface ITelegramClient {
32
32
  readonly platform: ICorePlatform;
33
33
  prepare(): Promise<void>;
34
34
  connect(): Promise<void>;
35
- close(): Promise<void>;
35
+ disconnect(): Promise<void>;
36
+ destroy(): Promise<void>;
36
37
  notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser>;
37
38
  notifyLoggedOut(): Promise<void>;
38
39
  notifyChannelOpened(channelId: number, pts?: number): Promise<boolean>;
@@ -112,7 +112,7 @@ async function* downloadAsIterable(client, input, params) {
112
112
  _: isWeb ? "upload.getWebFile" : "upload.getFile",
113
113
  // eslint-disable-next-line
114
114
  location,
115
- offset: chunkSize * chunk,
115
+ offset: offset + chunkSize * chunk,
116
116
  limit: chunkSize
117
117
  },
118
118
  {
@@ -105,7 +105,7 @@ async function* downloadAsIterable(client, input, params) {
105
105
  _: isWeb ? "upload.getWebFile" : "upload.getFile",
106
106
  // eslint-disable-next-line
107
107
  location,
108
- offset: chunkSize * chunk,
108
+ offset: offset + chunkSize * chunk,
109
109
  limit: chunkSize
110
110
  },
111
111
  {
@@ -11,11 +11,11 @@ const findInUpdate = require("../messages/find-in-update.cjs");
11
11
  const resolvePeer = require("../users/resolve-peer.cjs");
12
12
  const _normalizeInputStarGift = require("./_normalize-input-star-gift.cjs");
13
13
  async function transferStarGift(client, params) {
14
- const { gift, recepient, shouldDispatch } = params;
14
+ const { gift, recipient, shouldDispatch } = params;
15
15
  const invoice = {
16
16
  _: "inputInvoiceStarGiftTransfer",
17
17
  stargift: await _normalizeInputStarGift._normalizeInputStarGift(client, gift),
18
- toId: await resolvePeer.resolvePeer(client, recepient)
18
+ toId: await resolvePeer.resolvePeer(client, recipient)
19
19
  };
20
20
  let updates;
21
21
  try {
@@ -15,7 +15,7 @@ export declare function transferStarGift(client: ITelegramClient, params: {
15
15
  /** Star gift to transfer */
16
16
  gift: InputStarGift;
17
17
  /** ID of the user to transfer the gift to */
18
- recepient: InputPeerLike;
18
+ recipient: InputPeerLike;
19
19
  /**
20
20
  * Whether to dispatch the new message event
21
21
  * to the client's update handler.
@@ -15,7 +15,7 @@ export declare function transferStarGift(client: ITelegramClient, params: {
15
15
  /** Star gift to transfer */
16
16
  gift: InputStarGift;
17
17
  /** ID of the user to transfer the gift to */
18
- recepient: InputPeerLike;
18
+ recipient: InputPeerLike;
19
19
  /**
20
20
  * Whether to dispatch the new message event
21
21
  * to the client's update handler.
@@ -4,11 +4,11 @@ import { _findMessageInUpdate } from "../messages/find-in-update.js";
4
4
  import { resolvePeer } from "../users/resolve-peer.js";
5
5
  import { _normalizeInputStarGift } from "./_normalize-input-star-gift.js";
6
6
  async function transferStarGift(client, params) {
7
- const { gift, recepient, shouldDispatch } = params;
7
+ const { gift, recipient, shouldDispatch } = params;
8
8
  const invoice = {
9
9
  _: "inputInvoiceStarGiftTransfer",
10
10
  stargift: await _normalizeInputStarGift(client, gift),
11
- toId: await resolvePeer(client, recepient)
11
+ toId: await resolvePeer(client, recipient)
12
12
  };
13
13
  let updates;
14
14
  try {
@@ -5,13 +5,15 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
5
5
  }
6
6
  "use strict";
7
7
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
+ const utils = require("@fuman/utils");
8
9
  const tl = require("@mtcute/tl");
9
10
  const Long = require("long");
10
- const errors$1 = require("../../../types/errors.cjs");
11
+ const errors = require("../../../types/errors.cjs");
11
12
  const peerUtils = require("../../../utils/peer-utils.cjs");
12
- const errors = require("../../types/errors.cjs");
13
+ const errors$1 = require("../../types/errors.cjs");
13
14
  const peerUtils$1 = require("../../utils/peer-utils.cjs");
14
15
  const batchedQueries = require("../chats/batched-queries.cjs");
16
+ const resolvePhoneNumber = require("./resolve-phone-number.cjs");
15
17
  function _normalizePeerId(peerId) {
16
18
  if (typeof peerId === "object") {
17
19
  if (tl.tl.isAnyPeer(peerId)) {
@@ -34,6 +36,43 @@ function _normalizePeerId(peerId) {
34
36
  }
35
37
  return peerId;
36
38
  }
39
+ function _handleContactsResolvedPeer(peerId, res) {
40
+ if (res.peer._ === "peerUser") {
41
+ const id = res.peer.userId;
42
+ const found = res.users.find((it) => it.id === id);
43
+ if (found && found._ === "user") {
44
+ if (!found.accessHash) {
45
+ throw new errors$1.MtPeerNotFoundError(
46
+ `Peer (user) with username ${peerId} was found, but it has no access hash`
47
+ );
48
+ }
49
+ return {
50
+ _: "inputPeerUser",
51
+ userId: found.id,
52
+ accessHash: found.accessHash
53
+ };
54
+ }
55
+ } else if (res.peer._ === "peerChannel") {
56
+ const id = res.peer.channelId;
57
+ const found = res.chats.find((it) => it.id === id);
58
+ if (found) {
59
+ if (!(found._ === "channel" || found._ === "channelForbidden")) {
60
+ throw new errors.MtTypeAssertionError("ResolvedPeer#chats", "channel", found._);
61
+ }
62
+ if (!found.accessHash) {
63
+ throw new errors$1.MtPeerNotFoundError(`Peer (channel) with ${peerId} was found, but it has no access hash`);
64
+ }
65
+ return {
66
+ _: "inputPeerChannel",
67
+ channelId: found.id,
68
+ accessHash: found.accessHash
69
+ };
70
+ }
71
+ } else {
72
+ throw new errors.MtTypeAssertionError("ResolvedPeer#peer", "user or channel", res.peer._);
73
+ }
74
+ utils.unreachable();
75
+ }
37
76
  async function resolvePeer(client, peerId, force = false) {
38
77
  peerId = _normalizePeerId(peerId);
39
78
  if (typeof peerId === "object") {
@@ -45,76 +84,29 @@ async function resolvePeer(client, peerId, force = false) {
45
84
  }
46
85
  if (typeof peerId === "string") {
47
86
  if (peerId === "self" || peerId === "me") return { _: "inputPeerSelf" };
48
- peerId = peerId.replace(/[@+\s()]/g, "");
49
- let res;
50
- if (peerId.match(/^\d+$/)) {
51
- const fromStorage = await client.storage.peers.getByPhone(peerId);
87
+ peerId = peerId.replace(/^@/, "");
88
+ if (peerId.match(/^\d/)) {
89
+ throw new errors.MtArgumentError(
90
+ `Invalid username: ${peerId}. If you wanted to resolve by user ID, pass a number instead. If you wanted to resolve by phone number, use resolvePhoneNumber instead.`
91
+ );
92
+ }
93
+ if (!force) {
94
+ const fromStorage = await client.storage.peers.getByUsername(peerId);
52
95
  if (fromStorage) return fromStorage;
53
- try {
54
- res = await client.call({
55
- _: "contacts.resolvePhone",
56
- phone: peerId
57
- });
58
- } catch (e) {
59
- if (tl.tl.RpcError.is(e, "PHONE_NOT_OCCUPIED")) {
60
- throw new errors.MtPeerNotFoundError(`Peer with phone number ${peerId} was not found`);
61
- } else {
62
- throw e;
63
- }
64
- }
65
- } else {
66
- if (!force) {
67
- const fromStorage = await client.storage.peers.getByUsername(peerId);
68
- if (fromStorage) return fromStorage;
69
- }
70
- try {
71
- res = await client.call({
72
- _: "contacts.resolveUsername",
73
- username: peerId
74
- });
75
- } catch (e) {
76
- if (tl.tl.RpcError.is(e, "USERNAME_NOT_OCCUPIED")) {
77
- throw new errors.MtPeerNotFoundError(`Peer with username ${peerId} was not found`);
78
- } else {
79
- throw e;
80
- }
81
- }
82
96
  }
83
- if (res.peer._ === "peerUser") {
84
- const id = res.peer.userId;
85
- const found = res.users.find((it) => it.id === id);
86
- if (found && found._ === "user") {
87
- if (!found.accessHash) {
88
- throw new errors.MtPeerNotFoundError(
89
- `Peer (user) with username ${peerId} was found, but it has no access hash`
90
- );
91
- }
92
- return {
93
- _: "inputPeerUser",
94
- userId: found.id,
95
- accessHash: found.accessHash
96
- };
97
- }
98
- } else if (res.peer._ === "peerChannel") {
99
- const id = res.peer.channelId;
100
- const found = res.chats.find((it) => it.id === id);
101
- if (found) {
102
- if (!(found._ === "channel" || found._ === "channelForbidden")) {
103
- throw new errors$1.MtTypeAssertionError("contacts.resolveUsername#chats", "channel", found._);
104
- }
105
- if (!found.accessHash) {
106
- throw new errors.MtPeerNotFoundError(`Peer (channel) with ${peerId} was found, but it has no access hash`);
107
- }
108
- return {
109
- _: "inputPeerChannel",
110
- channelId: found.id,
111
- accessHash: found.accessHash
112
- };
97
+ try {
98
+ const res = await client.call({
99
+ _: "contacts.resolveUsername",
100
+ username: peerId
101
+ });
102
+ return _handleContactsResolvedPeer(peerId, res);
103
+ } catch (e) {
104
+ if (tl.tl.RpcError.is(e, "USERNAME_NOT_OCCUPIED") || tl.tl.RpcError.is(e, "USERNAME_INVALID")) {
105
+ throw new errors$1.MtPeerNotFoundError(`Peer with username ${peerId} was not found`);
106
+ } else {
107
+ throw e;
113
108
  }
114
- } else {
115
- throw new errors$1.MtTypeAssertionError("contacts.resolveUsername", "user or channel", res.peer._);
116
109
  }
117
- throw new errors.MtPeerNotFoundError(`Could not find a peer by ${peerId}`);
118
110
  }
119
111
  const [peerType, bareId] = peerUtils.parseMarkedPeerId(peerId);
120
112
  if (peerType === "chat") {
@@ -133,7 +125,7 @@ async function resolvePeer(client, peerId, force = false) {
133
125
  }
134
126
  }
135
127
  if (cached._ === "user" && cached.phone) {
136
- const resolved = await resolvePeer(client, cached.phone, true);
128
+ const resolved = await resolvePhoneNumber.resolvePhoneNumber(client, cached.phone, true);
137
129
  if (peerUtils.getMarkedPeerId(resolved) === peerId) {
138
130
  return resolved;
139
131
  }
@@ -171,7 +163,7 @@ async function resolvePeer(client, peerId, force = false) {
171
163
  break;
172
164
  }
173
165
  }
174
- throw new errors.MtPeerNotFoundError(`Peer ${peerId} is not found in local cache`);
166
+ throw new errors$1.MtPeerNotFoundError(`Peer ${peerId} is not found in local cache`);
175
167
  }
176
168
  async function resolveUser(client, peerId, force = false) {
177
169
  return peerUtils$1.toInputUser(await resolvePeer(client, peerId, force), peerId);
@@ -179,6 +171,7 @@ async function resolveUser(client, peerId, force = false) {
179
171
  async function resolveChannel(client, peerId, force = false) {
180
172
  return peerUtils$1.toInputChannel(await resolvePeer(client, peerId, force), peerId);
181
173
  }
174
+ exports._handleContactsResolvedPeer = _handleContactsResolvedPeer;
182
175
  exports._normalizePeerId = _normalizePeerId;
183
176
  exports.resolveChannel = resolveChannel;
184
177
  exports.resolvePeer = resolvePeer;
@@ -2,12 +2,13 @@ import { ITelegramClient } from '../../client.types.js';
2
2
  import { InputPeerLike } from '../../types/peers/index.js';
3
3
  import { tl } from '@mtcute/tl';
4
4
  export declare function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer;
5
+ export declare function _handleContactsResolvedPeer(peerId: string, res: tl.contacts.TypeResolvedPeer): tl.TypeInputPeer;
5
6
  /**
6
7
  * Get the `InputPeer` of a known peer id.
7
8
  * Useful when an `InputPeer` is needed in Raw API.
8
9
  *
9
10
  * @param peerId The peer identifier that you want to extract the `InputPeer` from.
10
- * @param force Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
11
+ * @param force Whether to force re-fetch the peer from the server
11
12
  */
12
13
  export declare function resolvePeer(client: ITelegramClient, peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputPeer>;
13
14
  /**
@@ -2,12 +2,13 @@ import { ITelegramClient } from '../../client.types.js';
2
2
  import { InputPeerLike } from '../../types/peers/index.js';
3
3
  import { tl } from '@mtcute/tl';
4
4
  export declare function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer;
5
+ export declare function _handleContactsResolvedPeer(peerId: string, res: tl.contacts.TypeResolvedPeer): tl.TypeInputPeer;
5
6
  /**
6
7
  * Get the `InputPeer` of a known peer id.
7
8
  * Useful when an `InputPeer` is needed in Raw API.
8
9
  *
9
10
  * @param peerId The peer identifier that you want to extract the `InputPeer` from.
10
- * @param force Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
11
+ * @param force Whether to force re-fetch the peer from the server
11
12
  */
12
13
  export declare function resolvePeer(client: ITelegramClient, peerId: InputPeerLike, force?: boolean): Promise<tl.TypeInputPeer>;
13
14
  /**