teleproto 1.223.2 → 1.224.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.
package/Utils.js CHANGED
@@ -920,6 +920,12 @@ function getInputMedia(media, { isPhoto = false, attributes = undefined, forceDo
920
920
  correctAnswers: correctAnswers,
921
921
  solution: media.results.solution,
922
922
  solutionEntities: media.results.solutionEntities,
923
+ attachedMedia: media.attachedMedia
924
+ ? getInputMedia(media.attachedMedia)
925
+ : undefined,
926
+ solutionMedia: media.results.solutionMedia
927
+ ? getInputMedia(media.results.solutionMedia)
928
+ : undefined,
923
929
  });
924
930
  }
925
931
  if (media instanceof tl_1.Api.Poll) {
package/Version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "1.223.2";
1
+ export declare const version = "1.224.1";
package/Version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
- exports.version = "1.223.2";
4
+ exports.version = "1.224.1";
@@ -352,7 +352,7 @@ export declare class TelegramClient extends TelegramBaseClient {
352
352
  * );
353
353
  * ```
354
354
  */
355
- downloadFile(inputLocation: Api.TypeInputFileLocation, fileParams?: downloadMethods.DownloadFileParamsV2): Promise<string | Buffer<ArrayBufferLike> | undefined>;
355
+ downloadFile(inputLocation: Api.TypeInputFileLocation, fileParams?: downloadMethods.DownloadFileParams): Promise<string | Buffer<ArrayBufferLike> | undefined>;
356
356
  /**
357
357
  * Iterates over a file download, yielding chunks of the file.
358
358
  * This method can be used to stream files in a more convenient way, since it offers more control (pausing, resuming, etc.)
@@ -1130,6 +1130,8 @@ export declare class TelegramClient extends TelegramBaseClient {
1130
1130
  port: number;
1131
1131
  }>;
1132
1132
  /** @hidden */
1133
+ _getDownloadConcurrency(fileSize: number): Promise<number>;
1134
+ /** @hidden */
1133
1135
  _removeSender(dcId: number): void;
1134
1136
  /** @hidden */
1135
1137
  _getResponseMessage(req: any, result: any, inputChat: any): Api.TypeMessage | Map<number, Api.Message> | (Api.Message | undefined)[] | undefined;
@@ -431,7 +431,7 @@ class TelegramClient extends telegramBaseClient_1.TelegramBaseClient {
431
431
  * ```
432
432
  */
433
433
  downloadFile(inputLocation, fileParams = {}) {
434
- return downloadMethods.downloadFileV2(this, inputLocation, fileParams);
434
+ return downloadMethods.downloadFile(this, inputLocation, fileParams);
435
435
  }
436
436
  /**
437
437
  * Iterates over a file download, yielding chunks of the file.
@@ -1260,6 +1260,45 @@ class TelegramClient extends telegramBaseClient_1.TelegramBaseClient {
1260
1260
  throw new Error(`Cannot find the DC with the ID of ${dcId}`);
1261
1261
  }
1262
1262
  /** @hidden */
1263
+ async _getDownloadConcurrency(fileSize) {
1264
+ var _a, _b, _c, _d;
1265
+ if (!this._appConfig) {
1266
+ try {
1267
+ const result = await this.invoke(new tl_1.Api.help.GetAppConfig({ hash: 0 }));
1268
+ if (result instanceof tl_1.Api.help.AppConfig) {
1269
+ this._appConfig = {};
1270
+ const walk = (v) => {
1271
+ if (v instanceof tl_1.Api.JsonObject) {
1272
+ const obj = {};
1273
+ for (const kv of v.value) {
1274
+ obj[kv.key] = walk(kv.value);
1275
+ }
1276
+ return obj;
1277
+ }
1278
+ if (v instanceof tl_1.Api.JsonArray)
1279
+ return v.value.map(walk);
1280
+ if (v instanceof tl_1.Api.JsonString)
1281
+ return v.value;
1282
+ if (v instanceof tl_1.Api.JsonNumber)
1283
+ return v.value;
1284
+ if (v instanceof tl_1.Api.JsonBool)
1285
+ return v.value;
1286
+ if (v instanceof tl_1.Api.JsonNull)
1287
+ return null;
1288
+ return v;
1289
+ };
1290
+ this._appConfig = walk(result.config);
1291
+ }
1292
+ }
1293
+ catch (_e) {
1294
+ this._appConfig = {};
1295
+ }
1296
+ }
1297
+ const smallLimit = (_b = (_a = this._appConfig) === null || _a === void 0 ? void 0 : _a.small_queue_max_active_operations_count) !== null && _b !== void 0 ? _b : 4;
1298
+ const largeLimit = (_d = (_c = this._appConfig) === null || _c === void 0 ? void 0 : _c.large_queue_max_active_operations_count) !== null && _d !== void 0 ? _d : 8;
1299
+ return fileSize > 20 * 1024 * 1024 ? largeLimit : smallLimit;
1300
+ }
1301
+ /** @hidden */
1263
1302
  _removeSender(dcId) {
1264
1303
  delete this._borrowedSenderPromises[dcId];
1265
1304
  }
@@ -19,30 +19,7 @@ export interface progressCallback {
19
19
  /** Does nothing for now. */
20
20
  acceptsBuffer?: boolean;
21
21
  }
22
- /**
23
- * Low level interface for downloading files
24
- */
25
22
  export interface DownloadFileParams {
26
- /** The dcId that the file belongs to. Used to borrow a sender from that DC */
27
- dcId: number;
28
- /** How much to download. The library will download until it reaches this amount.<br/>
29
- * can be useful for downloading by chunks */
30
- fileSize?: number;
31
- /** Used to determine how many download tasks should be run in parallel. anything above 16 is unstable. */
32
- workers?: number;
33
- /** How much to download in each chunk. The larger the less requests to be made. (max is 512kb). */
34
- partSizeKb?: number;
35
- /** Where to start downloading. useful for chunk downloading. */
36
- start?: number;
37
- /** Where to stop downloading. useful for chunk downloading. */
38
- end?: number;
39
- /** A callback function accepting two parameters: ``(received bytes, total)``. */
40
- progressCallback?: progressCallback;
41
- }
42
- /**
43
- * Low level interface for downloading files
44
- */
45
- export interface DownloadFileParamsV2 {
46
23
  /**
47
24
  * The output file path, directory,buffer, or stream-like object.
48
25
  * If the path exists and is a file, it will be overwritten.
@@ -60,7 +37,6 @@ export interface DownloadFileParamsV2 {
60
37
  partSizeKb?: number;
61
38
  /** Progress callback accepting one param. (progress :number) which is a float between 0 and 1 */
62
39
  progressCallback?: progressCallback;
63
- /** */
64
40
  msgData?: [EntityLike, number];
65
41
  }
66
42
  /**
@@ -112,7 +88,7 @@ export declare class GenericDownloadIter extends DirectDownloadIter {
112
88
  /** @hidden */
113
89
  export declare function iterDownload(client: TelegramClient, { file, offset, stride, limit, chunkSize, requestSize, fileSize, dcId, msgData, }: IterDownloadFunction): DirectDownloadIter;
114
90
  /** @hidden */
115
- export declare function downloadFileV2(client: TelegramClient, inputLocation: Api.TypeInputFileLocation, { outputFile, partSizeKb, fileSize, progressCallback, dcId, msgData, }: DownloadFileParamsV2): Promise<string | Buffer<ArrayBufferLike> | undefined>;
91
+ export declare function downloadFile(client: TelegramClient, inputLocation: Api.TypeInputFileLocation, { outputFile, partSizeKb, fileSize, progressCallback, dcId, msgData, }: DownloadFileParams): Promise<string | Buffer<ArrayBufferLike> | undefined>;
116
92
  /**
117
93
  * All of these are optional and will be calculated automatically if not specified.
118
94
  */
@@ -45,7 +45,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
45
45
  Object.defineProperty(exports, "__esModule", { value: true });
46
46
  exports.GenericDownloadIter = exports.DirectDownloadIter = void 0;
47
47
  exports.iterDownload = iterDownload;
48
- exports.downloadFileV2 = downloadFileV2;
48
+ exports.downloadFile = downloadFile;
49
49
  exports.downloadMedia = downloadMedia;
50
50
  exports._downloadDocument = _downloadDocument;
51
51
  exports._downloadContact = _downloadContact;
@@ -61,6 +61,7 @@ const requestIter_1 = require("../requestIter");
61
61
  const errors_1 = require("../errors");
62
62
  const fs_1 = require("fs");
63
63
  const extensions_1 = require("../extensions");
64
+ const CTR_1 = require("../crypto/CTR");
64
65
  const fs = __importStar(require("fs"));
65
66
  const path_1 = __importDefault(require("path"));
66
67
  const big_integer_1 = __importDefault(require("big-integer"));
@@ -68,12 +69,10 @@ const big_integer_1 = __importDefault(require("big-integer"));
68
69
  const sizeTypes = ["w", "y", "d", "x", "c", "m", "b", "a", "s"];
69
70
  // Chunk sizes for `upload.getFile` must be multiple of the smallest size
70
71
  const MIN_CHUNK_SIZE = 4096;
71
- const DEFAULT_CHUNK_SIZE = 64; // kb
72
72
  const ONE_MB = 1024 * 1024;
73
- const REQUEST_TIMEOUT = 15000;
74
- const DISCONNECT_SLEEP = 1000;
75
73
  const TIMED_OUT_SLEEP = 1000;
76
- const MAX_CHUNK_SIZE = 512 * 1024;
74
+ const MAX_CHUNK_SIZE = ONE_MB;
75
+ const MAX_WORKERS = 16;
77
76
  class DirectDownloadIter extends requestIter_1.RequestIter {
78
77
  constructor() {
79
78
  super(...arguments);
@@ -84,6 +83,8 @@ class DirectDownloadIter extends requestIter_1.RequestIter {
84
83
  location: fileLocation,
85
84
  offset,
86
85
  limit: requestSize,
86
+ precise: true,
87
+ cdnSupported: false,
87
88
  });
88
89
  this.total = fileSize;
89
90
  this._stride = stride;
@@ -276,21 +277,150 @@ function returnWriterValue(writer) {
276
277
  }
277
278
  }
278
279
  }
280
+ function getDownloadPartSize(fileSize) {
281
+ if (!fileSize)
282
+ return 256;
283
+ if (fileSize.lesser(10 * ONE_MB))
284
+ return 256;
285
+ if (fileSize.lesser(100 * ONE_MB))
286
+ return 512;
287
+ return 1024;
288
+ }
289
+ function computeCdnIv(initialIv, offset) {
290
+ const iv = Buffer.from(initialIv);
291
+ let carry = Math.floor(offset / 16);
292
+ for (let i = 15; i >= 0 && carry > 0; i--) {
293
+ carry += iv[i];
294
+ iv[i] = carry & 0xff;
295
+ carry >>= 8;
296
+ }
297
+ return iv;
298
+ }
299
+ async function verifyFileHashes(data, offset, hashes) {
300
+ for (const hash of hashes) {
301
+ const hashOffset = typeof hash.offset === "number"
302
+ ? hash.offset
303
+ : hash.offset.toJSNumber();
304
+ const hashLimit = hash.limit;
305
+ const localOffset = hashOffset - offset;
306
+ if (localOffset < 0 || localOffset + hashLimit > data.length)
307
+ continue;
308
+ const chunk = data.subarray(localOffset, localOffset + hashLimit);
309
+ const computed = await (0, Helpers_1.sha256)(chunk);
310
+ if (!computed.equals(hash.hash)) {
311
+ return false;
312
+ }
313
+ }
314
+ return true;
315
+ }
316
+ async function downloadChunk(client, location, offset, limit, dcId, senderRef) {
317
+ var _a, _b, _c, _d;
318
+ let timedOut = false;
319
+ while (true) {
320
+ try {
321
+ if (!senderRef.sender || !senderRef.sender.isConnected()) {
322
+ senderRef.sender = await client.getSender((_c = (_b = (_a = senderRef.sender) === null || _a === void 0 ? void 0 : _a.dcId) !== null && _b !== void 0 ? _b : dcId) !== null && _c !== void 0 ? _c : 0);
323
+ }
324
+ const result = await client.invokeWithSender(new tl_1.Api.upload.GetFile({
325
+ location,
326
+ offset,
327
+ limit,
328
+ precise: true,
329
+ cdnSupported: false,
330
+ }), senderRef.sender);
331
+ if (result instanceof tl_1.Api.upload.FileCdnRedirect) {
332
+ return await downloadFromCdn(client, senderRef, result, location, offset, limit);
333
+ }
334
+ return result.bytes;
335
+ }
336
+ catch (e) {
337
+ if (e.errorMessage === "TIMEOUT") {
338
+ if (timedOut) {
339
+ throw e;
340
+ }
341
+ timedOut = true;
342
+ client._log.info("Got timeout while downloading file, retrying once");
343
+ await (0, Helpers_1.sleep)(TIMED_OUT_SLEEP);
344
+ continue;
345
+ }
346
+ else if (e instanceof errors_1.FileMigrateError) {
347
+ client._log.info("File lives in another DC");
348
+ senderRef.sender = await client.getSender(e.newDc);
349
+ continue;
350
+ }
351
+ else if (e.errorMessage === "FLOOD_WAIT" ||
352
+ ((_d = e.errorMessage) === null || _d === void 0 ? void 0 : _d.startsWith("FLOOD_WAIT_"))) {
353
+ const seconds = e.seconds || parseInt(e.errorMessage.split("_").pop()) || 1;
354
+ client._log.warn(`Flood wait ${seconds}s during download`);
355
+ await (0, Helpers_1.sleep)(seconds * 1000);
356
+ continue;
357
+ }
358
+ throw e;
359
+ }
360
+ }
361
+ }
362
+ async function downloadFromCdn(client, originSenderRef, redirect, _location, offset, limit) {
363
+ var _a, _b, _c, _d;
364
+ const cdnSender = await client.getSender(redirect.dcId);
365
+ const offsetNum = typeof offset === "number" ? offset : offset.toJSNumber();
366
+ while (true) {
367
+ const cdnResult = await client.invokeWithSender(new tl_1.Api.upload.GetCdnFile({
368
+ fileToken: redirect.fileToken,
369
+ offset,
370
+ limit,
371
+ }), cdnSender);
372
+ if (cdnResult instanceof tl_1.Api.upload.CdnFileReuploadNeeded) {
373
+ const originSender = await client.getSender((_b = (_a = originSenderRef.sender) === null || _a === void 0 ? void 0 : _a.dcId) !== null && _b !== void 0 ? _b : 0);
374
+ await client.invokeWithSender(new tl_1.Api.upload.ReuploadCdnFile({
375
+ fileToken: redirect.fileToken,
376
+ requestToken: cdnResult.requestToken,
377
+ }), originSender);
378
+ continue;
379
+ }
380
+ const iv = computeCdnIv(redirect.encryptionIv, offsetNum);
381
+ const ctr = new CTR_1.CTR(redirect.encryptionKey, iv);
382
+ const decrypted = ctr.encrypt(cdnResult.bytes);
383
+ let hashes = redirect.fileHashes;
384
+ if (!hashes || hashes.length === 0) {
385
+ const cdnHashes = await client.invokeWithSender(new tl_1.Api.upload.GetCdnFileHashes({
386
+ fileToken: redirect.fileToken,
387
+ offset,
388
+ }), await client.getSender((_d = (_c = originSenderRef.sender) === null || _c === void 0 ? void 0 : _c.dcId) !== null && _d !== void 0 ? _d : 0));
389
+ hashes = cdnHashes;
390
+ }
391
+ if (hashes && hashes.length > 0) {
392
+ const valid = await verifyFileHashes(decrypted, offsetNum, hashes);
393
+ if (!valid) {
394
+ throw new Error("CDN file hash verification failed");
395
+ }
396
+ }
397
+ return decrypted;
398
+ }
399
+ }
279
400
  /** @hidden */
280
- async function downloadFileV2(client, inputLocation, { outputFile = undefined, partSizeKb = undefined, fileSize = undefined, progressCallback = undefined, dcId = undefined, msgData = undefined, }) {
401
+ async function downloadFile(client, inputLocation, { outputFile = undefined, partSizeKb = undefined, fileSize = undefined, progressCallback = undefined, dcId = undefined, msgData = undefined, }) {
281
402
  var _a, e_1, _b, _c;
282
403
  if (!partSizeKb) {
283
- if (!fileSize) {
284
- partSizeKb = 64;
285
- }
286
- else {
287
- partSizeKb = utils.getAppropriatedPartSize(fileSize);
288
- }
404
+ partSizeKb = getDownloadPartSize(fileSize || undefined);
289
405
  }
290
406
  const partSize = Math.floor(partSizeKb * 1024);
291
- if (partSize % MIN_CHUNK_SIZE != 0) {
407
+ if (partSize % MIN_CHUNK_SIZE !== 0) {
292
408
  throw new Error("The part size must be evenly divisible by 4096");
293
409
  }
410
+ if (fileSize && fileSize.greater(0)) {
411
+ const sizeNum = fileSize.toJSNumber();
412
+ const workers = await client._getDownloadConcurrency(sizeNum);
413
+ if (workers > 1) {
414
+ return _downloadParallel(client, inputLocation, {
415
+ outputFile,
416
+ partSize,
417
+ fileSize,
418
+ workers: Math.min(workers, MAX_WORKERS),
419
+ dcId,
420
+ progressCallback,
421
+ });
422
+ }
423
+ }
294
424
  const writer = getWriter(outputFile);
295
425
  let downloaded = big_integer_1.default.zero;
296
426
  try {
@@ -324,36 +454,49 @@ async function downloadFileV2(client, inputLocation, { outputFile = undefined, p
324
454
  closeWriter(writer);
325
455
  }
326
456
  }
327
- class Foreman {
328
- constructor(maxWorkers) {
329
- this.maxWorkers = maxWorkers;
330
- this.activeWorkers = 0;
331
- }
332
- requestWorker() {
333
- this.activeWorkers++;
334
- if (this.activeWorkers > this.maxWorkers) {
335
- this.deferred = createDeferred();
336
- return this.deferred.promise;
457
+ async function _downloadParallel(client, inputLocation, params) {
458
+ const { outputFile, partSize, fileSize, workers, dcId, progressCallback } = params;
459
+ const fileSizeNum = fileSize.toJSNumber();
460
+ const partCount = Math.ceil(fileSizeNum / partSize);
461
+ const writer = getWriter(outputFile);
462
+ let downloaded = big_integer_1.default.zero;
463
+ const senderRef = {};
464
+ senderRef.sender = await client.getSender(dcId !== null && dcId !== void 0 ? dcId : 0);
465
+ client._log.info(`Starting parallel download: ${partCount} parts, ${workers} workers, ${partSize / 1024}KB chunks`);
466
+ try {
467
+ for (let i = 0; i < partCount; i += workers) {
468
+ const batchEnd = Math.min(i + workers, partCount);
469
+ const batchPromises = [];
470
+ for (let j = i; j < batchEnd; j++) {
471
+ const offset = (0, big_integer_1.default)(j).multiply(partSize);
472
+ batchPromises.push((async (partIndex) => {
473
+ const partSenderRef = {
474
+ sender: senderRef.sender,
475
+ };
476
+ const data = await downloadChunk(client, inputLocation, offset, partSize, dcId, partSenderRef);
477
+ senderRef.sender = partSenderRef.sender;
478
+ return { index: partIndex, data };
479
+ })(j));
480
+ }
481
+ const results = await Promise.all(batchPromises);
482
+ results.sort((a, b) => a.index - b.index);
483
+ for (const { data } of results) {
484
+ await writer.write(data);
485
+ downloaded = downloaded.add(data.length);
486
+ if (progressCallback) {
487
+ if (progressCallback.isCanceled) {
488
+ throw new Error("USER_CANCELED");
489
+ }
490
+ await progressCallback(downloaded, fileSize);
491
+ }
492
+ }
337
493
  }
338
- return Promise.resolve();
494
+ return returnWriterValue(writer);
339
495
  }
340
- releaseWorker() {
341
- this.activeWorkers--;
342
- if (this.deferred && this.activeWorkers <= this.maxWorkers) {
343
- this.deferred.resolve();
344
- }
496
+ finally {
497
+ closeWriter(writer);
345
498
  }
346
499
  }
347
- function createDeferred() {
348
- let resolve;
349
- const promise = new Promise((_resolve) => {
350
- resolve = _resolve;
351
- });
352
- return {
353
- promise,
354
- resolve: resolve,
355
- };
356
- }
357
500
  /** @hidden */
358
501
  async function downloadMedia(client, messageOrMedia, outputFile, thumb, progressCallback) {
359
502
  /*
@@ -424,7 +567,7 @@ async function _downloadDocument(client, doc, outputFile, date, thumb, progressC
424
567
  return _downloadCachedPhotoSize(size, outputFile);
425
568
  }
426
569
  }
427
- return await downloadFileV2(client, new tl_1.Api.InputDocumentFileLocation({
570
+ return await downloadFile(client, new tl_1.Api.InputDocumentFileLocation({
428
571
  id: doc.id,
429
572
  accessHash: doc.accessHash,
430
573
  fileReference: doc.fileReference,
@@ -566,7 +709,7 @@ async function _downloadPhoto(client, photo, file, date, thumb, progressCallback
566
709
  else {
567
710
  fileSize = "size" in size ? size.size : 512;
568
711
  }
569
- return downloadFileV2(client, new tl_1.Api.InputPhotoFileLocation({
712
+ return downloadFile(client, new tl_1.Api.InputPhotoFileLocation({
570
713
  id: photo.id,
571
714
  accessHash: photo.accessHash,
572
715
  fileReference: photo.fileReference,
@@ -122,6 +122,10 @@ export declare abstract class TelegramBaseClient {
122
122
  /** @hidden */
123
123
  _config?: Api.Config;
124
124
  /** @hidden */
125
+ _appConfig?: {
126
+ [key: string]: any;
127
+ };
128
+ /** @hidden */
125
129
  _log: Logger;
126
130
  /** @hidden */
127
131
  _floodSleepThreshold: number;
@@ -65,6 +65,15 @@ export declare class FloodError extends RPCError {
65
65
  code: number;
66
66
  errorMessage: string;
67
67
  }
68
+ /**
69
+ * The account is frozen and cannot use this method.
70
+ * Clients should call help.getAppConfig to get freeze_since_date,
71
+ * freeze_until_date, and freeze_appeal_url.
72
+ */
73
+ export declare class FrozenError extends RPCError {
74
+ code: number;
75
+ errorMessage: string;
76
+ }
68
77
  /**
69
78
  * An internal server error occurred while a request was being processed
70
79
  * for example, there was a disruption while accessing a database or file
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimedOutError = exports.ServerError = exports.FloodError = exports.AuthKeyError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.InvalidDCError = exports.RPCError = void 0;
3
+ exports.TimedOutError = exports.ServerError = exports.FrozenError = exports.FloodError = exports.AuthKeyError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.InvalidDCError = exports.RPCError = void 0;
4
4
  const ts_custom_error_1 = require("ts-custom-error");
5
5
  class RPCError extends ts_custom_error_1.CustomError {
6
6
  constructor(message, request, code) {
@@ -107,6 +107,19 @@ class FloodError extends RPCError {
107
107
  }
108
108
  }
109
109
  exports.FloodError = FloodError;
110
+ /**
111
+ * The account is frozen and cannot use this method.
112
+ * Clients should call help.getAppConfig to get freeze_since_date,
113
+ * freeze_until_date, and freeze_appeal_url.
114
+ */
115
+ class FrozenError extends RPCError {
116
+ constructor() {
117
+ super(...arguments);
118
+ this.code = 420;
119
+ this.errorMessage = "FROZEN";
120
+ }
121
+ }
122
+ exports.FrozenError = FrozenError;
110
123
  /**
111
124
  * An internal server error occurred while a request was being processed
112
125
  * for example, there was a disruption while accessing a database or file
@@ -1,4 +1,4 @@
1
- import { InvalidDCError, FloodError, BadRequestError } from "./RPCBaseErrors";
1
+ import { InvalidDCError, FloodError, FrozenError, BadRequestError } from "./RPCBaseErrors";
2
2
  export declare class UserMigrateError extends InvalidDCError {
3
3
  newDc: number;
4
4
  constructor(args: any);
@@ -34,4 +34,10 @@ export declare class EmailUnconfirmedError extends BadRequestError {
34
34
  export declare class MsgWaitError extends FloodError {
35
35
  constructor(args: any);
36
36
  }
37
+ export declare class FrozenMethodError extends FrozenError {
38
+ constructor(args: any);
39
+ }
40
+ export declare class FrozenParticipantError extends BadRequestError {
41
+ constructor(args: any);
42
+ }
37
43
  export declare const rpcErrorRe: Map<RegExp, any>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rpcErrorRe = exports.MsgWaitError = exports.EmailUnconfirmedError = exports.NetworkMigrateError = exports.FileMigrateError = exports.FloodTestPhoneWaitError = exports.FloodWaitError = exports.SlowModeWaitError = exports.PhoneMigrateError = exports.UserMigrateError = void 0;
3
+ exports.rpcErrorRe = exports.FrozenParticipantError = exports.FrozenMethodError = exports.MsgWaitError = exports.EmailUnconfirmedError = exports.NetworkMigrateError = exports.FileMigrateError = exports.FloodTestPhoneWaitError = exports.FloodWaitError = exports.SlowModeWaitError = exports.PhoneMigrateError = exports.UserMigrateError = void 0;
4
4
  const RPCBaseErrors_1 = require("./RPCBaseErrors");
5
5
  class UserMigrateError extends RPCBaseErrors_1.InvalidDCError {
6
6
  constructor(args) {
@@ -103,11 +103,27 @@ class MsgWaitError extends RPCBaseErrors_1.FloodError {
103
103
  }
104
104
  }
105
105
  exports.MsgWaitError = MsgWaitError;
106
+ class FrozenMethodError extends RPCBaseErrors_1.FrozenError {
107
+ constructor(args) {
108
+ super(`This method cannot be used by a frozen account${RPCBaseErrors_1.RPCError._fmtRequest(args.request)}`, args.request, 420);
109
+ this.message = `This method cannot be used by a frozen account${RPCBaseErrors_1.RPCError._fmtRequest(args.request)}`;
110
+ }
111
+ }
112
+ exports.FrozenMethodError = FrozenMethodError;
113
+ class FrozenParticipantError extends RPCBaseErrors_1.BadRequestError {
114
+ constructor(args) {
115
+ super(`This peer cannot be accessed by a frozen account${RPCBaseErrors_1.RPCError._fmtRequest(args.request)}`, args.request, 400);
116
+ this.message = `This peer cannot be accessed by a frozen account${RPCBaseErrors_1.RPCError._fmtRequest(args.request)}`;
117
+ }
118
+ }
119
+ exports.FrozenParticipantError = FrozenParticipantError;
106
120
  exports.rpcErrorRe = new Map([
107
121
  [/FILE_MIGRATE_(\d+)/, FileMigrateError],
108
122
  [/FLOOD_TEST_PHONE_WAIT_(\d+)/, FloodTestPhoneWaitError],
109
123
  [/FLOOD_WAIT_(\d+)/, FloodWaitError],
110
124
  [/FLOOD_PREMIUM_WAIT_(\d+)/, FloodWaitError],
125
+ [/FROZEN_METHOD_INVALID/, FrozenMethodError],
126
+ [/FROZEN_PARTICIPANT_MISSING/, FrozenParticipantError],
111
127
  [/MSG_WAIT_(.*)/, MsgWaitError],
112
128
  [/PHONE_MIGRATE_(\d+)/, PhoneMigrateError],
113
129
  [/SLOWMODE_WAIT_(\d+)/, SlowModeWaitError],
@@ -497,6 +497,11 @@ class MTProtoSender {
497
497
  this._handleBadAuthKey(true);
498
498
  }
499
499
  }
500
+ else if (e instanceof errors_1.TypeNotFoundError) {
501
+ // Unknown constructor in an update (e.g. new TL objects not in our schema).
502
+ // Safe to skip — no reconnect needed.
503
+ this._log.info(`Unknown constructor ${e.invalidConstructorId} in update, skipping (remaining: ${e.remaining.length} bytes)`);
504
+ }
500
505
  else {
501
506
  this._log.error("Unhandled error while receiving data");
502
507
  if (this._client._errorHandler) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teleproto",
3
- "version": "1.223.2",
3
+ "version": "1.224.1",
4
4
  "description": "NodeJS MTProto API Telegram client library,",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",