|
@@ -1,11 +1,10 @@
|
|
|
const fs = require('fs');
|
|
|
const util = require('util');
|
|
|
-const {crc32} = require('crc');
|
|
|
+const { crc32 } = require('crc');
|
|
|
const SourceBuilder = require('../sourcebuilder');
|
|
|
-const {snakeToCamelCase, variableSnakeToCamelCase} = require("../utils");
|
|
|
+const { snakeToCamelCase, variableSnakeToCamelCase } = require('../utils');
|
|
|
|
|
|
-const AUTO_GEN_NOTICE =
|
|
|
- "/*! File generated by TLObjects' generator. All changes will be ERASED !*/";
|
|
|
+const AUTO_GEN_NOTICE = '/*! File generated by TLObjects\' generator. All changes will be ERASED !*/';
|
|
|
|
|
|
const AUTO_CASTS = {
|
|
|
InputPeer: 'utils.get_input_peer(await client.get_input_entity(%s))',
|
|
@@ -34,21 +33,11 @@ const NAMED_AUTO_CASTS = {
|
|
|
// did recurse into them to resolve them.
|
|
|
const NAMED_BLACKLIST = new Set(['messages.discardEncryption']);
|
|
|
|
|
|
-const BASE_TYPES = [
|
|
|
- 'string',
|
|
|
- 'bytes',
|
|
|
- 'int',
|
|
|
- 'long',
|
|
|
- 'int128',
|
|
|
- 'int256',
|
|
|
- 'double',
|
|
|
- 'Bool',
|
|
|
- 'true',
|
|
|
-];
|
|
|
+const BASE_TYPES = ['string', 'bytes', 'int', 'long', 'int128', 'int256', 'double', 'Bool', 'true'];
|
|
|
|
|
|
// Patched types {fullname: custom.ns.Name}
|
|
|
|
|
|
-//No patches currently
|
|
|
+// No patches currently
|
|
|
/**
|
|
|
const PATCHED_TYPES = {
|
|
|
messageEmpty: 'message.Message',
|
|
@@ -57,15 +46,9 @@ const BASE_TYPES = [
|
|
|
};*/
|
|
|
const PATCHED_TYPES = {};
|
|
|
|
|
|
-const writeModules = (
|
|
|
- outDir,
|
|
|
- depth,
|
|
|
- kind,
|
|
|
- namespaceTlobjects,
|
|
|
- typeConstructors
|
|
|
-) => {
|
|
|
+const writeModules = (outDir, depth, kind, namespaceTlobjects, typeConstructors) => {
|
|
|
// namespace_tlobjects: {'namespace', [TLObject]}
|
|
|
- fs.mkdirSync(outDir, {recursive: true});
|
|
|
+ fs.mkdirSync(outDir, { recursive: true });
|
|
|
|
|
|
for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
|
|
|
const file = `${outDir}/${ns === 'null' ? 'index' : ns}.js`;
|
|
@@ -74,14 +57,10 @@ const writeModules = (
|
|
|
const dotDepth = '.'.repeat(depth || 1);
|
|
|
|
|
|
builder.writeln(AUTO_GEN_NOTICE);
|
|
|
- builder.writeln(
|
|
|
- `const { TLObject } = require('${dotDepth}/tlobject');`
|
|
|
- );
|
|
|
+ builder.writeln(`const { TLObject } = require('${dotDepth}/tlobject');`);
|
|
|
|
|
|
if (kind !== 'TLObject') {
|
|
|
- builder.writeln(
|
|
|
- `const { ${kind} } = require('${dotDepth}/tlobject');`
|
|
|
- );
|
|
|
+ builder.writeln(`const { ${kind} } = require('${dotDepth}/tlobject');`);
|
|
|
}
|
|
|
|
|
|
// Add the relative imports to the namespaces,
|
|
@@ -95,7 +74,7 @@ const writeModules = (
|
|
|
}
|
|
|
|
|
|
// Import struct for the .__bytes__(self) serialization
|
|
|
- builder.writeln("const struct = require('python-struct');");
|
|
|
+ builder.writeln('const struct = require(\'python-struct\');');
|
|
|
builder.writeln(`const Helpers = require('../../utils/Helpers');`);
|
|
|
|
|
|
const typeNames = new Set();
|
|
@@ -136,17 +115,7 @@ const writeModules = (
|
|
|
}*/
|
|
|
|
|
|
const imports = {};
|
|
|
- const primitives = new Set([
|
|
|
- 'int',
|
|
|
- 'long',
|
|
|
- 'int128',
|
|
|
- 'int256',
|
|
|
- 'double',
|
|
|
- 'string',
|
|
|
- 'bytes',
|
|
|
- 'Bool',
|
|
|
- 'true',
|
|
|
- ]);
|
|
|
+ const primitives = new Set(['int', 'long', 'int128', 'int256', 'double', 'string', 'bytes', 'Bool', 'true']);
|
|
|
|
|
|
// Find all the types in other files that are used in this file
|
|
|
// and generate the information required to import those types.
|
|
@@ -214,20 +183,18 @@ const writeModules = (
|
|
|
builder.writeln(line);
|
|
|
}
|
|
|
writeModuleExports(tlobjects, builder);
|
|
|
- if (file.indexOf("index.js") > 0) {
|
|
|
- for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
|
|
|
+ if (file.indexOf('index.js') > 0) {
|
|
|
+ for (const [ns] of Object.entries(namespaceTlobjects)) {
|
|
|
if (ns !== 'null') {
|
|
|
- builder.writeln("let %s = require('./%s');", ns, ns);
|
|
|
+ builder.writeln('let %s = require(\'./%s\');', ns, ns);
|
|
|
}
|
|
|
}
|
|
|
- for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
|
|
|
+ for (const [ns] of Object.entries(namespaceTlobjects)) {
|
|
|
if (ns !== 'null') {
|
|
|
- builder.writeln("module.exports.%s = %s;", ns, ns);
|
|
|
+ builder.writeln('module.exports.%s = %s;', ns, ns);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -237,8 +204,9 @@ const writeReadResult = (tlobject, builder) => {
|
|
|
//
|
|
|
// The default behaviour is reading a TLObject too, so no need
|
|
|
// to override it unless necessary.
|
|
|
- if (!tlobject.isFunction)
|
|
|
+ if (!tlobject.isFunction) {
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
// https://core.telegram.org/mtproto/serialize#boxed-and-bare-types
|
|
|
// TL;DR; boxed types start with uppercase always, so we can use
|
|
@@ -247,17 +215,18 @@ const writeReadResult = (tlobject, builder) => {
|
|
|
// Currently only un-boxed responses are Vector<int>/Vector<long>.
|
|
|
// If this weren't the case, we should check upper case after
|
|
|
// max(index('<'), index('.')) (and if it is, it's boxed, so return).
|
|
|
- let m = tlobject.result.match(/Vector<(int|long)>/);
|
|
|
+ const m = tlobject.result.match(/Vector<(int|long)>/);
|
|
|
if (!m) {
|
|
|
- return
|
|
|
+ return;
|
|
|
}
|
|
|
- //builder.endBlock();
|
|
|
+
|
|
|
+ // builder.endBlock();
|
|
|
builder.writeln('readResult(reader){');
|
|
|
builder.writeln('reader.readInt(); // Vector ID');
|
|
|
builder.writeln('let temp = [];');
|
|
|
- builder.writeln("let len = reader.readInt(); //fix this");
|
|
|
+ builder.writeln('let len = reader.readInt(); //fix this');
|
|
|
builder.writeln('for (let i=0;i<len;i++){');
|
|
|
- let read = m[1][0].toUpperCase() + m[1].slice(1);
|
|
|
+ const read = m[1][0].toUpperCase() + m[1].slice(1);
|
|
|
builder.writeln('temp.push(reader.read%s())', read);
|
|
|
builder.endBlock();
|
|
|
builder.writeln('return temp');
|
|
@@ -275,30 +244,20 @@ const writeReadResult = (tlobject, builder) => {
|
|
|
const writeSourceCode = (tlobject, kind, builder, typeConstructors) => {
|
|
|
writeClassConstructor(tlobject, kind, typeConstructors, builder);
|
|
|
writeResolve(tlobject, builder);
|
|
|
- //writeToJson(tlobject, builder);
|
|
|
+ // writeToJson(tlobject, builder);
|
|
|
writeToBytes(tlobject, builder);
|
|
|
builder.currentIndent--;
|
|
|
writeFromReader(tlobject, builder);
|
|
|
writeReadResult(tlobject, builder);
|
|
|
builder.currentIndent--;
|
|
|
builder.writeln('}');
|
|
|
-
|
|
|
};
|
|
|
|
|
|
-
|
|
|
const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
|
|
|
builder.writeln();
|
|
|
builder.writeln();
|
|
|
builder.writeln(`class ${tlobject.className} extends ${kind} {`);
|
|
|
|
|
|
- // Convert the args to string parameters, flags having =None
|
|
|
- const args = tlobject.realArgs.map(
|
|
|
- a =>
|
|
|
- `${a.name}: ${a.typeHint()}${
|
|
|
- a.isFlag || a.canBeInferred ? `=None` : ''
|
|
|
- }`
|
|
|
- );
|
|
|
-
|
|
|
// Write the __init__ function if it has any argument
|
|
|
if (!tlobject.realArgs.length) {
|
|
|
return;
|
|
@@ -306,10 +265,8 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
|
|
|
|
|
|
// Note : this is needed to be able to access them
|
|
|
// with or without an instance
|
|
|
- builder.writeln(
|
|
|
- `static CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`
|
|
|
- );
|
|
|
- builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString("16")};`);
|
|
|
+ builder.writeln(`static CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`);
|
|
|
+ builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`);
|
|
|
builder.writeln();
|
|
|
|
|
|
builder.writeln('/**');
|
|
@@ -327,11 +284,7 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
|
|
|
} else if (constructors.length === 1) {
|
|
|
builder.writeln(`Instance of ${constructors[0].className}`);
|
|
|
} else {
|
|
|
- builder.writeln(
|
|
|
- `Instance of either ${constructors
|
|
|
- .map(c => c.className)
|
|
|
- .join(', ')}`
|
|
|
- );
|
|
|
+ builder.writeln(`Instance of either ${constructors.map((c) => c.className).join(', ')}`);
|
|
|
}
|
|
|
|
|
|
builder.writeln('*/');
|
|
@@ -339,21 +292,23 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
|
|
|
builder.writeln(`super();`);
|
|
|
|
|
|
// Class-level variable to store its Telegram's constructor ID
|
|
|
- builder.writeln(
|
|
|
- `this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`
|
|
|
- );
|
|
|
- builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString("16")};`);
|
|
|
+ builder.writeln(`this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`);
|
|
|
+ builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`);
|
|
|
+
|
|
|
builder.writeln();
|
|
|
|
|
|
// Set the arguments
|
|
|
for (const arg of tlobject.realArgs) {
|
|
|
if (!arg.canBeInferred) {
|
|
|
- builder.writeln(`this.${variableSnakeToCamelCase(arg.name)} = args.${variableSnakeToCamelCase(arg.name)};`);
|
|
|
- }
|
|
|
+ builder.writeln(
|
|
|
+ `this.${variableSnakeToCamelCase(arg.name)}: ${a.typeHint()} = args.${variableSnakeToCamelCase(
|
|
|
+ arg.name
|
|
|
+ )}${a.isFlag || a.canBeInferred ? ' || null' : ''};`
|
|
|
+ );
|
|
|
|
|
|
// Currently the only argument that can be
|
|
|
- // inferred are those called 'random_id'
|
|
|
- else if (arg.name === 'random_id') {
|
|
|
+ // inferred are those called 'random_id'
|
|
|
+ } else if (arg.name === 'random_id') {
|
|
|
// Endianness doesn't really matter, and 'big' is shorter
|
|
|
let code = `Helpers.readBigIntFromBuffer(Helpers.generateRandomBytes(${
|
|
|
arg.type === 'long' ? 8 : 4
|
|
@@ -362,18 +317,14 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
|
|
|
if (arg.isVector) {
|
|
|
// Currently for the case of "messages.forwardMessages"
|
|
|
// Ensure we can infer the length from id:Vector<>
|
|
|
- if (!tlobject.realArgs.find(a => a.name === 'id').isVector) {
|
|
|
- throw new Error(
|
|
|
- `Cannot infer list of random ids for ${tlobject}`
|
|
|
- );
|
|
|
+ if (!tlobject.realArgs.find((a) => a.name === 'id').isVector) {
|
|
|
+ throw new Error(`Cannot infer list of random ids for ${tlobject}`);
|
|
|
}
|
|
|
|
|
|
code = `new Array(id.length).fill().map(_ => ${code})`;
|
|
|
}
|
|
|
|
|
|
- builder.writeln(
|
|
|
- `this.randomId = args.randomId !== undefined ? args.randomId : ${code};`
|
|
|
- );
|
|
|
+ builder.writeln(`this.randomId = args.randomId !== undefined ? args.randomId : ${code};`);
|
|
|
} else {
|
|
|
throw new Error(`Cannot infer a value for ${arg}`);
|
|
|
}
|
|
@@ -386,10 +337,9 @@ const writeResolve = (tlobject, builder) => {
|
|
|
if (
|
|
|
tlobject.isFunction &&
|
|
|
tlobject.realArgs.some(
|
|
|
- arg =>
|
|
|
+ (arg) =>
|
|
|
arg.type in AUTO_CASTS ||
|
|
|
- (`${arg.name},${arg.type}` in NAMED_AUTO_CASTS &&
|
|
|
- !NAMED_BLACKLIST.has(tlobject.fullname))
|
|
|
+ (`${arg.name},${arg.type}` in NAMED_AUTO_CASTS && !NAMED_BLACKLIST.has(tlobject.fullname))
|
|
|
)
|
|
|
) {
|
|
|
builder.writeln('async resolve(client, utils) {');
|
|
@@ -416,10 +366,7 @@ const writeResolve = (tlobject, builder) => {
|
|
|
builder.endBlock();
|
|
|
builder.writeln(`this.${arg.name} = _tmp;`);
|
|
|
} else {
|
|
|
- builder.writeln(
|
|
|
- `this.${arg.name} = %s`,
|
|
|
- util.format(ac, `this.${arg.name}`)
|
|
|
- );
|
|
|
+ builder.writeln(`this.${arg.name} = %s`, util.format(ac, `this.${arg.name}`));
|
|
|
}
|
|
|
|
|
|
if (arg.isFlag) {
|
|
@@ -482,7 +429,7 @@ const writeToBytes = (tlobject, builder) => {
|
|
|
// Some objects require more than one flag parameter to be set
|
|
|
// at the same time. In this case, add an assertion.
|
|
|
const repeatedArgs = {};
|
|
|
- for (let arg of tlobject.args) {
|
|
|
+ for (const arg of tlobject.args) {
|
|
|
if (arg.isFlag) {
|
|
|
if (!repeatedArgs[arg.flagIndex]) {
|
|
|
repeatedArgs[arg.flagIndex] = [];
|
|
@@ -490,66 +437,64 @@ const writeToBytes = (tlobject, builder) => {
|
|
|
repeatedArgs[arg.flagIndex].push(arg);
|
|
|
}
|
|
|
}
|
|
|
- for (let ra of Object.values(repeatedArgs)) {
|
|
|
+
|
|
|
+ for (const ra of Object.values(repeatedArgs)) {
|
|
|
if (ra.length > 1) {
|
|
|
- let cnd1 = [];
|
|
|
- let cnd2 = [];
|
|
|
- let names = [];
|
|
|
+ const cnd1 = [];
|
|
|
+ const cnd2 = [];
|
|
|
+ const names = [];
|
|
|
|
|
|
- for (let a of ra) {
|
|
|
+ for (const a of ra) {
|
|
|
cnd1.push(`this.${a.name} || this.${a.name}!==null`);
|
|
|
cnd2.push(`this.${a.name}===null || this.${a.name}===false`);
|
|
|
names.push(a.name);
|
|
|
}
|
|
|
- builder.writeln("if (!((%s) && (%s)))\n\t throw new Error('%s paramaters must all"
|
|
|
- + " be false-y or all true')", cnd1.join(" && "), cnd2.join(" && "), names.join(", "));
|
|
|
+ builder.writeln(
|
|
|
+ 'if (!((%s) && (%s)))\n\t throw new Error(\'%s paramaters must all be false-y or all true\')',
|
|
|
+ cnd1.join(' && '),
|
|
|
+ cnd2.join(' && '),
|
|
|
+ names.join(', ')
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
- builder.writeln("return Buffer.concat([");
|
|
|
+ builder.writeln('return Buffer.concat([');
|
|
|
builder.currentIndent++;
|
|
|
- let b = Buffer.alloc(4);
|
|
|
+ const b = Buffer.alloc(4);
|
|
|
b.writeUInt32LE(tlobject.id, 0);
|
|
|
// First constructor code, we already know its bytes
|
|
|
- builder.writeln('Buffer.from("%s","hex"),', b.toString("hex"));
|
|
|
- for (let arg of tlobject.args) {
|
|
|
+ builder.writeln('Buffer.from("%s","hex"),', b.toString('hex'));
|
|
|
+ for (const arg of tlobject.args) {
|
|
|
if (writeArgToBytes(builder, arg, tlobject.args)) {
|
|
|
builder.writeln(',');
|
|
|
}
|
|
|
}
|
|
|
- builder.writeln("])");
|
|
|
+ builder.writeln('])');
|
|
|
builder.endBlock();
|
|
|
-
|
|
|
};
|
|
|
|
|
|
// writeFromReader
|
|
|
const writeFromReader = (tlobject, builder) => {
|
|
|
-
|
|
|
- builder.writeln("static fromReader(reader) {");
|
|
|
+ builder.writeln('static fromReader(reader) {');
|
|
|
for (const arg of tlobject.args) {
|
|
|
-
|
|
|
- if (arg.name !== "flag") {
|
|
|
-
|
|
|
-
|
|
|
- if (arg.name !== "x") {
|
|
|
-
|
|
|
-
|
|
|
- builder.writeln("let %s", "_" + arg.name + ";");
|
|
|
+ if (arg.name !== 'flag') {
|
|
|
+ if (arg.name !== 'x') {
|
|
|
+ builder.writeln('let %s', '_' + arg.name + ';');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- // TODO fix this really
|
|
|
- builder.writeln("let _x;");
|
|
|
- builder.writeln("let len;");
|
|
|
|
|
|
+ // TODO fix this really
|
|
|
+ builder.writeln('let _x;');
|
|
|
+ builder.writeln('let len;');
|
|
|
|
|
|
for (const arg of tlobject.args) {
|
|
|
- writeArgReadCode(builder, arg, tlobject.args, "_" + arg.name);
|
|
|
+ writeArgReadCode(builder, arg, tlobject.args, '_' + arg.name);
|
|
|
}
|
|
|
- let temp = [];
|
|
|
- for (let a of tlobject.realArgs) {
|
|
|
- temp.push(`${variableSnakeToCamelCase(a.name)}:_${a.name}`)
|
|
|
+ const temp = [];
|
|
|
+ for (const a of tlobject.realArgs) {
|
|
|
+ temp.push(`${variableSnakeToCamelCase(a.name)}:_${a.name}`);
|
|
|
}
|
|
|
- builder.writeln("return new this({%s})", temp.join(",\n\t"));
|
|
|
+ builder.writeln('return new this({%s})', temp.join(',\n\t'));
|
|
|
builder.endBlock();
|
|
|
};
|
|
|
// writeReadResult
|
|
@@ -568,12 +513,11 @@ const writeArgToBytes = (builder, arg, args, name = null) => {
|
|
|
if (arg.genericDefinition) {
|
|
|
return; // Do nothing, this only specifies a later type
|
|
|
}
|
|
|
+
|
|
|
if (name === null) {
|
|
|
name = `this.${arg.name}`;
|
|
|
}
|
|
|
- if (name =="this.msg_ids"){
|
|
|
- console.log(name)
|
|
|
- }
|
|
|
+
|
|
|
name = variableSnakeToCamelCase(name);
|
|
|
// The argument may be a flag, only write if it's not None AND
|
|
|
// if it's not a True type.
|
|
@@ -587,22 +531,22 @@ const writeArgToBytes = (builder, arg, args, name = null) => {
|
|
|
// so we need an extra join here. Note that empty vector flags
|
|
|
// should NOT be sent either!
|
|
|
builder.write(
|
|
|
- "(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) :Buffer.concat([",
|
|
|
+ '(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) :Buffer.concat([',
|
|
|
name,
|
|
|
name,
|
|
|
name
|
|
|
);
|
|
|
} else {
|
|
|
- builder.write("(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) : [", name, name,name);
|
|
|
+ builder.write('(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) : [', name, name, name);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (arg.isVector) {
|
|
|
if (arg.useVectorId) {
|
|
|
- builder.write("Buffer.from('15c4b51c','hex'),");
|
|
|
+ builder.write('Buffer.from(\'15c4b51c\', \'hex\'),');
|
|
|
}
|
|
|
|
|
|
- builder.write("struct.pack('<i', %s.length),", name);
|
|
|
+ builder.write('struct.pack(\'<i\', %s.length),', name);
|
|
|
|
|
|
// Cannot unpack the values for the outer tuple through *[(
|
|
|
// since that's a Python >3.5 feature, so add another join.
|
|
@@ -618,34 +562,37 @@ const writeArgToBytes = (builder, arg, args, name = null) => {
|
|
|
builder.write('))');
|
|
|
} else if (arg.flagIndicator) {
|
|
|
// Calculate the flags with those items which are not None
|
|
|
- if (!args.some(f => f.isFlag)) {
|
|
|
+ if (!args.some((f) => f.isFlag)) {
|
|
|
// There's a flag indicator, but no flag arguments so it's 0
|
|
|
builder.write('Buffer.alloc(4)');
|
|
|
} else {
|
|
|
- builder.write("struct.pack('<I', ");
|
|
|
+ builder.write('struct.pack(\'<I\', ');
|
|
|
builder.write(
|
|
|
args
|
|
|
- .filter(flag => flag.isFlag)
|
|
|
+ .filter((flag) => flag.isFlag)
|
|
|
.map(
|
|
|
- flag =>
|
|
|
- `(this.${variableSnakeToCamelCase(flag.name)} === undefined || this.${
|
|
|
- variableSnakeToCamelCase(flag.name)
|
|
|
- } === false || this.${variableSnakeToCamelCase(flag.name)} === null) ? 0 : ${1 << flag.flagIndex}`
|
|
|
+ (flag) =>
|
|
|
+ `(this.${variableSnakeToCamelCase(
|
|
|
+ flag.name
|
|
|
+ )} === undefined || this.${variableSnakeToCamelCase(
|
|
|
+ flag.name
|
|
|
+ )} === false || this.${variableSnakeToCamelCase(flag.name)} === null) ? 0 : ${1 <<
|
|
|
+ flag.flagIndex}`
|
|
|
)
|
|
|
.join(' | ')
|
|
|
);
|
|
|
builder.write(')');
|
|
|
}
|
|
|
} else if (arg.type === 'int') {
|
|
|
- builder.write("struct.pack('<i', %s)", name);
|
|
|
+ builder.write('struct.pack(\'<i\', %s)', name);
|
|
|
} else if (arg.type === 'long') {
|
|
|
- builder.write("Helpers.readBufferFromBigInt(%s,8,true,true)", name);
|
|
|
+ builder.write('Helpers.readBufferFromBigInt(%s,8,true,true)', name);
|
|
|
} else if (arg.type === 'int128') {
|
|
|
- builder.write("Helpers.readBufferFromBigInt(%s,16,true,true)", name);
|
|
|
+ builder.write('Helpers.readBufferFromBigInt(%s,16,true,true)', name);
|
|
|
} else if (arg.type === 'int256') {
|
|
|
- builder.write("Helpers.readBufferFromBigInt(%s,32,true,true)", name);
|
|
|
+ builder.write('Helpers.readBufferFromBigInt(%s,32,true,true)', name);
|
|
|
} else if (arg.type === 'double') {
|
|
|
- builder.write("struct.pack('<d', %s.toString())", name);
|
|
|
+ builder.write('struct.pack(\'<d\', %s.toString())', name);
|
|
|
} else if (arg.type === 'string') {
|
|
|
builder.write('TLObject.serializeBytes(%s)', name);
|
|
|
} else if (arg.type === 'Bool') {
|
|
@@ -681,7 +628,6 @@ const writeArgToBytes = (builder, arg, args, name = null) => {
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Writes the read code for the given argument, setting the
|
|
|
* arg.name variable to its read value.
|
|
@@ -695,20 +641,20 @@ const writeArgToBytes = (builder, arg, args, name = null) => {
|
|
|
*/
|
|
|
const writeArgReadCode = (builder, arg, args, name) => {
|
|
|
if (arg.genericDefinition) {
|
|
|
- return // Do nothing, this only specifies a later type
|
|
|
+ return; // Do nothing, this only specifies a later type
|
|
|
}
|
|
|
- //The argument may be a flag, only write that flag was given!
|
|
|
+ // The argument may be a flag, only write that flag was given!
|
|
|
let wasFlag = false;
|
|
|
if (arg.isFlag) {
|
|
|
// Treat 'true' flags as a special case, since they're true if
|
|
|
// they're set, and nothing else needs to actually be read.
|
|
|
- if (arg.type === "true") {
|
|
|
- builder.writeln("%s = Boolean(flags & %s);", name, 1 << arg.flagIndex);
|
|
|
+ if (arg.type === 'true') {
|
|
|
+ builder.writeln('%s = Boolean(flags & %s);', name, 1 << arg.flagIndex);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
wasFlag = true;
|
|
|
- builder.writeln("if (flags & %s) {", 1 << arg.flagIndex);
|
|
|
+ builder.writeln('if (flags & %s) {', 1 << arg.flagIndex);
|
|
|
// Temporary disable .is_flag not to enter this if
|
|
|
// again when calling the method recursively
|
|
|
arg.isFlag = false;
|
|
@@ -717,41 +663,41 @@ const writeArgReadCode = (builder, arg, args, name) => {
|
|
|
if (arg.isVector) {
|
|
|
if (arg.useVectorId) {
|
|
|
// We have to read the vector's constructor ID
|
|
|
- builder.writeln("reader.readInt();");
|
|
|
+ builder.writeln('reader.readInt();');
|
|
|
}
|
|
|
- builder.writeln("%s = [];", name);
|
|
|
- builder.writeln("len = reader.readInt();");
|
|
|
+
|
|
|
+ builder.writeln('%s = [];', name);
|
|
|
+ builder.writeln('len = reader.readInt();');
|
|
|
builder.writeln('for (let i=0;i<len;i++){');
|
|
|
|
|
|
// Temporary disable .is_vector, not to enter this if again
|
|
|
arg.isVector = false;
|
|
|
- writeArgReadCode(builder, arg, args, "_x");
|
|
|
- builder.writeln("%s.push(_x);", name);
|
|
|
+ writeArgReadCode(builder, arg, args, '_x');
|
|
|
+ builder.writeln('%s.push(_x);', name);
|
|
|
arg.isVector = true;
|
|
|
-
|
|
|
} else if (arg.flagIndicator) {
|
|
|
- //Read the flags, which will indicate what items we should read next
|
|
|
- builder.writeln("let flags = reader.readInt();");
|
|
|
+ // Read the flags, which will indicate what items we should read next
|
|
|
+ builder.writeln('let flags = reader.readInt();');
|
|
|
builder.writeln();
|
|
|
- } else if (arg.type === "int") {
|
|
|
- builder.writeln("%s = reader.readInt();", name)
|
|
|
- } else if (arg.type === "long") {
|
|
|
- builder.writeln("%s = reader.readLong();", name);
|
|
|
- } else if (arg.type === "int128") {
|
|
|
+ } else if (arg.type === 'int') {
|
|
|
+ builder.writeln('%s = reader.readInt();', name);
|
|
|
+ } else if (arg.type === 'long') {
|
|
|
+ builder.writeln('%s = reader.readLong();', name);
|
|
|
+ } else if (arg.type === 'int128') {
|
|
|
builder.writeln('%s = reader.readLargeInt(128);', name);
|
|
|
- } else if (arg.type === "int256") {
|
|
|
+ } else if (arg.type === 'int256') {
|
|
|
builder.writeln('%s = reader.readLargeInt(256);', name);
|
|
|
- } else if (arg.type === "double") {
|
|
|
+ } else if (arg.type === 'double') {
|
|
|
builder.writeln('%s = reader.readDouble();', name);
|
|
|
- } else if (arg.type === "string") {
|
|
|
+ } else if (arg.type === 'string') {
|
|
|
builder.writeln('%s = reader.tgReadString();', name);
|
|
|
- } else if (arg.type === "Bool") {
|
|
|
+ } else if (arg.type === 'Bool') {
|
|
|
builder.writeln('%s = reader.tgReadBool();', name);
|
|
|
- } else if (arg.type === "true") {
|
|
|
+ } else if (arg.type === 'true') {
|
|
|
builder.writeln('%s = true;', name);
|
|
|
- } else if (arg.type === "bytes") {
|
|
|
+ } else if (arg.type === 'bytes') {
|
|
|
builder.writeln('%s = reader.tgReadBytes();', name);
|
|
|
- } else if (arg.type === "date") {
|
|
|
+ } else if (arg.type === 'date') {
|
|
|
builder.writeln('%s = reader.tgReadDate();', name);
|
|
|
} else {
|
|
|
// Else it may be a custom type
|
|
@@ -762,45 +708,46 @@ const writeArgReadCode = (builder, arg, args, name) => {
|
|
|
// There may be better solutions so that we can just access
|
|
|
// all the types before the files have been parsed, but I
|
|
|
// don't know of any.
|
|
|
- let sepIndex = arg.type.indexOf(".");
|
|
|
- let ns, t;
|
|
|
+ const sepIndex = arg.type.indexOf('.');
|
|
|
+ let ns;
|
|
|
+ let t;
|
|
|
+
|
|
|
if (sepIndex === -1) {
|
|
|
- ns = ".";
|
|
|
+ ns = '.';
|
|
|
t = arg.type;
|
|
|
} else {
|
|
|
- ns = "." + arg.type.slice(0, sepIndex);
|
|
|
+ ns = '.' + arg.type.slice(0, sepIndex);
|
|
|
t = arg.type.slice(sepIndex + 1);
|
|
|
}
|
|
|
- let className = snakeToCamelCase(t);
|
|
|
+
|
|
|
+ const className = snakeToCamelCase(t);
|
|
|
|
|
|
// There would be no need to import the type if we're in the
|
|
|
// file with the same namespace, but since it does no harm
|
|
|
// and we don't have information about such thing in the
|
|
|
// method we just ignore that case.
|
|
|
builder.writeln('let %s = require("%s");', className, ns);
|
|
|
- builder.writeln("%s = %s.fromReader(reader);", name, className);
|
|
|
+ builder.writeln('%s = %s.fromReader(reader);', name, className);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// End vector and flag blocks if required (if we opened them before)
|
|
|
if (arg.isVector) {
|
|
|
- builder.writeln("}");
|
|
|
-
|
|
|
+ builder.writeln('}');
|
|
|
}
|
|
|
+
|
|
|
if (wasFlag) {
|
|
|
builder.endBlock();
|
|
|
- builder.writeln("else {");
|
|
|
- builder.writeln("%s = null", name);
|
|
|
+ builder.writeln('else {');
|
|
|
+ builder.writeln('%s = null', name);
|
|
|
builder.endBlock();
|
|
|
// Restore .isFlag;
|
|
|
arg.isFlag = true;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-
|
|
|
const writePatched = (outDir, namespaceTlobjects) => {
|
|
|
-
|
|
|
- fs.mkdirSync(outDir, {recursive: true});
|
|
|
+ fs.mkdirSync(outDir, { recursive: true });
|
|
|
|
|
|
for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
|
|
|
const file = `${outDir}/${ns === 'null' ? 'index' : ns}.js`;
|
|
@@ -808,41 +755,32 @@ const writePatched = (outDir, namespaceTlobjects) => {
|
|
|
const builder = new SourceBuilder(stream);
|
|
|
|
|
|
builder.writeln(AUTO_GEN_NOTICE);
|
|
|
- builder.writeln("const struct = require('python-struct');");
|
|
|
+ builder.writeln('const struct = require(\'python-struct\');');
|
|
|
builder.writeln(`const { TLObject, types, custom } = require('..');`);
|
|
|
builder.writeln(`const Helpers = require('../../utils/Helpers');`);
|
|
|
|
|
|
builder.writeln();
|
|
|
|
|
|
for (const t of tlobjects) {
|
|
|
- builder.writeln(
|
|
|
- 'class %s extends custom.%s {',
|
|
|
- t.className,
|
|
|
- PATCHED_TYPES[t.fullname]
|
|
|
- );
|
|
|
+ builder.writeln('class %s extends custom.%s {', t.className, PATCHED_TYPES[t.fullname]);
|
|
|
builder.writeln(`static CONSTRUCTOR_ID = 0x${t.id.toString(16)}`);
|
|
|
- builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(t.result).toString("16")}`);
|
|
|
+ builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(t.result).toString('16')}`);
|
|
|
builder.writeln();
|
|
|
builder.writeln('constructor() {');
|
|
|
builder.writeln('super();');
|
|
|
builder.writeln(`this.CONSTRUCTOR_ID = 0x${t.id.toString(16)}`);
|
|
|
- builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(t.result).toString("16")}`);
|
|
|
+ builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(t.result).toString('16')}`);
|
|
|
|
|
|
builder.endBlock();
|
|
|
|
|
|
- //writeToJson(t, builder);
|
|
|
+ // writeToJson(t, builder);
|
|
|
writeToBytes(t, builder);
|
|
|
writeFromReader(t, builder);
|
|
|
|
|
|
builder.writeln();
|
|
|
builder.endBlock();
|
|
|
builder.currentIndent = 0;
|
|
|
- builder.writeln(
|
|
|
- 'types.%s%s = %s',
|
|
|
- t.namespace ? `${t.namespace}.` : '',
|
|
|
- t.className,
|
|
|
- t.className
|
|
|
- );
|
|
|
+ builder.writeln('types.%s%s = %s', t.namespace ? `${t.namespace}.` : '', t.className, t.className);
|
|
|
builder.writeln();
|
|
|
}
|
|
|
}
|
|
@@ -852,7 +790,7 @@ const writeAllTLObjects = (tlobjects, layer, builder) => {
|
|
|
builder.writeln(AUTO_GEN_NOTICE);
|
|
|
builder.writeln();
|
|
|
|
|
|
- builder.writeln("const { types, functions, patched } = require('.');");
|
|
|
+ builder.writeln('const { types, functions, patched } = require(\'.\');');
|
|
|
builder.writeln();
|
|
|
|
|
|
// Create a constant variable to indicate which layer this is
|
|
@@ -925,20 +863,8 @@ const generateTLObjects = (tlobjects, layer, importDepth, outputDir) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- writeModules(
|
|
|
- `${outputDir}/functions`,
|
|
|
- importDepth,
|
|
|
- 'TLRequest',
|
|
|
- namespaceFunctions,
|
|
|
- typeConstructors
|
|
|
- );
|
|
|
- writeModules(
|
|
|
- `${outputDir}/types`,
|
|
|
- importDepth,
|
|
|
- 'TLObject',
|
|
|
- namespaceTypes,
|
|
|
- typeConstructors
|
|
|
- );
|
|
|
+ writeModules(`${outputDir}/functions`, importDepth, 'TLRequest', namespaceFunctions, typeConstructors);
|
|
|
+ writeModules(`${outputDir}/types`, importDepth, 'TLObject', namespaceTypes, typeConstructors);
|
|
|
writePatched(`${outputDir}/patched`, namespacePatched);
|
|
|
|
|
|
const filename = `${outputDir}/alltlobjects.js`;
|
|
@@ -948,8 +874,8 @@ const generateTLObjects = (tlobjects, layer, importDepth, outputDir) => {
|
|
|
writeAllTLObjects(tlobjects, layer, builder);
|
|
|
};
|
|
|
|
|
|
-const cleanTLObjects = outputDir => {
|
|
|
- for (let d in ['functions', 'types', 'patched']) {
|
|
|
+const cleanTLObjects = (outputDir) => {
|
|
|
+ for (let d of ['functions', 'types', 'patched']) {
|
|
|
d = `${outputDir}/d`;
|
|
|
|
|
|
if (fs.statSync(d).isDirectory()) {
|
|
@@ -965,7 +891,6 @@ const cleanTLObjects = outputDir => {
|
|
|
};
|
|
|
|
|
|
const writeModuleExports = (tlobjects, builder) => {
|
|
|
-
|
|
|
builder.writeln('module.exports = {');
|
|
|
|
|
|
for (const t of tlobjects) {
|