GramJs: Fix ESLint errors (#1070)

This commit is contained in:
Alexander Zinchuk 2021-05-21 14:50:12 +03:00
parent 4faa7563aa
commit b36ec8cf44
46 changed files with 330 additions and 296 deletions

View File

@ -20,6 +20,10 @@
],
"no-bitwise": "off",
"no-underscore-dangle": "off",
"no-null/no-null": "off"
"no-continue": "off",
"no-restricted-syntax": "off",
"class-methods-use-this": "off",
"max-classes-per-file": "off",
"camelcase": "error"
}
}

View File

@ -310,7 +310,7 @@ function makeCRCTable() {
return crcTable;
}
let crcTable = null;
let crcTable;
function crc32(buf) {
if (!crcTable) {

View File

@ -1,5 +1,4 @@
const BigInt = require('big-integer');
const Factorizator = require('./crypto/Factorizator');
const { constructors } = require('./tl');
const {
readBigIntFromBuffer,
@ -148,7 +147,7 @@ function xor(a, b) {
const length = Math.min(a.length, b.length);
for (let i = 0; i < length; i++) {
a[i] = a[i] ^ b[i];
a[i] ^= b[i];
}
return a;

View File

@ -1,16 +1,9 @@
const { constructors } = require('./tl');
const USERNAME_RE = new RegExp('@|(?:https?:\\/\\/)?(?:www\\.)?'
+ '(?:telegram\\.(?:me|dog)|t\\.me)\\/(@|joinchat\\/)?');
// eslint-disable-next-line max-len
const JPEG_HEADER = Buffer.from('ffd8ffe000104a46494600010100000100010000ffdb004300281c1e231e19282321232d2b28303c64413c37373c7b585d4964918099968f808c8aa0b4e6c3a0aadaad8a8cc8ffcbdaeef5ffffff9bc1fffffffaffe6fdfff8ffdb0043012b2d2d3c353c76414176f8a58ca5f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8ffc00011080000000003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00', 'hex');
const JPEG_FOOTER = Buffer.from('ffd9', 'hex');
const TG_JOIN_RE = new RegExp('tg:\\/\\/(join)\\?invite=');
const VALID_USERNAME_RE = new RegExp('^([a-z]((?!__)[\\w\\d]){3,30}[a-z\\d]|gif|vid|'
+ 'pic|bing|wiki|imdb|bold|vote|like|coub)$');
function _raiseCastFail(entity, target) {
throw new Error(`Cannot cast ${entity.className} to any kind of ${target}`);
}
@ -111,6 +104,7 @@ function getInputPeer(entity, allowSelf = true, checkHash = true) {
}
_raiseCastFail(entity, 'InputPeer');
return undefined;
}
/**
@ -252,7 +246,8 @@ function getInputMessage(message) {
/**
* Adds the JPG header and footer to a stripped image.
* Ported from https://github.com/telegramdesktop/tdesktop/blob/bec39d89e19670eb436dc794a8f20b657cb87c71/Telegram/SourceFiles/ui/image/image.cpp#L225
* Ported from https://github.com/telegramdesktop/
* tdesktop/blob/bec39d89e19670eb436dc794a8f20b657cb87c71/Telegram/SourceFiles/ui/image/image.cpp#L225
* @param stripped{Buffer}
* @returns {Buffer}
@ -263,7 +258,9 @@ function strippedPhotoToJpg(stripped) {
return stripped;
}
const header = Buffer.from(JPEG_HEADER);
// eslint-disable-next-line prefer-destructuring
header[164] = stripped[1];
// eslint-disable-next-line prefer-destructuring
header[166] = stripped[2];
return Buffer.concat([header, stripped.slice(3), JPEG_FOOTER]);
}
@ -502,8 +499,8 @@ function _getEntityPair(entityId, entities, cache, getInputPeer = getInputPeer)
*/
function getMessageId(message) {
if (message === null || message === undefined) {
return null;
if (message === undefined) {
return undefined;
}
if (typeof message === 'number') {
return message;
@ -515,15 +512,6 @@ function getMessageId(message) {
}
/**
* Parses the given phone, or returns `None` if it's invalid.
* @param phone
*/
function parsePhone(phone) {
return phone.toString()
.replace(/[+()\s-]/gm, '');
}
/**
Parses the given username or channel access hash, given
a string, username or URL. Returns a tuple consisting of
@ -617,7 +605,7 @@ function isListLike(item) {
)
}
*/
function getDC(dcId, cdn = false) {
function getDC(dcId) {
switch (dcId) {
case 1:
return {

View File

@ -1,4 +1,5 @@
import TelegramClient from './TelegramClient';
// eslint-disable-next-line import/no-named-default
import { default as Api } from '../tl/api';
import { generateRandomBytes } from '../Helpers';
import { computeCheck, computeDigest } from '../Password';
@ -100,7 +101,8 @@ export async function updateTwoFaSettings(
}));
} catch (e) {
if (e instanceof errors.EmailUnconfirmedError) {
while (1) {
// eslint-disable-next-line no-constant-condition
while (true) {
try {
const code = await emailCodeCallback!(e.codeLength);

View File

@ -4,7 +4,6 @@ const { sleep } = require('../Helpers');
const errors = require('../errors');
const MemorySession = require('../sessions/Memory');
const Helpers = require('../Helpers');
const { BinaryWriter } = require('../extensions');
const utils = require('../Utils');
const Session = require('../sessions/Abstract');
const { LAYER } = require('../tl/AllTLObjects');
@ -13,7 +12,6 @@ const {
requests,
} = require('../tl');
const MTProtoSender = require('../network/MTProtoSender');
const { UpdateConnectionState } = require('../network');
const { ConnectionTCPObfuscated } = require('../network/connection/TCPObfuscated');
const {
authFlow,
@ -35,7 +33,7 @@ class TelegramClient {
static DEFAULT_OPTIONS = {
connection: ConnectionTCPObfuscated,
useIPV6: false,
proxy: null,
proxy: undefined,
timeout: 10,
requestRetries: 5,
connectionRetries: Infinity,
@ -43,9 +41,9 @@ class TelegramClient {
autoReconnect: true,
sequentialUpdates: false,
floodSleepLimit: 60,
deviceModel: null,
systemVersion: null,
appVersion: null,
deviceModel: undefined,
systemVersion: undefined,
appVersion: undefined,
langCode: 'en',
systemLangCode: 'en',
baseLogger: 'gramjs',
@ -91,7 +89,7 @@ class TelegramClient {
this._phoneCodeHash = {};
this.session = session;
// this._entityCache = EntityCache();
this.apiId = parseInt(apiId);
this.apiId = parseInt(apiId, 10);
this.apiHash = apiHash;
this._requestRetries = args.requestRetries;
@ -123,14 +121,14 @@ class TelegramClient {
langPack: '', // this should be left empty.
systemLangCode: args.systemLangCode,
query: x,
proxy: null, // no proxies yet.
proxy: undefined, // no proxies yet.
}),
});
};
this._args = args;
// These will be set later
this._config = null;
this._config = undefined;
this.phoneCodeHashes = [];
this._borrowedSenderPromises = {};
this._additionalDcsDisabled = args.additionalDcsDisabled;
@ -178,7 +176,8 @@ class TelegramClient {
await this.session.load();
if (!this.session.serverAddress || (this.session.serverAddress.includes(':') !== this._useIPV6)) {
this.session.setDC(DEFAULT_DC_ID, this._useIPV6 ? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, this._args.useWSS ? 443 : 80);
this.session.setDC(DEFAULT_DC_ID, this._useIPV6
? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, this._args.useWSS ? 443 : 80);
}
}
@ -208,7 +207,7 @@ class TelegramClient {
try {
await this.invoke(new requests.updates.GetState());
} catch (e) {
// we don't care about errors here
}
}
}
@ -230,6 +229,7 @@ class TelegramClient {
if (sender) {
return sender.disconnect();
}
return undefined;
});
}),
);
@ -253,13 +253,13 @@ class TelegramClient {
this.session.setDC(newDc, DC.ipAddress, DC.port);
// authKey's are associated with a server, which has now changed
// so it's not valid anymore. Set to None to force recreating it.
await this._sender.authKey.setKey(null);
this.session.setAuthKey(null);
await this._sender.authKey.setKey(undefined);
this.session.setAuthKey(undefined);
await this.disconnect();
return this.connect();
}
async _authKeyCallback(authKey, dcId) {
_authKeyCallback(authKey, dcId) {
this.session.setAuthKey(authKey, dcId);
}
@ -270,7 +270,7 @@ class TelegramClient {
delete this._borrowedSenderPromises[dcId];
}
async _borrowExportedSender(dcId) {
_borrowExportedSender(dcId) {
if (this._additionalDcsDisabled) {
return undefined;
}
@ -326,7 +326,7 @@ class TelegramClient {
await sender.disconnect();
}
}
return null;
return undefined;
}
// end region
@ -345,18 +345,15 @@ class TelegramClient {
* @param [args[workers] {number}]
* @returns {Promise<Buffer>}
*/
async downloadFile(inputLocation, args = {}) {
downloadFile(inputLocation, args = {}) {
return downloadFile(this, inputLocation, args);
}
async downloadMedia(messageOrMedia, args) {
let date;
downloadMedia(messageOrMedia, args) {
let media;
if (messageOrMedia instanceof constructors.Message) {
date = messageOrMedia.date;
media = messageOrMedia.media;
} else {
date = new Date().getTime();
media = messageOrMedia;
}
if (typeof media === 'string') {
@ -377,9 +374,10 @@ class TelegramClient {
} else if (media instanceof constructors.WebDocument || media instanceof constructors.WebDocumentNoProxy) {
return this._downloadWebDocument(media, args);
}
return undefined;
}
async downloadProfilePhoto(entity, isBig = false) {
downloadProfilePhoto(entity, isBig = false) {
// ('User', 'Chat', 'UserFull', 'ChatFull')
const ENTITIES = [0x2da17977, 0xc5af5d94, 0x1f4661b9, 0xd49a2697];
// ('InputPeer', 'InputUser', 'InputChannel')
@ -393,7 +391,7 @@ class TelegramClient {
if (!entity.photo) {
// Special case: may be a ChatFull with photo:Photo
if (!entity.chatPhoto) {
return null;
return undefined;
}
return this._downloadPhoto(
@ -417,32 +415,14 @@ class TelegramClient {
// as input location, because then this method would be able
// to "download the profile photo of a message", i.e. its
// media which should be done with `download_media` instead.
return null;
}
try {
return this.downloadFile(loc, {
dcId,
});
} catch (e) {
// TODO this should never raise
throw e;
/* if (e.message === 'LOCATION_INVALID') {
const ie = await this.getInputEntity(entity)
if (ie instanceof constructors.InputPeerChannel) {
const full = await this.invoke(new requests.channels.GetFullChannel({
channel: ie,
}))
return this._downloadPhoto(full.fullChat.chatPhoto, { sizeType })
} else {
return null
}
} else {
throw e
} */
return undefined;
}
return this.downloadFile(loc, {
dcId,
});
}
async downloadStickerSetThumb(stickerSet) {
downloadStickerSetThumb(stickerSet) {
if (!stickerSet.thumbs || !stickerSet.thumbs.length) {
return undefined;
}
@ -462,7 +442,7 @@ class TelegramClient {
_pickFileSize(sizes, sizeType) {
if (!sizeType || !sizes || !sizes.length) {
return null;
return undefined;
}
const indexOfSize = sizeTypes.indexOf(sizeType);
let size;
@ -472,7 +452,7 @@ class TelegramClient {
return size;
}
}
return null;
return undefined;
}
@ -487,16 +467,16 @@ class TelegramClient {
return data;
}
async _downloadPhoto(photo, args) {
_downloadPhoto(photo, args) {
if (photo instanceof constructors.MessageMediaPhoto) {
photo = photo.photo;
}
if (!(photo instanceof constructors.Photo)) {
return;
return undefined;
}
const size = this._pickFileSize(photo.sizes, args.sizeType);
if (!size || (size instanceof constructors.PhotoSizeEmpty)) {
return;
return undefined;
}
if (size instanceof constructors.PhotoCachedSize || size instanceof constructors.PhotoStrippedSize) {
@ -517,22 +497,23 @@ class TelegramClient {
);
}
async _downloadDocument(doc, args) {
_downloadDocument(doc, args) {
if (doc instanceof constructors.MessageMediaDocument) {
doc = doc.document;
}
if (!(doc instanceof constructors.Document)) {
return;
return undefined;
}
let size = null;
let size;
if (args.sizeType) {
size = doc.thumbs ? this._pickFileSize(doc.thumbs, args.sizeType) : null;
size = doc.thumbs ? this._pickFileSize(doc.thumbs, args.sizeType) : undefined;
if (!size && doc.mimeType.startsWith('video/')) {
return;
return undefined;
}
if (size && (size instanceof constructors.PhotoCachedSize || size instanceof constructors.PhotoStrippedSize)) {
if (size && (size instanceof constructors.PhotoCachedSize
|| size instanceof constructors.PhotoStrippedSize)) {
return this._downloadCachedPhotoSize(size);
}
}
@ -555,10 +536,12 @@ class TelegramClient {
);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_downloadContact(media, args) {
throw new Error('not implemented');
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_downloadWebDocument(media, args) {
throw new Error('not implemented');
}
@ -601,7 +584,8 @@ class TelegramClient {
} else if (e instanceof errors.PhoneMigrateError || e instanceof errors.NetworkMigrateError
|| e instanceof errors.UserMigrateError) {
this._log.info(`Phone migrated to ${e.newDc}`);
const shouldRaise = e instanceof errors.PhoneMigrateError || e instanceof errors.NetworkMigrateError;
const shouldRaise = e instanceof errors.PhoneMigrateError
|| e instanceof errors.NetworkMigrateError;
if (shouldRaise && await checkAuthorization(this)) {
throw e;
}
@ -619,7 +603,10 @@ class TelegramClient {
return (await this.invoke(new requests.users
.GetUsers({ id: [new constructors.InputUserSelf()] })))[0];
} catch (e) {
this._log.warn('error while getting me');
this._log.warn(e);
}
return undefined;
}
async start(authParams) {
@ -666,9 +653,9 @@ class TelegramClient {
this._processUpdate(u, update.updates, entities);
}
} else if (update instanceof constructors.UpdateShort) {
this._processUpdate(update.update, null);
this._processUpdate(update.update, undefined);
} else {
this._processUpdate(update, null);
this._processUpdate(update, undefined);
}
// TODO add caching
// this._stateCache.update(update)
@ -915,10 +902,10 @@ class TelegramClient {
}
*/
async _dispatchUpdate(args = {
update: null,
others: null,
channelId: null,
ptsDate: null,
update: undefined,
others: undefined,
channelId: undefined,
ptsDate: undefined,
}) {
for (const [builder, callback] of this._eventBuilders) {
const event = builder.build(args.update);
@ -938,7 +925,7 @@ class TelegramClient {
}
}
async function timeout(promise, ms) {
function timeout(promise, ms) {
return Promise.race([
promise,
Helpers.sleep(ms)
@ -959,6 +946,7 @@ async function attempts(cb, times, pause) {
await Helpers.sleep(pause);
}
}
return undefined;
}
module.exports = TelegramClient;

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-named-default
import { default as Api } from '../tl/api';
import TelegramClient from './TelegramClient';
import utils from '../Utils';
@ -55,7 +56,8 @@ async function signInUser(
let phoneCodeHash;
let isCodeViaApp = false;
while (1) {
// eslint-disable-next-line no-constant-condition
while (true) {
try {
if (typeof authParams.phoneNumber === 'function') {
try {
@ -92,6 +94,7 @@ async function signInUser(
let isRegistrationRequired = false;
let termsOfService;
// eslint-disable-next-line no-constant-condition
while (1) {
try {
try {
@ -132,6 +135,7 @@ async function signInUser(
}
if (isRegistrationRequired) {
// eslint-disable-next-line no-constant-condition
while (1) {
try {
const [firstName, lastName] = await authParams.firstAndLastNames();
@ -168,6 +172,7 @@ async function signInUserWithQrCode(
let isScanningComplete = false;
const inputPromise = (async () => {
// eslint-disable-next-line no-constant-condition
while (1) {
if (isScanningComplete) {
break;
@ -228,7 +233,8 @@ async function signInUserWithQrCode(
token: result2.token,
}));
if (migratedResult instanceof Api.auth.LoginTokenSuccess && migratedResult.authorization instanceof Api.auth.Authorization) {
if (migratedResult instanceof Api.auth.LoginTokenSuccess
&& migratedResult.authorization instanceof Api.auth.Authorization) {
return migratedResult.authorization.user;
}
}
@ -241,6 +247,7 @@ async function signInUserWithQrCode(
}
// This is a workaround for TypeScript (never actually reached)
// eslint-disable-next-line no-throw-literal
throw undefined;
}
@ -288,6 +295,7 @@ async function sendCode(
async function signInWithPassword(
client: TelegramClient, apiCredentials: ApiCredentials, authParams: UserAuthParams,
): Promise<Api.TypeUser> {
// eslint-disable-next-line no-constant-condition
while (1) {
try {
const passwordSrpResult = await client.invoke(new Api.account.GetPassword());
@ -307,6 +315,7 @@ async function signInWithPassword(
}
}
// eslint-disable-next-line no-unreachable
return undefined!; // Never reached (TypeScript fix)
}

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-named-default
import { default as Api } from '../tl/api';
import TelegramClient from './TelegramClient';
import { getAppropriatedPartSize } from '../Utils';
@ -34,13 +35,45 @@ const DEFAULT_CHUNK_SIZE = 64; // kb
const ONE_MB = 1024 * 1024;
const REQUEST_TIMEOUT = 15000;
class Foreman {
private deferred: Deferred | undefined;
private activeWorkers = 0;
constructor(private maxWorkers: number) {
}
requestWorker() {
this.activeWorkers++;
if (this.activeWorkers > this.maxWorkers) {
this.deferred = createDeferred();
return this.deferred.promise;
}
return Promise.resolve();
}
releaseWorker() {
this.activeWorkers--;
if (this.deferred && (this.activeWorkers <= this.maxWorkers)) {
this.deferred.resolve();
}
}
}
export async function downloadFile(
client: TelegramClient,
inputLocation: Api.InputFileLocation,
fileParams: DownloadFileParams,
) {
let {
partSizeKb, fileSize, workers = 1, end,
partSizeKb, end,
} = fileParams;
const {
fileSize, workers = 1,
} = fileParams;
const { dcId, progressCallback, start = 0 } = fileParams;
@ -88,12 +121,13 @@ export async function downloadFile(
progressCallback(progress);
}
// eslint-disable-next-line no-constant-condition
while (true) {
let limit = partSize;
let isPrecise = false;
if (Math.floor(offset / ONE_MB) !== Math.floor((offset + limit - 1) / ONE_MB)) {
limit = ONE_MB - offset % ONE_MB;
limit = ONE_MB - (offset % ONE_MB);
isPrecise = true;
}
@ -104,6 +138,7 @@ export async function downloadFile(
break;
}
// eslint-disable-next-line no-loop-func
promises.push((async () => {
try {
const result = await Promise.race([
@ -151,33 +186,6 @@ export async function downloadFile(
return Buffer.concat(buffers, totalLength);
}
class Foreman {
private deferred: Deferred | undefined;
private activeWorkers = 0;
constructor(private maxWorkers: number) {
}
requestWorker() {
this.activeWorkers++;
if (this.activeWorkers > this.maxWorkers) {
this.deferred = createDeferred();
return this.deferred.promise;
}
return Promise.resolve();
}
releaseWorker() {
this.activeWorkers--;
if (this.deferred && (this.activeWorkers <= this.maxWorkers)) {
this.deferred.resolve();
}
}
}
function createDeferred(): Deferred {
let resolve: Deferred['resolve'];

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-named-default
import { default as Api } from '../tl/api';
import TelegramClient from './TelegramClient';
@ -61,6 +62,7 @@ export async function uploadFile(
for (let j = i; j < end; j++) {
const bytes = buffer.slice(j * partSize, (j + 1) * partSize);
// eslint-disable-next-line no-loop-func
sendingParts.push((async () => {
await sender.send(
isLarge
@ -94,6 +96,7 @@ export async function uploadFile(
]);
} catch (err) {
if (err.message === 'TIMEOUT') {
// eslint-disable-next-line no-console
console.warn('Upload timeout. Retrying...');
i -= workers;
continue;
@ -117,10 +120,6 @@ export async function uploadFile(
});
}
function generateRandomBigInt() {
return readBigIntFromBuffer(generateRandomBytes(8), false);
}
function fileToBuffer(file: File) {
return new Response(file).arrayBuffer();
}

View File

@ -22,7 +22,10 @@ class AuthKey {
async setKey(value) {
if (!value) {
this._key = this.auxHash = this.keyId = this._hash = null;
this._key = undefined;
this.auxHash = undefined;
this.keyId = undefined;
this._hash = undefined;
return;
}
if (value instanceof AuthKey) {

View File

@ -70,6 +70,7 @@ class Factorizator {
if (g.eq(pq)) {
// eslint-disable-next-line no-constant-condition
while (true) {
ys = (modExp(ys, BigInt(2), pq)).add(c)
.remainder(pq);

View File

@ -1,10 +1,10 @@
const { IGE: aes_ige } = require('@cryptography/aes');
const { IGE: AESIGE } = require('@cryptography/aes');
const Helpers = require('../Helpers');
class IGENEW {
constructor(key, iv) {
this.ige = new aes_ige(key, iv);
this.ige = new AESIGE(key, iv);
}
/**

View File

@ -1,8 +1,8 @@
/* eslint-disable max-len */
const BigInt = require('big-integer');
const {
readBigIntFromBuffer,
readBufferFromBigInt,
getByteArray,
sha1,
generateRandomBytes,
modExp,

View File

@ -35,7 +35,7 @@ class CTR {
this._counter = counter;
this._remainingCounter = null;
this._remainingCounter = undefined;
this._remainingCounterIndex = 16;
this._aes = new AES(getWords(key));
@ -95,12 +95,16 @@ class Hash {
this.data = new Uint8Array(data);
}
async digest() {
if (this.algorithm === 'sha1') {
// eslint-disable-next-line no-restricted-globals
return Buffer.from(await self.crypto.subtle.digest('SHA-1', this.data));
} else if (this.algorithm === 'sha256') {
// eslint-disable-next-line no-restricted-globals
return Buffer.from(await self.crypto.subtle.digest('SHA-256', this.data));
}
return undefined;
}
}

View File

@ -22,6 +22,7 @@ class TypeNotFoundError extends Error {
read with ID ${invalidConstructorId}. Most likely, a TLObject was trying to be read when
it should not be read. Remaining bytes: ${remaining.length}`);
if (typeof alert !== 'undefined') {
// eslint-disable-next-line no-alert
alert(`Missing MTProto Entity: Please, make sure to add TL definition for ID ${invalidConstructorId}`);
}
this.invalidConstructorId = invalidConstructorId;
@ -47,7 +48,7 @@ class InvalidChecksumError extends Error {
*/
class InvalidBufferError extends Error {
constructor(payload) {
let code = null;
let code;
if (payload.length === 4) {
code = -payload.readInt32LE(0);
super(`Invalid response buffer (HTTP code ${code})`);
@ -100,7 +101,7 @@ class BadMessageError extends Error {
'Incorrect two lower order msg_id bits (the server expects client message msg_id '
+ 'to be divisible by 4).',
19: 'Container msg_id is the same as msg_id of a previously received message ' + '(this must never happen).',
19: 'Container msg_id is the same as msg_id of a previously received message (this must never happen).',
20:
'Message too old, and it cannot be verified whether the server has received a '

View File

@ -2,7 +2,7 @@
* Base class for all Remote Procedure Call errors.
*/
class RPCError extends Error {
constructor(message, request, code = null) {
constructor(message, request, code = undefined) {
super(
'RPCError {0}: {1}{2}'
.replace('{0}', code)

View File

@ -9,7 +9,9 @@ const {
class UserMigrateError extends InvalidDCError {
constructor(args) {
const newDc = Number(args.capture || 0);
// eslint-disable-next-line max-len
super(`The user whose identity is being used to execute queries is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `The user whose identity is being used to execute queries is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`;
this.newDc = newDc;
}
@ -19,7 +21,9 @@ class UserMigrateError extends InvalidDCError {
class PhoneMigrateError extends InvalidDCError {
constructor(args) {
const newDc = Number(args.capture || 0);
// eslint-disable-next-line max-len
super(`The phone number a user is trying to use for authorization is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `The phone number a user is trying to use for authorization is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`;
this.newDc = newDc;
}
@ -28,7 +32,9 @@ class PhoneMigrateError extends InvalidDCError {
class SlowModeWaitError extends FloodError {
constructor(args) {
const seconds = Number(args.capture || 0);
// eslint-disable-next-line max-len
super(`A wait of ${seconds} seconds is required before sending another message in this chat${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `A wait of ${seconds} seconds is required before sending another message in this chat${RPCError._fmtRequest(args.request)}`;
this.seconds = seconds;
}
@ -47,6 +53,7 @@ class FloodTestPhoneWaitError extends FloodError {
constructor(args) {
const seconds = Number(args.capture || 0);
super(`A wait of ${seconds} seconds is required in the test servers${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `A wait of ${seconds} seconds is required in the test servers${RPCError._fmtRequest(args.request)}`;
this.seconds = seconds;
}
@ -56,6 +63,7 @@ class FileMigrateError extends InvalidDCError {
constructor(args) {
const newDc = Number(args.capture || 0);
super(`The file to be accessed is currently stored in DC ${newDc}${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `The file to be accessed is currently stored in DC ${newDc}${RPCError._fmtRequest(args.request)}`;
this.newDc = newDc;
}
@ -74,6 +82,7 @@ class EmailUnconfirmedError extends BadRequestError {
constructor(args) {
const codeLength = Number(args.capture || 0);
super(`Email unconfirmed, the length of the code must be ${codeLength}${RPCError._fmtRequest(args.request)}`);
// eslint-disable-next-line max-len
this.message = `Email unconfirmed, the length of the code must be ${codeLength}${RPCError._fmtRequest(args.request)}`;
this.codeLength = codeLength;
}

View File

@ -11,7 +11,7 @@ function RPCMessageToError(rpcError, request) {
for (const [msgRegex, Cls] of rpcErrorRe) {
const m = rpcError.errorMessage.match(msgRegex);
if (m) {
const capture = m.length === 2 ? parseInt(m[1]) : null;
const capture = m.length === 2 ? parseInt(m[1], 10) : undefined;
return new Cls({
request,
capture,
@ -22,9 +22,13 @@ function RPCMessageToError(rpcError, request) {
return new RPCError(rpcError.errorMessage, request);
}
const Common = require('./Common');
const RPCBaseErrors = require('./RPCBaseErrors');
const RPCErrorList = require('./RPCErrorList');
module.exports = {
RPCMessageToError,
...require('./Common'),
...require('./RPCBaseErrors'),
...require('./RPCErrorList'),
...Common,
...RPCBaseErrors,
...RPCErrorList,
};

View File

@ -2,8 +2,8 @@ const { EventBuilder } = require('./common');
class Raw extends EventBuilder {
constructor(args = {
types: null,
func: null,
types: undefined,
func: undefined,
}) {
super();
if (!args.types) {
@ -13,7 +13,7 @@ class Raw extends EventBuilder {
}
}
build(update, others = null) {
build(update) {
return update;
}
}

View File

@ -1,8 +1,8 @@
class EventBuilder {
constructor(args = {
chats: null,
blacklistChats: null,
func: null,
chats: undefined,
blacklistChats: undefined,
func: undefined,
}) {
this.chats = args.chats;
this.blacklistChats = Boolean(args.blacklistChats);
@ -10,17 +10,13 @@ class EventBuilder {
this.func = args.func;
}
build(update, others = null) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
build(update) {
}
}
class EventCommon {
}
module.exports = {
EventBuilder,
EventCommon,
};

View File

@ -10,7 +10,7 @@ class BinaryReader {
*/
constructor(data) {
this.stream = data;
this._last = null;
this._last = undefined;
this.offset = 0;
}
@ -234,7 +234,7 @@ class BinaryReader {
* Closes the reader.
*/
close() {
this.stream = null;
this.stream = undefined;
}
// region Position related

View File

@ -1,4 +1,4 @@
let _level = null;
let _level;
class Logger {
static levels = ['error', 'warn', 'info', 'debug'];
@ -92,12 +92,12 @@ class Logger {
}
if (this.canSend(level)) {
if (!this.isBrowser) {
// eslint-disable-next-line no-console
console.log(color + this.format(message, level) + this.colors.end);
} else {
// eslint-disable-next-line no-console
console.log(this.colors.start + this.format(message, level), color);
}
} else {
}
}
}

View File

@ -49,7 +49,7 @@ class MessagePacker {
}
if (!this._queue[this._queue.length - 1]) {
this._queue = [];
return;
return undefined;
}
let data;
let buffer = new BinaryWriter(Buffer.alloc(0));
@ -69,7 +69,8 @@ class MessagePacker {
buffer, state.data, state.request.classType === 'request',
afterId,
);
this._log.debug(`Assigned msgId = ${state.msgId} to ${state.request.className || state.request.constructor.name}`);
this._log.debug(`Assigned msgId = ${state.msgId} to ${state.request.className
|| state.request.constructor.name}`);
batch.push(state);
continue;
}
@ -77,12 +78,13 @@ class MessagePacker {
this._queue.unshift(state);
break;
}
this._log.warn(`Message payload for ${state.request.className || state.request.constructor.name} is too long ${state.data.length} and cannot be sent`);
this._log.warn(`Message payload for ${state.request.className
|| state.request.constructor.name} is too long ${state.data.length} and cannot be sent`);
state.reject('Request Payload is too big');
size = 0;
}
if (!batch.length) {
return null;
return undefined;
}
if (batch.length > 1) {
const b = Buffer.alloc(8);

View File

@ -15,12 +15,13 @@ class PromisedWebSockets {
process.__nwjs
*/
this.client = null;
this.client = undefined;
this.closed = true;
}
async readExactly(number) {
let readData = Buffer.alloc(0);
// eslint-disable-next-line no-constant-condition
while (true) {
const thisTime = await this.read(number);
readData = Buffer.concat([readData, thisTime]);
@ -71,7 +72,7 @@ class PromisedWebSockets {
}
}
async connect(port, ip) {
connect(port, ip) {
this.stream = Buffer.alloc(0);
this.canRead = new Promise((resolve) => {
this.resolveRead = resolve;
@ -93,6 +94,7 @@ class PromisedWebSockets {
};
// CONTEST
// Seems to not be working, at least in a web worker
// eslint-disable-next-line no-restricted-globals
self.addEventListener('offline', async () => {
await this.close();
this.resolveRead(false);
@ -112,7 +114,7 @@ class PromisedWebSockets {
this.closed = true;
}
async receive() {
receive() {
this.client.onmessage = async (message) => {
const release = await mutex.acquire();
try {

View File

@ -58,16 +58,16 @@ async function doAuthentication(sender, log) {
});
// sha_digest + data + random_bytes
let cipherText = null;
let targetFingerprint = null;
let cipherText;
let targetFingerprint;
for (const fingerprint of resPQ.serverPublicKeyFingerprints) {
cipherText = await RSA.encrypt(fingerprint.toString(), pqInnerData.getBytes());
if (cipherText !== null && cipherText !== undefined) {
if (cipherText !== undefined) {
targetFingerprint = fingerprint;
break;
}
}
if (cipherText === null || cipherText === undefined) {
if (cipherText === undefined) {
throw new SecurityError('Step 2 could not find a valid key for fingerprints');
}
@ -81,7 +81,8 @@ async function doAuthentication(sender, log) {
encryptedData: cipherText,
}),
);
if (!(serverDhParams instanceof constructors.ServerDHParamsOk || serverDhParams instanceof constructors.ServerDHParamsFail)) {
if (!(serverDhParams instanceof constructors.ServerDHParamsOk
|| serverDhParams instanceof constructors.ServerDHParamsFail)) {
throw new Error(`Step 2.1 answer was ${serverDhParams}`);
}
if (serverDhParams.nonce.neq(resPQ.nonce)) {

View File

@ -3,7 +3,6 @@
* in plain text, when no authorization key has been created yet.
*/
const BigInt = require('big-integer');
const Helpers = require('../Helpers');
const MTProtoState = require('./MTProtoState');
const BinaryReader = require('../extensions/BinaryReader');
const { InvalidBufferError } = require('../errors/Common');

View File

@ -50,16 +50,16 @@ const { TypeNotFoundError } = require('../errors/Common');
*/
class MTProtoSender {
static DEFAULT_OPTIONS = {
logger: null,
logger: undefined,
retries: Infinity,
delay: 2000,
autoReconnect: true,
connectTimeout: null,
authKeyCallback: null,
updateCallback: null,
autoReconnectCallback: null,
isMainSender: null,
onConnectionBreak: null,
connectTimeout: undefined,
authKeyCallback: undefined,
updateCallback: undefined,
autoReconnectCallback: undefined,
isMainSender: undefined,
onConnectionBreak: undefined,
};
/**
@ -68,7 +68,7 @@ class MTProtoSender {
*/
constructor(authKey, opts) {
const args = { ...MTProtoSender.DEFAULT_OPTIONS, ...opts };
this._connection = null;
this._connection = undefined;
this._log = args.logger;
this._dcId = args.dcId;
this._retries = args.retries;
@ -96,8 +96,8 @@ class MTProtoSender {
/**
* We need to join the loops upon disconnection
*/
this._send_loop_handle = null;
this._recv_loop_handle = null;
this._send_loop_handle = undefined;
this._recv_loop_handle = undefined;
/**
* Preserving the references of the AuthKey and state is important
@ -180,6 +180,7 @@ class MTProtoSender {
await Helpers.sleep(this._delay);
}
}
return true;
}
isConnected() {
@ -286,10 +287,10 @@ class MTProtoSender {
this._log.info('Connection to %s complete!'.replace('%s', this._connection.toString()));
}
async _disconnect(error = null) {
async _disconnect() {
this._send_queue.rejectAll();
if (this._connection === null) {
if (this._connection === undefined) {
this._log.info('Not disconnecting (already have no connection)');
return;
}
@ -495,12 +496,12 @@ class MTProtoSender {
* @private
*/
_handleRPCResult(message) {
const RPCResult = message.obj;
const state = this._pending_state[RPCResult.reqMsgId];
const result = message.obj;
const state = this._pending_state[result.reqMsgId];
if (state) {
delete this._pending_state[RPCResult.reqMsgId];
delete this._pending_state[result.reqMsgId];
}
this._log.debug(`Handling RPC result for message ${RPCResult.reqMsgId}`);
this._log.debug(`Handling RPC result for message ${result.reqMsgId}`);
if (!state) {
// TODO We should not get responses to things we never sent
@ -508,27 +509,27 @@ class MTProtoSender {
// See #658, #759 and #958. They seem to happen in a container
// which contain the real response right after.
try {
const reader = new BinaryReader(RPCResult.body);
const reader = new BinaryReader(result.body);
if (!(reader.tgReadObject() instanceof upload.File)) {
throw new TypeNotFoundError('Not an upload.File');
}
} catch (e) {
this._log.error(e);
if (e instanceof TypeNotFoundError) {
this._log.info(`Received response without parent request: ${RPCResult.body}`);
this._log.info(`Received response without parent request: ${result.body}`);
return;
} else {
throw e;
}
}
}
if (RPCResult.error) {
if (result.error) {
// eslint-disable-next-line new-cap
const error = RPCMessageToError(RPCResult.error, state.request);
const error = RPCMessageToError(result.error, state.request);
this._send_queue.append(new RequestState(new MsgsAck({ msgIds: [state.msgId] })));
state.reject(error);
} else {
const reader = new BinaryReader(RPCResult.body);
const reader = new BinaryReader(result.body);
const read = state.request.readResult(reader);
state.resolve(read);
}
@ -562,7 +563,7 @@ class MTProtoSender {
await this._processMessage(message);
}
async _handleUpdate(message) {
_handleUpdate(message) {
if (message.obj.SUBCLASS_OF_ID !== 0x8af52aac) {
// crc32(b'Updates')
this._log.warn(`Note: ${message.obj.className} is not an update, not dispatching it`);
@ -582,7 +583,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handlePong(message) {
_handlePong(message) {
const pong = message.obj;
this._log.debug(`Handling pong for message ${pong.msgId}`);
const state = this._pending_state[pong.msgId];
@ -603,7 +604,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleBadServerSalt(message) {
_handleBadServerSalt(message) {
const badSalt = message.obj;
this._log.debug(`Handling bad salt for message ${badSalt.badMsgId}`);
this._state.salt = badSalt.newServerSalt;
@ -621,7 +622,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleBadNotification(message) {
_handleBadNotification(message) {
const badMsg = message.obj;
const states = this._popStates(badMsg.badMsgId);
this._log.debug(`Handling bad msg ${JSON.stringify(badMsg)}`);
@ -657,7 +658,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleDetailedInfo(message) {
_handleDetailedInfo(message) {
// TODO https://goo.gl/VvpCC6
const msgId = message.obj.answerMsgId;
this._log.debug(`Handling detailed info for message ${msgId}`);
@ -672,7 +673,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleNewDetailedInfo(message) {
_handleNewDetailedInfo(message) {
// TODO https://goo.gl/VvpCC6
const msgId = message.obj.answerMsgId;
this._log.debug(`Handling new detailed info for message ${msgId}`);
@ -687,7 +688,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleNewSessionCreated(message) {
_handleNewSessionCreated(message) {
// TODO https://goo.gl/LMyN7A
this._log.debug('Handling new session created');
this._state.salt = message.obj.serverSalt;
@ -711,7 +712,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleAck(message) {
_handleAck(message) {
const ack = message.obj;
this._log.debug(`Handling acknowledge for ${ack.msgIds}`);
for (const msgId of ack.msgIds) {
@ -732,7 +733,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleFutureSalts(message) {
_handleFutureSalts(message) {
// TODO save these salts and automatically adjust to the
// correct one whenever the salt in use expires.
this._log.debug(`Handling future salts for message ${message.msgId}`);
@ -751,7 +752,7 @@ class MTProtoSender {
* @returns {Promise<void>}
* @private
*/
async _handleStateForgotten(message) {
_handleStateForgotten(message) {
this._send_queue.append(
new RequestState(new MsgsStateInfo(message.msgId, String.fromCharCode(1)
.repeat(message.obj.msgIds))),
@ -760,14 +761,17 @@ class MTProtoSender {
/**
* Handles :tl:`MsgsAllInfo` by doing nothing (yet).
* used as part of the telegram protocol https://core.telegram.org/mtproto/service_messages_about_messages
* This message does not require an acknowledgment.
* @param message
* @returns {Promise<void>}
* @private
*/
async _handleMsgAll(message) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_handleMsgAll(message) {
}
async reconnect() {
reconnect() {
if (this._user_connected && !this._reconnecting) {
this._reconnecting = true;
// TODO Should we set this?
@ -785,7 +789,7 @@ class MTProtoSender {
this._log.warn(err);
}
this._send_queue.append(null);
this._send_queue.append(undefined);
this._state.reset();
await this.connect(this._connection, true);

View File

@ -1,3 +1,5 @@
const BigInt = require('big-integer');
const Helpers = require('../Helpers');
const IGE = require('../crypto/IGE');
const BinaryReader = require('../extensions/BinaryReader');
@ -8,12 +10,9 @@ const {
InvalidBufferError,
} = require('../errors/Common');
const { InvokeAfterMsg } = require('../tl').requests;
const BigInt = require('big-integer');
const {
toSignedLittleBuffer,
readBufferFromBigInt,
} = require('../Helpers');
const { readBigIntFromBuffer } = require('../Helpers');
class MTProtoState {
/**
@ -47,7 +46,9 @@ class MTProtoState {
this.timeOffset = 0;
this.salt = 0;
this.id = this._sequence = this._lastMsgId = null;
this.id = undefined;
this._sequence = undefined;
this._lastMsgId = undefined;
this.reset();
}

View File

@ -1,11 +1,11 @@
class RequestState {
constructor(request, after = null) {
this.containerId = null;
this.msgId = null;
constructor(request, after = undefined) {
this.containerId = undefined;
this.msgId = undefined;
this.request = request;
this.data = request.getBytes();
this.after = after;
this.result = null;
this.result = undefined;
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;

View File

@ -13,7 +13,7 @@ const AsyncQueue = require('../../extensions/AsyncQueue');
* the client is disconnected (includes remote disconnections).
*/
class Connection {
PacketCodecClass = null;
PacketCodecClass = undefined;
constructor(ip, port, dcId, loggers) {
this._ip = ip;
@ -21,10 +21,10 @@ class Connection {
this._dcId = dcId;
this._log = loggers;
this._connected = false;
this._sendTask = null;
this._recvTask = null;
this._codec = null;
this._obfuscation = null; // TcpObfuscated and MTProxy
this._sendTask = undefined;
this._recvTask = undefined;
this._codec = undefined;
this._obfuscation = undefined; // TcpObfuscated and MTProxy
this._sendArray = new AsyncQueue();
this._recvArray = new AsyncQueue();
// this.socket = new PromiseSocket(new Socket())
@ -53,7 +53,7 @@ class Connection {
async disconnect() {
this._connected = false;
await this._recvArray.push(null);
await this._recvArray.push(undefined);
await this.socket.close();
}
@ -81,7 +81,7 @@ class Connection {
while (this._connected) {
const data = await this._sendArray.pop();
if (!data) {
this._sendTask = null;
this._sendTask = undefined;
return;
}
await this._send(data);
@ -116,13 +116,13 @@ class Connection {
}
}
async _send(data) {
_send(data) {
const encodedPacket = this._codec.encodePacket(data);
this.socket.write(encodedPacket);
}
async _recv() {
return await this._codec.readPacket(this.socket);
_recv() {
return this._codec.readPacket(this.socket);
}
toString() {
@ -131,9 +131,9 @@ class Connection {
}
class ObfuscatedConnection extends Connection {
ObfuscatedIO = null;
ObfuscatedIO = undefined;
async _initConn() {
_initConn() {
this._obfuscation = new this.ObfuscatedIO(this);
this.socket.write(this._obfuscation.header);
}
@ -143,8 +143,8 @@ class ObfuscatedConnection extends Connection {
}
async _recv() {
return await this._codec.readPacket(this._obfuscation);
_recv() {
return this._codec.readPacket(this._obfuscation);
}
}
@ -153,13 +153,15 @@ class PacketCodec {
this._conn = connection;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
encodePacket(data) {
throw new Error('Not Implemented');
// Override
}
async readPacket(reader) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
readPacket(reader) {
// override
throw new Error('Not Implemented');
}

View File

@ -36,7 +36,7 @@ class AbridgedPacketCodec extends PacketCodec {
.readInt32LE(0);
}
return await reader.read(length << 2);
return reader.read(length << 2);
}
}

View File

@ -4,7 +4,7 @@ const { AbridgedPacketCodec } = require('./TCPAbridged');
const CTR = require('../../crypto/CTR');
class ObfuscatedIO {
header = null;
header = undefined;
constructor(connection) {
this.connection = connection.socket;

View File

@ -1,8 +1,4 @@
class Session {
constructor() {
}
/**
* Creates a clone of this session file
* @param toInstance {Session|null}
@ -59,6 +55,7 @@ class Session {
* @param serverAddress {string}
* @param port {number}
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setDC(dcId, serverAddress, port) {
throw new Error('Not implemented');
}

View File

@ -1,3 +1,4 @@
/* eslint-disable no-restricted-globals */
const StorageSession = require('./StorageSession');
const CACHE_NAME = 'GramJs';
@ -13,7 +14,7 @@ class CacheApiSession extends StorageSession {
const request = new Request(this._storageKey);
const cache = await self.caches.open(CACHE_NAME);
const cached = await cache.match(request);
return cached ? cached.text() : null;
return cached ? cached.text() : undefined;
}
async _saveToCache(data) {

View File

@ -4,15 +4,15 @@ const StorageSession = require('./StorageSession');
const CACHE_NAME = 'GramJs';
class IdbSession extends StorageSession {
async _delete() {
_delete() {
return idb.del(`${CACHE_NAME}:${this._storageKey}`);
}
async _fetchFromCache() {
_fetchFromCache() {
return idb.get(`${CACHE_NAME}:${this._storageKey}`);
}
async _saveToCache(data) {
_saveToCache(data) {
return idb.set(`${CACHE_NAME}:${this._storageKey}`, data);
}
}

View File

@ -1,15 +1,15 @@
const StorageSession = require('./StorageSession');
class LocalStorageSession extends StorageSession {
async _delete() {
_delete() {
return localStorage.removeItem(this._storageKey);
}
async _fetchFromCache(key) {
_fetchFromCache() {
return localStorage.getItem(this._storageKey);
}
async _saveToCache(key, data) {
_saveToCache(data) {
return localStorage.setItem(this._storageKey, data);
}
}

View File

@ -1,15 +1,13 @@
const utils = require('../Utils');
const types = require('../tl').constructors;
const Session = require('./Abstract');
class MemorySession extends Session {
constructor() {
super();
this._serverAddress = null;
this._serverAddress = undefined;
this._dcId = 0;
this._port = null;
this._takeoutId = null;
this._port = undefined;
this._takeoutId = undefined;
this._entities = new Set();
this._updateStates = {};

View File

@ -48,7 +48,9 @@ class StorageSession extends MemorySession {
}
});
} catch (err) {
// eslint-disable-next-line no-console
console.warn('Failed to retrieve or parse session from storage');
// eslint-disable-next-line no-console
console.warn(err);
}
}
@ -101,12 +103,15 @@ class StorageSession extends MemorySession {
const authKey = this._authKeys[dcId];
sessionData.keys[dcId] = authKey._key;
sessionData.hashes[dcId] = authKey._hash;
return undefined;
});
try {
await this._saveToCache(JSON.stringify(sessionData));
} catch (err) {
// eslint-disable-next-line no-console
console.warn('Failed to update session in storage');
// eslint-disable-next-line no-console
console.warn(err);
}
}
@ -115,23 +120,27 @@ class StorageSession extends MemorySession {
try {
return await this._delete();
} catch (err) {
// eslint-disable-next-line no-console
console.warn('Failed to delete session from storage');
// eslint-disable-next-line no-console
console.warn(err);
}
return undefined;
}
// @abstract
async _delete() {
_delete() {
throw new Error('Not Implemented');
}
// @abstract
async _fetchFromCache() {
_fetchFromCache() {
throw new Error('Not Implemented');
}
// @abstract
async _saveToCache(data) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_saveToCache(data) {
throw new Error('Not Implemented');
}
}

View File

@ -21,7 +21,7 @@ class StringSession extends MemorySession {
* `decode` definition must be ``function decode(value: string) -> Buffer:``.
* @param session {string|null}
*/
constructor(session = null) {
constructor(session = undefined) {
super();
if (session) {
if (session[0] !== CURRENT_VERSION) {
@ -96,7 +96,7 @@ class StringSession extends MemorySession {
setAuthKey(authKey, dcId) {
if (dcId && dcId !== this.dcId) {
// Not supported.
return undefined;
return;
}
this.authKey = authKey;

View File

@ -34,10 +34,14 @@ class MTProtoRequest {
throw Error(`Not overload ${this.constructor.name}`);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onResponse(buffer) {
throw Error(`Not overload ${this.constructor.name}`);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onException(exception) {
throw Error(`Not overload ${this.constructor.name}`);
}
}

View File

@ -4,7 +4,6 @@ const {
serializeDate,
} = require('./generationHelpers');
const {
readBufferFromBigInt,
toSignedLittleBuffer,
} = require('../Helpers');
@ -32,6 +31,7 @@ const AUTO_CASTS = new Set([
])
*/
// eslint-disable-next-line no-restricted-globals
const CACHING_SUPPORTED = typeof self !== 'undefined' && self.localStorage !== undefined;
const CACHE_KEY = 'GramJs:apiCache';
@ -93,27 +93,33 @@ function extractParams(fileContent) {
const constructors = [];
const functions = [];
for (const d of f) {
d.isFunction ? functions.push(d) : constructors.push(d);
if (d.isFunction) {
functions.push(d);
} else {
constructors.push(d);
}
}
return [constructors, functions];
}
function argToBytes(x, type) {
switch (type) {
case 'int':
case 'int': {
const i = Buffer.alloc(4);
i.writeInt32LE(x, 0);
return i;
}
case 'long':
return toSignedLittleBuffer(x, 8);
case 'int128':
return toSignedLittleBuffer(x, 16);
case 'int256':
return toSignedLittleBuffer(x, 32);
case 'double':
case 'double': {
const d = Buffer.alloc(8);
d.writeDoubleLE(x, 0);
return d;
}
case 'string':
return serializeBytes(x);
case 'Bool':
@ -201,7 +207,7 @@ function getArgFromReader(reader, arg) {
if (!arg.skipConstructorId) {
return reader.tgReadObject();
} else {
return api.constructors[arg.type].fromReader(reader);
throw new Error(`Unknown type ${arg}`);
}
}
}
@ -254,13 +260,13 @@ function createClasses(classesType, params) {
const arg = argsConfig[argName];
if (arg.isFlag) {
if (arg.type === 'true') {
args[argName] = Boolean(args.flags & 1 << arg.flagIndex);
args[argName] = Boolean(args.flags & (1 << arg.flagIndex));
continue;
}
if (args.flags & 1 << arg.flagIndex) {
if (args.flags & (1 << arg.flagIndex)) {
args[argName] = getArgFromReader(reader, arg);
} else {
args[argName] = null;
args[argName] = undefined;
}
} else {
if (arg.flagIndicator) {
@ -282,7 +288,8 @@ function createClasses(classesType, params) {
for (const arg in argsConfig) {
if (argsConfig.hasOwnProperty(arg)) {
if (argsConfig[arg].isFlag) {
if ((this[arg] === false && argsConfig[arg].type === 'true') || this[arg] === null || this[arg] === undefined) {
if ((this[arg] === false && argsConfig[arg].type === 'true')
|| this[arg] === undefined) {
continue;
}
}
@ -301,7 +308,8 @@ function createClasses(classesType, params) {
let flagCalculate = 0;
for (const f in argsConfig) {
if (argsConfig[f].isFlag) {
if ((this[f] === false && argsConfig[f].type === 'true') || this[f] === undefined || this[f] === null) {
if ((this[f] === false && argsConfig[f].type === 'true')
|| this[f] === undefined) {
flagCalculate |= 0;
} else {
flagCalculate |= 1 << argsConfig[f].flagIndex;

View File

@ -34,12 +34,12 @@ class GZIPPacked {
return Buffer.from(inflate(input));
}
static async read(reader) {
static read(reader) {
const constructor = reader.readInt(false);
if (constructor !== GZIPPacked.CONSTRUCTOR_ID) {
throw new Error('not equal');
}
return await GZIPPacked.gzip(reader.tgReadBytes());
return GZIPPacked.gzip(reader.tgReadBytes());
}
static async fromReader(reader) {

View File

@ -26,16 +26,16 @@ class MessageContainer {
this.classType = 'constructor';
}
static async fromReader(reader) {
static fromReader(reader) {
const messages = [];
const length = reader.readInt();
for (let x = 0; x < length; x++) {
const msgId = reader.readLong();
const seqNo = reader.readInt();
const length = reader.readInt();
const containerLength = reader.readInt();
const before = reader.tellPosition();
const obj = reader.tgReadObject();
reader.setPosition(before + length);
reader.setPosition(before + containerLength);
const tlMessage = new TLMessage(msgId, seqNo, obj);
messages.push(tlMessage);
}

View File

@ -18,7 +18,7 @@ class RPCResult {
const msgId = reader.readLong();
const innerCode = reader.readInt(false);
if (innerCode === RpcError.CONSTRUCTOR_ID) {
return new RPCResult(msgId, null, RpcError.fromReader(reader));
return new RPCResult(msgId, undefined, RpcError.fromReader(reader));
}
if (innerCode === GZIPPacked.CONSTRUCTOR_ID) {
return new RPCResult(msgId, (await GZIPPacked.fromReader(reader)).data);
@ -27,7 +27,7 @@ class RPCResult {
// This reader.read() will read more than necessary, but it's okay.
// We could make use of MessageContainer's length here, but since
// it's not necessary we don't need to care about it.
return new RPCResult(msgId, reader.read(), null);
return new RPCResult(msgId, reader.read(), undefined);
}
}

View File

@ -44,7 +44,7 @@ function makeCRCTable() {
return crcTable;
}
let crcTable = null;
let crcTable;
function crc32(buf) {
if (!crcTable) {
@ -62,6 +62,21 @@ function crc32(buf) {
return (crc ^ (-1)) >>> 0;
}
const findAll = (regex, str, matches = []) => {
if (!regex.flags.includes('g')) {
regex = new RegExp(regex.source, 'g');
}
const res = regex.exec(str);
if (res) {
matches.push(res.slice(1));
findAll(regex, str, matches);
}
return matches;
};
const fromLine = (line, isFunction) => {
const match = line.match(/([\w.]+)(?:#([0-9a-fA-F]+))?(?:\s{?\w+:[\w\d<>#.?!]+}?)*\s=\s([\w\d<>#.?]+);$/);
if (!match) {
@ -77,7 +92,7 @@ const fromLine = (line, isFunction) => {
subclassOfId: crc32(match[3]),
result: match[3],
isFunction,
namespace: null,
namespace: undefined,
};
if (!currentConfig.constructorId) {
const hexId = '';
@ -134,16 +149,10 @@ function buildArgConfig(name, argType) {
skipConstructorId: false,
flagIndex: -1,
flagIndicator: true,
type: null,
useVectorId: null,
type: undefined,
useVectorId: undefined,
};
// Special case: some types can be inferred, which makes it
// less annoying to type. Currently the only type that can
// be inferred is if the name is 'random_id', to which a
// random ID will be assigned if left as None (the default)
const canBeInferred = name === 'random_id';
// The type can be an indicator that other arguments will be flags
if (argType !== '#') {
currentConfig.flagIndicator = false;
@ -206,8 +215,8 @@ function buildArgConfig(name, argType) {
}
const parseTl = function* (content, layer, methods = [], ignoreIds = CORE_TYPES) {
const methodInfo = (methods || []).reduce((o, m) => ({
function* parseTl(content, layer, methods = [], ignoreIds = CORE_TYPES) {
(methods || []).reduce((o, m) => ({
...o,
[m.name]: m,
}), {});
@ -281,22 +290,7 @@ const parseTl = function* (content, layer, methods = [], ignoreIds = CORE_TYPES)
for (const obj of objAll) {
yield obj;
}
};
const findAll = (regex, str, matches = []) => {
if (!regex.flags.includes('g')) {
regex = new RegExp(regex.source, 'g');
}
const res = regex.exec(str);
if (res) {
matches.push(res.slice(1));
findAll(regex, str, matches);
}
return matches;
};
}
function serializeBytes(data) {
if (!(data instanceof Buffer)) {

View File

@ -4,13 +4,10 @@ const {
serializeDate,
} = require('./generationHelpers');
const patched = null;
module.exports = {
// TODO Refactor internal usages to always use `api`.
constructors: api,
requests: api,
patched,
serializeBytes,
serializeDate,
};