Skip to content

Instantly share code, notes, and snippets.

@Bannerets
Last active April 6, 2018 17:49
Show Gist options
  • Save Bannerets/cc3ff0689869e6777ee18917388003e8 to your computer and use it in GitHub Desktop.
Save Bannerets/cc3ff0689869e6777ee18917388003e8 to your computer and use it in GitHub Desktop.
generate flow types from tl schema (in json)
#!/usr/bin/env node
// @flow
// https://gist.github.com/Bannerets/cc3ff0689869e6777ee18917388003e8
const fs = require('fs')
const jsonfile = process.argv[2]
const json = JSON.parse(fs.readFileSync(jsonfile).toString())
/*::
type Param = { name: string, type: string }
type Constructor = {
id: string,
predicate: string,
params: Param[],
type: string
}
*/
const constructors/*: Constructor[]*/ = json.constructors
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))
}
}
/*::
type Type = { name: string, predicates: string[] }
*/
const predicates/*: string[] */ = []
const types/*: Type[] */ = []
constructors.forEach(({ predicate, params, type }) => {
predicates.push(`export type ${replaceDots(predicate)} = {`)
predicates.push(` _: '${predicate}',`)
params.forEach(({ name, type }) => {
const { isOptional, jstype } = convertParamType(type)
predicates.push(` ${name}${isOptional ? '?' : ''}: ${jstype},`)
})
predicates.push('}\n')
const t = types.find(e => e.name === type)
if (t) {
t.predicates.push(predicate)
} else {
types.push({
name: type,
predicates: [predicate]
})
}
})
const str = predicates.join('\n')
const typesStr = types
.map(({ name, predicates }) => {
const predicatesStr = predicates
.map(replaceDots)
.map(e => ` | ${e}`)
.join('\n')
return `export type ${replaceDots(name)} =\n${predicatesStr}`
})
.join('\n\n')
console.log(str)
console.log('/* ---------------- */')
console.log()
console.log(typesStr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment