Skip to content

Instantly share code, notes, and snippets.

@Bannerets
Last active June 4, 2022 17:19
Show Gist options
  • Save Bannerets/d0fca87f36de5bae5ffecab4aa4377af to your computer and use it in GitHub Desktop.
Save Bannerets/d0fca87f36de5bae5ffecab4aa4377af to your computer and use it in GitHub Desktop.
generate flow types for tl methods
#!/usr/bin/env node
// @flow
const fs = require('fs')
const jsonfile = process.argv[2]
const json = JSON.parse(fs.readFileSync(jsonfile).toString())
/*::
type Param = { name: string, type: string }
type Method = {
id: string,
method: string,
params: Param[],
type: string
}
*/
const methods/*: Method[]*/ = json.methods
const replaceDots = (str/*: string*/) => str.replace(/\./g, '_')
const convertParamType = (type/*: string*/) => {
let isOptional = false
let isVector = false
const f = jstype => ({
isOptional,
jstype: isVector ? jstype + '[]' : jstype
})
const parsedType = type
.replace(/^flags\.\d+\?/, () => {
isOptional = true
return ''
})
.replace(/^Vector<(.+?)>$/, (_, $1) => {
isVector = true
return $1
})
switch (parsedType) {
case '#': return f('number')
case 'int': return f('number')
case 'double': return f('number')
case 'long': return f('string')
case 'bytes': return f('number[]')
case 'Bool': return f('boolean')
default: return f(replaceDots(parsedType))
}
}
const strs/*: string[] */ = []
const add = s => strs.push(s || '')
add('// @flow')
add()
add('import type {')
const cache/*: Set<string>*/ = new Set()
const addImport = (type) => {
const t = convertParamType(type).jstype.replace('[]', '')
if (cache.has(t) || /string|number|boolean|true|false/.test(t)) return
add(` ${t},`)
cache.add(t)
}
methods.forEach(({ params, type }) => {
addImport(type)
params.forEach(({ type }) => addImport(type))
})
add('} from \'./telegram-types\'')
add()
add('type Invoke = (method: string, options: Object) => Promise<any>')
add()
methods.forEach(({ method: name, params, type }) => {
add(`export const ${replaceDots(name)} = (`)
add(' invoke: Invoke,')
add(' options: {')
params.forEach(({ name, type }) => {
if (name === 'flags') return
const { isOptional, jstype } = convertParamType(type)
add(` ${name}${isOptional ? '?' : ''}: ${jstype},`)
})
add(' }')
add(`): Promise<${convertParamType(type).jstype}> =>`)
add(` invoke('${name}', options)`)
add()
})
const str = strs.join('\n')
console.log(str)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment