fix: handle vectors of primitives in rpc_result

This commit is contained in:
alina 🌸 2023-07-20 22:07:07 +03:00
parent 99e83b40aa
commit 6221a8716f
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
21 changed files with 241 additions and 80 deletions

View file

@ -101,7 +101,7 @@ export function normalizeToInputChannel(
} }
} }
throw new MtInvalidPeerTypeError(input ?? res, 'user') throw new MtInvalidPeerTypeError(input ?? res, 'channel')
} }
export function isInputPeerUser( export function isInputPeerUser(

View file

@ -394,6 +394,13 @@ export class SessionConnection extends PersistentConnection {
return return
} }
if (message.peekUint() === 0xf35c6d01) {
// rpc_result
message.uint()
return this._onRpcResult(message)
}
// we are safe.. i guess // we are safe.. i guess
this._handleMessage(messageId, message.object()) this._handleMessage(messageId, message.object())
} }
@ -433,9 +440,6 @@ export class SessionConnection extends PersistentConnection {
} }
switch (message._) { switch (message._) {
case 'mt_rpc_result':
this._onRpcResult(message)
break
case 'mt_pong': case 'mt_pong':
this._onPong(message) this._onPong(message)
break break
@ -482,7 +486,9 @@ export class SessionConnection extends PersistentConnection {
break break
default: default:
if (tl.isAnyUpdates(message)) { if (tl.isAnyUpdates(message)) {
if (this._usable && this.params.inactivityTimeout) { this._rescheduleInactivity() } if (this._usable && this.params.inactivityTimeout) {
this._rescheduleInactivity()
}
this.emit('update', message) this.emit('update', message)
@ -493,13 +499,24 @@ export class SessionConnection extends PersistentConnection {
} }
} }
private _onRpcResult({ result, reqMsgId }: mtp.RawMt_rpc_result): void { private _onRpcResult(message: TlBinaryReader): void {
if (this._usable && this.params.inactivityTimeout) { this._rescheduleInactivity() } if (this._usable && this.params.inactivityTimeout) {
this._rescheduleInactivity()
}
const reqMsgId = message.long()
if (reqMsgId.isZero()) { if (reqMsgId.isZero()) {
let resultType
try {
resultType = (message.object() as any)._
} catch (err) {
resultType = message.peekUint()
}
this.log.warn( this.log.warn(
'received rpc_result with %s with req_msg_id = 0', 'received rpc_result with %s with req_msg_id = 0',
result._, resultType,
) )
return return
@ -508,12 +525,24 @@ export class SessionConnection extends PersistentConnection {
const msg = this._pendingMessages.get(reqMsgId) const msg = this._pendingMessages.get(reqMsgId)
if (!msg) { if (!msg) {
let result
try {
result = message.object() as any
} catch (err) {
result = '[failed to parse]'
}
this.log.warn(
'received rpc_result with %s with req_msg_id = 0',
result,
)
// check if the msg is one of the recent ones // check if the msg is one of the recent ones
if (this._recentOutgoingMsgIds.has(reqMsgId)) { if (this._recentOutgoingMsgIds.has(reqMsgId)) {
this.log.debug( this.log.debug(
'received rpc_result again for %l (contains %s)', 'received rpc_result again for %l (contains %s)',
reqMsgId, reqMsgId,
result._, result,
) )
} else { } else {
this.log.warn( this.log.warn(
@ -537,6 +566,11 @@ export class SessionConnection extends PersistentConnection {
} }
const rpc = msg.rpc const rpc = msg.rpc
const customReader = this._readerMap._results![rpc.method]
const result: any = customReader ?
customReader(message) :
message.object()
// initConnection call was definitely received and // initConnection call was definitely received and
// processed by the server, so we no longer need to use it // processed by the server, so we no longer need to use it
if (rpc.initConn) this._initConnectionCalled = true if (rpc.initConn) this._initConnectionCalled = true
@ -1056,7 +1090,9 @@ export class SessionConnection extends PersistentConnection {
stack?: string, stack?: string,
timeout?: number, timeout?: number,
): Promise<tl.RpcCallReturn[T['_']]> { ): Promise<tl.RpcCallReturn[T['_']]> {
if (this._usable && this.params.inactivityTimeout) { this._rescheduleInactivity() } if (this._usable && this.params.inactivityTimeout) {
this._rescheduleInactivity()
}
if (!stack && this.params.niceStacks !== false) { if (!stack && this.params.niceStacks !== false) {
stack = new Error().stack stack = new Error().stack
@ -1162,7 +1198,7 @@ export class SessionConnection extends PersistentConnection {
timeout: undefined, timeout: undefined,
} }
const promise = createCancellablePromise( const promise = createCancellablePromise<any>(
this._cancelRpc.bind(this, pending), this._cancelRpc.bind(this, pending),
) )
pending.promise = promise pending.promise = promise

View file

@ -18,7 +18,10 @@ const TWO_PWR_32_DBL = (1 << 16) * (1 << 16)
*/ */
// avoid unnecessary type complexity // avoid unnecessary type complexity
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type TlReaderMap = Record<number, (r: any) => unknown> export type TlReaderMap = Record<number, (r: any) => unknown> & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_results?: Record<string, (r: any) => unknown>
}
/** /**
* Reader for TL objects. * Reader for TL objects.
@ -157,7 +160,8 @@ export class TlBinaryReader {
bytes(): Buffer { bytes(): Buffer {
const firstByte = this.data[this.pos++] const firstByte = this.data[this.pos++]
let length; let padding let length
let padding
if (firstByte === 254) { if (firstByte === 254) {
length = length =
@ -183,7 +187,9 @@ export class TlBinaryReader {
object(): unknown { object(): unknown {
const id = this.uint() const id = this.uint()
if (id === 0x1cb5c415 /* vector */) { return this.vector(this.object, true) } if (id === 0x1cb5c415 /* vector */) {
return this.vector(this.object, true)
}
if (id === 0x3072cfa1 /* gzip_packed */) return this.gzip() if (id === 0x3072cfa1 /* gzip_packed */) return this.gzip()
if (id === 0xbc799737 /* boolFalse */) return false if (id === 0xbc799737 /* boolFalse */) return false
if (id === 0x997275b5 /* boolTrue */) return true if (id === 0x997275b5 /* boolTrue */) return true
@ -251,7 +257,9 @@ export class TlBinaryReader {
* @param pos Position to seek to * @param pos Position to seek to
*/ */
seekTo(pos: number): void { seekTo(pos: number): void {
if (pos >= this.data.length || pos < 0) { throw new RangeError('New position is out of range') } if (pos >= this.data.length || pos < 0) {
throw new RangeError('New position is out of range')
}
this.pos = pos this.pos = pos
} }
} }

View file

@ -7,7 +7,10 @@ const TWO_PWR_32_DBL = (1 << 16) * (1 << 16)
*/ */
// avoid unnecessary type complexity // avoid unnecessary type complexity
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type TlWriterMap = Record<string, (w: any, val: any) => void> export type TlWriterMap = Record<string, (w: any, val: any) => void> & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_bare?: Record<number, (w: any, val: any) => void>
}
/** /**
* Counter of the required number of bytes to encode a given object. * Counter of the required number of bytes to encode a given object.
@ -198,7 +201,9 @@ export class TlBinaryWriter {
obj: { _: string }, obj: { _: string },
knownSize = -1, knownSize = -1,
): Buffer { ): Buffer {
if (knownSize === -1) { knownSize = TlSerializationCounter.countNeededBytes(objectMap, obj) } if (knownSize === -1) {
knownSize = TlSerializationCounter.countNeededBytes(objectMap, obj)
}
const writer = TlBinaryWriter.alloc(objectMap, knownSize) const writer = TlBinaryWriter.alloc(objectMap, knownSize)
@ -315,7 +320,11 @@ export class TlBinaryWriter {
fn(this, obj) fn(this, obj)
} }
vector(fn: (item: unknown, bare?: boolean) => void, val: unknown[], bare?: boolean): void { vector(
fn: (item: unknown, bare?: boolean) => void,
val: unknown[],
bare?: boolean,
): void {
if (!bare) this.uint(0x1cb5c415) if (!bare) this.uint(0x1cb5c415)
this.uint(val.length) this.uint(val.length)

View file

@ -19,12 +19,23 @@ export interface ReaderCodegenOptions {
* Whether to include methods in the readers map * Whether to include methods in the readers map
*/ */
includeMethods?: boolean includeMethods?: boolean
/**
* Whether to include `._results` field in the result object,
* containing a map of methods names to their result readers.
*
* Requires `parseMethodTypes` to be `true` when parsing the TL schema.
*
* **Note**: will only work for primitives and vectors of primitives
*/
includeMethodResults?: boolean
} }
const DEFAULT_OPTIONS: ReaderCodegenOptions = { const DEFAULT_OPTIONS: ReaderCodegenOptions = {
includeFlags: false, includeFlags: false,
variableName: 'm', variableName: 'm',
includeMethods: false, includeMethods: false,
includeMethodResults: false,
} }
/** /**
@ -177,5 +188,34 @@ export function generateReaderCodeForTlEntries(
ret += generateReaderCodeForTlEntry(entry, params) + '\n' ret += generateReaderCodeForTlEntry(entry, params) + '\n'
}) })
if (params.includeMethodResults) {
ret += '_results:{\n'
entries.forEach((entry) => {
if (entry.kind !== 'method') return
const pre = `'${entry.name}':function(r){return `
const isVector =
entry.typeModifiers?.isVector ||
entry.typeModifiers?.isBareVector
const post = entry.typeModifiers?.isBareVector ? ',1' : ''
if (entry.type in TL_PRIMITIVES) {
const type = entry.type
// booleans can be properly parsed as they have own constructor ids
if (type === 'Bool' || type === 'bool') return
if (isVector) {
ret += `${pre}r.vector(r.${type}${post})},\n`
} else {
ret += `${pre}r.${type}()},\n`
}
}
})
ret += '},\n'
}
return ret + '}' return ret + '}'
} }

View file

@ -1,4 +1,4 @@
import { TlEntry, TlErrors, TlFullSchema } from '../types' import { TlEntry, TlErrors, TlFullSchema, TlTypeModifiers } from '../types'
import { groupTlEntriesByNamespace, splitNameToNamespace } from '../utils' import { groupTlEntriesByNamespace, splitNameToNamespace } from '../utils'
import { errorCodeToClassName, generateCodeForErrors } from './errors' import { errorCodeToClassName, generateCodeForErrors } from './errors'
import { camelToPascal, indent, jsComment, snakeToCamel } from './utils' import { camelToPascal, indent, jsComment, snakeToCamel } from './utils'
@ -26,10 +26,31 @@ export const PRIMITIVE_TO_TS: Record<string, string> = {
function fullTypeName( function fullTypeName(
type: string, type: string,
baseNamespace: string, baseNamespace: string,
namespace = true, {
method = false, namespace = true,
link = false, method = false,
link = false,
typeModifiers,
}: {
namespace?: boolean
method?: boolean
link?: boolean
typeModifiers?: TlTypeModifiers
} = {},
): string { ): string {
if (typeModifiers) {
const inner = fullTypeName(type, baseNamespace, {
namespace,
method,
link,
})
if (typeModifiers.isVector || typeModifiers.isBareVector) {
if (link) return `${inner} array`
return `${inner}[]`
}
}
if (type in PRIMITIVE_TO_TS) return PRIMITIVE_TO_TS[type] if (type in PRIMITIVE_TO_TS) return PRIMITIVE_TO_TS[type]
const [ns, name] = splitNameToNamespace(type) const [ns, name] = splitNameToNamespace(type)
@ -52,7 +73,10 @@ function fullTypeName(
} }
function entryFullTypeName(entry: TlEntry): string { function entryFullTypeName(entry: TlEntry): string {
return fullTypeName(entry.name, '', false, entry.kind === 'method') return fullTypeName(entry.name, '', {
namespace: false,
method: entry.kind === 'method',
})
} }
/** /**
@ -82,9 +106,7 @@ export function generateTypescriptDefinitionsForTlEntry(
comment += `RPC method returns ${fullTypeName( comment += `RPC method returns ${fullTypeName(
entry.type, entry.type,
baseNamespace, baseNamespace,
true, { link: true, typeModifiers: entry.typeModifiers },
false,
true,
)}` )}`
if (errors) { if (errors) {
@ -151,10 +173,10 @@ export function generateTypescriptDefinitionsForTlEntry(
typeFinal = true typeFinal = true
} }
if (!typeFinal) type = fullTypeName(arg.type, baseNamespace) if (!typeFinal) {
type = fullTypeName(arg.type, baseNamespace, {
if (arg.typeModifiers?.isVector || arg.typeModifiers?.isBareVector) { typeModifiers: arg.typeModifiers,
type += '[]' })
} }
ret += `: ${type};\n` ret += `: ${type};\n`
@ -306,7 +328,9 @@ export function generateTypescriptDefinitionsForTlSchema(
} }
if (!type) { if (!type) {
type = fullTypeName(entry.type, namespace + '.') type = fullTypeName(entry.type, namespace + '.', {
typeModifiers: entry.typeModifiers,
})
} }
ts += indent(indentSize + 4, `'${entry.name}': ${type}`) + '\n' ts += indent(indentSize + 4, `'${entry.name}': ${type}`) + '\n'
@ -324,7 +348,7 @@ export function generateTypescriptDefinitionsForTlSchema(
if (union.comment) { if (union.comment) {
ts += indent(indentSize, jsComment(union.comment)) + '\n' ts += indent(indentSize, jsComment(union.comment)) + '\n'
} }
const typeName = fullTypeName(name, '', false) const typeName = fullTypeName(name, '', { namespace: false })
const typeWithoutNs = typeName.substring(4) const typeWithoutNs = typeName.substring(4)
ts += indent(indentSize, `type ${typeName} = `) ts += indent(indentSize, `type ${typeName} = `)
@ -364,7 +388,8 @@ export function generateTypescriptDefinitionsForTlSchema(
ts += ts +=
indent( indent(
8, 8,
'| ' + fullTypeName(entry.name, namespace + '.', true, true), '| ' +
fullTypeName(entry.name, namespace + '.', { method: true }),
) + '\n' ) + '\n'
} }
@ -381,12 +406,9 @@ export function generateTypescriptDefinitionsForTlSchema(
indent( indent(
8, 8,
'| ' + '| ' +
fullTypeName( fullTypeName(entry.name, namespace + '.', {
entry.name, method: entry.kind === 'method',
namespace + '.', }),
true,
entry.kind === 'method',
),
) + '\n' ) + '\n'
}) })

View file

@ -15,14 +15,16 @@ export function mergeTlEntries(entries: TlEntry[]): TlEntry | string {
kind: first.kind, kind: first.kind,
name: first.name, name: first.name,
type: first.type, type: first.type,
typeModifiers: first.typeModifiers,
id: first.id, id: first.id,
comment: first.comment, comment: first.comment,
generics: first.generics, generics: first.generics,
arguments: first.arguments, arguments: first.arguments,
} }
// even if the entry contains id, let's re-calculate it just to be sure if (result.id === 0) {
result.id = computeConstructorIdFromEntry(result) result.id = computeConstructorIdFromEntry(result)
}
const argsIndex: Record<string, true> = {} const argsIndex: Record<string, true> = {}
const flagsLastIndex: Record<string, number> = {} const flagsLastIndex: Record<string, number> = {}

View file

@ -13,7 +13,7 @@ const SINGLE_REGEX =
*/ */
export function parseTlToEntries( export function parseTlToEntries(
tl: string, tl: string,
params?: { params: {
/** /**
* Whether to throw an error if a line failed to parse * Whether to throw an error if a line failed to parse
*/ */
@ -45,7 +45,12 @@ export function parseTlToEntries(
* If true, the `id` field will be set to 0 for all entries. * If true, the `id` field will be set to 0 for all entries.
*/ */
forIdComputation?: boolean forIdComputation?: boolean
},
/**
* Whether to parse typeModifiers for method return types
*/
parseMethodTypes?: boolean
} = {},
): TlEntry[] { ): TlEntry[] {
const ret: TlEntry[] = [] const ret: TlEntry[] = []
@ -56,13 +61,13 @@ export function parseTlToEntries(
let currentKind: TlEntry['kind'] = 'class' let currentKind: TlEntry['kind'] = 'class'
let currentComment = '' let currentComment = ''
const prefix = params?.prefix ?? '' const prefix = params.prefix ?? ''
lines.forEach((line, idx) => { lines.forEach((line, idx) => {
line = line.trim() line = line.trim()
if (line === '') { if (line === '') {
if (params?.onOrphanComment) { if (params.onOrphanComment) {
params.onOrphanComment(currentComment) params.onOrphanComment(currentComment)
} }
@ -102,9 +107,9 @@ export function parseTlToEntries(
if (!match) { if (!match) {
const err = new Error(`Failed to parse line ${idx + 1}: ${line}`) const err = new Error(`Failed to parse line ${idx + 1}: ${line}`)
if (params?.panicOnError) { if (params.panicOnError) {
throw err throw err
} else if (params?.onError) { } else if (params.onError) {
params.onError(err, line, idx + 1) params.onError(err, line, idx + 1)
} else { } else {
console.warn(err) console.warn(err)
@ -121,7 +126,7 @@ export function parseTlToEntries(
let typeIdNum = typeId ? parseInt(typeId, 16) : 0 let typeIdNum = typeId ? parseInt(typeId, 16) : 0
if (typeIdNum === 0 && !params?.forIdComputation) { if (typeIdNum === 0 && !params.forIdComputation) {
typeIdNum = computeConstructorIdFromString(line) typeIdNum = computeConstructorIdFromString(line)
} }
@ -141,6 +146,15 @@ export function parseTlToEntries(
arguments: [], arguments: [],
} }
if (entry.kind === 'method' && params.parseMethodTypes) {
const [type, modifiers] = parseArgumentType(entry.type)
entry.type = type
if (Object.keys(modifiers).length) {
entry.typeModifiers = modifiers
}
}
if (generics) { if (generics) {
entry.generics = generics.split(',').map((it) => { entry.generics = generics.split(',').map((it) => {
const [name, type] = it.split(':') const [name, type] = it.split(':')
@ -193,14 +207,29 @@ export function parseTlToEntries(
} }
}) })
if (currentComment && params?.onOrphanComment) { if (currentComment && params.onOrphanComment) {
params.onOrphanComment(currentComment) params.onOrphanComment(currentComment)
} }
// post-process: // post-process:
// - add return type ctor id for methods
// - find arguments where type is not a union and put corresponding modifiers // - find arguments where type is not a union and put corresponding modifiers
// - apply prefix // - apply prefix
ret.forEach((entry, entryIdx) => { ret.forEach((entry, entryIdx) => {
if (params.parseMethodTypes && entry.kind === 'method') {
const type = entry.type
if (type in unions && unions[type].length === 1) {
if (!entry.typeModifiers) entry.typeModifiers = {}
entry.typeModifiers.constructorId = unions[type][0].id
} else if (type in entries) {
if (!entry.typeModifiers) entry.typeModifiers = {}
entry.typeModifiers.isBareType = true
entry.typeModifiers.constructorId = entries[type].id
}
}
entry.arguments.forEach((arg) => { entry.arguments.forEach((arg) => {
const type = arg.type const type = arg.type
@ -214,9 +243,9 @@ export function parseTlToEntries(
`Union ${type} has more than one entry, cannot use it like %${type} (found in ${entry.name}#${arg.name})`, `Union ${type} has more than one entry, cannot use it like %${type} (found in ${entry.name}#${arg.name})`,
) )
if (params?.panicOnError) { if (params.panicOnError) {
throw err throw err
} else if (params?.onError) { } else if (params.onError) {
params.onError(err, '', entryIdx) params.onError(err, '', entryIdx)
} else { } else {
console.warn(err) console.warn(err)

View file

@ -27,11 +27,12 @@ export function patchRuntimeTlSchema(
readerMap: TlReaderMap readerMap: TlReaderMap
writerMap: TlWriterMap writerMap: TlWriterMap
} { } {
const entries = parseTlToEntries(schema) const entries = parseTlToEntries(schema, { parseMethodTypes: true })
const readersCode = generateReaderCodeForTlEntries(entries, { const readersCode = generateReaderCodeForTlEntries(entries, {
variableName: '_', variableName: '_',
includeMethods: false, includeMethods: false,
includeMethodResults: true,
}) })
const writersCode = generateWriterCodeForTlEntries(entries, { const writersCode = generateWriterCodeForTlEntries(entries, {
variableName: '_', variableName: '_',
@ -49,10 +50,21 @@ export function patchRuntimeTlSchema(
readerMap: { readerMap: {
...readers, ...readers,
...newReaders, ...newReaders,
_results: {
...readers._results,
...newReaders._results,
},
}, },
// ts is not smart enough
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
writerMap: { writerMap: {
...writers, ...writers,
...newWriters, ...newWriters,
_bare: {
...writers._bare,
...newWriters._bare,
},
}, },
} }
} }

View file

@ -62,7 +62,10 @@ export function writeTlEntryToString(
if (forIdComputation) { if (forIdComputation) {
str += '= ' + normalizeType(entry.type) str += '= ' + normalizeType(entry.type)
} else { } else {
str += '= ' + entry.type + ';' const type = entry.typeModifiers ?
stringifyArgumentType(entry.type, entry.typeModifiers) :
entry.type
str += '= ' + type + ';'
} }
return str return str

View file

@ -1,7 +1,7 @@
/** /**
* Modifiers for {@link TlArgument.type} * Modifiers for {@link TlArgument.type}
*/ */
export interface TlArgumentModifiers { export interface TlTypeModifiers {
/** /**
* Predicate of the argument * Predicate of the argument
* @example `flags.3` * @example `flags.3`
@ -74,7 +74,7 @@ export interface TlArgument {
/** /**
* Modifiers for {@link type} * Modifiers for {@link type}
*/ */
typeModifiers?: TlArgumentModifiers typeModifiers?: TlTypeModifiers
/** /**
* Comment of the argument * Comment of the argument
@ -121,6 +121,11 @@ export interface TlEntry {
*/ */
type: string type: string
/**
* For methods (where {@link type} is the return type), modifiers for {@link type}
*/
typeModifiers?: TlTypeModifiers
/** /**
* Comment of the entry * Comment of the entry
*/ */

View file

@ -1,4 +1,4 @@
import { TlArgumentModifiers, TlEntry } from './types' import { TlEntry, TlTypeModifiers } from './types'
/** /**
* Split qualified TL entry name into namespace and name * Split qualified TL entry name into namespace and name
@ -63,7 +63,7 @@ export function groupTlEntriesByNamespace(
export function stringifyArgumentType( export function stringifyArgumentType(
type: string, type: string,
modifiers?: TlArgumentModifiers, modifiers?: TlTypeModifiers,
) { ) {
if (!modifiers) return type if (!modifiers) return type
let ret = type let ret = type
@ -76,8 +76,8 @@ export function stringifyArgumentType(
return ret return ret
} }
export function parseArgumentType(type: string): [string, TlArgumentModifiers] { export function parseArgumentType(type: string): [string, TlTypeModifiers] {
const modifiers: TlArgumentModifiers = {} const modifiers: TlTypeModifiers = {}
const [predicate, type_] = type.split('?') const [predicate, type_] = type.split('?')
if (type_) { if (type_) {

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,5 @@
declare const __tlReaderMap: Record<number, (r: unknown) => unknown> declare const __tlReaderMap: Record<number, (r: unknown) => unknown> & {
_results: Record<string, (r: unknown) => unknown>
}
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default __tlReaderMap export default __tlReaderMap

View file

@ -1,3 +1,5 @@
declare const __tlWriterMap: Record<string, (w: unknown, val: unknown) => void> declare const __tlWriterMap: Record<string, (w: unknown, val: unknown) => void> & {
_bare: Record<number, (r: unknown) => unknown>
}
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default __tlWriterMap export default __tlWriterMap

View file

@ -80,7 +80,6 @@
"phoneCallAccepted": ["admin_id", "participant_id"], "phoneCallAccepted": ["admin_id", "participant_id"],
"phoneCallRequested": ["admin_id", "participant_id"], "phoneCallRequested": ["admin_id", "participant_id"],
"phoneCallWaiting": ["admin_id", "participant_id"], "phoneCallWaiting": ["admin_id", "participant_id"],
"pollResults": ["recent_voters"],
"privacyValueAllowChatParticipants": ["chats"], "privacyValueAllowChatParticipants": ["chats"],
"privacyValueAllowUsers": ["users"], "privacyValueAllowUsers": ["users"],
"privacyValueDisallowChatParticipants": ["chats"], "privacyValueDisallowChatParticipants": ["chats"],
@ -123,7 +122,6 @@
"updateDeleteChannelMessages": ["channel_id"], "updateDeleteChannelMessages": ["channel_id"],
"updateGroupCall": ["chat_id"], "updateGroupCall": ["chat_id"],
"updateInlineBotCallbackQuery": ["user_id"], "updateInlineBotCallbackQuery": ["user_id"],
"updateMessagePollVote": ["user_id"],
"updatePinnedChannelMessages": ["channel_id"], "updatePinnedChannelMessages": ["channel_id"],
"updateReadChannelDiscussionInbox": ["channel_id", "broadcast_id"], "updateReadChannelDiscussionInbox": ["channel_id", "broadcast_id"],
"updateReadChannelDiscussionOutbox": ["channel_id"], "updateReadChannelDiscussionOutbox": ["channel_id"],
@ -139,7 +137,6 @@
"updateUserPhoto": ["user_id"], "updateUserPhoto": ["user_id"],
"updateUserStatus": ["user_id"], "updateUserStatus": ["user_id"],
"updateUserTyping": ["user_id"], "updateUserTyping": ["user_id"],
"updateWebViewResultSent": ["bot_id"],
"user": ["id"], "user": ["id"],
"userEmpty": ["id"], "userEmpty": ["id"],
"userFull": ["id"], "userFull": ["id"],

File diff suppressed because one or more lines are too long

View file

@ -45,7 +45,11 @@ const README_MD_FILE = join(__dirname, '../README.md')
const PACKAGE_JSON_FILE = join(__dirname, '../package.json') const PACKAGE_JSON_FILE = join(__dirname, '../package.json')
function tlToFullSchema(tl: string): TlFullSchema { function tlToFullSchema(tl: string): TlFullSchema {
return parseFullTlSchema(parseTlToEntries(tl)) return parseFullTlSchema(
parseTlToEntries(tl, {
parseMethodTypes: true,
}),
)
} }
interface Schema { interface Schema {

View file

@ -34,21 +34,10 @@ async function main() {
'mt_message', 'mt_message',
'mt_msg_copy', 'mt_msg_copy',
'mt_gzip_packed', 'mt_gzip_packed',
'mt_rpc_result',
].indexOf(it.name) === -1, ].indexOf(it.name) === -1,
) )
const rpcResult = entries.find((it) => it.name === 'mt_rpc_result')
if (!rpcResult) {
throw new Error('mt_rpc_result not found')
}
rpcResult.arguments.forEach((arg) => {
if (arg.name === 'result') {
arg.type = 'any'
}
})
// mtproto is handled internally, for simplicity we make them all classes // mtproto is handled internally, for simplicity we make them all classes
entries.forEach((entry) => { entries.forEach((entry) => {
entry.kind = 'class' entry.kind = 'class'

View file

@ -59,6 +59,7 @@ async function generateReaders(
let code = generateReaderCodeForTlEntries(apiSchema.entries, { let code = generateReaderCodeForTlEntries(apiSchema.entries, {
variableName: 'm', variableName: 'm',
includeMethods: false, includeMethods: false,
includeMethodResults: true,
}) })
const mtpCode = generateReaderCodeForTlEntries(mtpSchema.entries, { const mtpCode = generateReaderCodeForTlEntries(mtpSchema.entries, {