164 lines
4.8 KiB
JavaScript
164 lines
4.8 KiB
JavaScript
// since this logic is quite big, i decided to
|
|
// implement it in a separate file
|
|
//
|
|
// this basically takes descriptions.yaml and applies
|
|
// it to the resulting JSON.
|
|
|
|
async function applyDescriptionsFile(input, yaml) {
|
|
const { objects: byObjects, arguments: byArguments, regex: byRegex } = yaml
|
|
|
|
// util function to handle text and objects with text for overrides
|
|
function applyOverwrite(where, what) {
|
|
let text = what
|
|
let overwrite = false
|
|
if (typeof what === 'object') {
|
|
if (!what.text) throw new Error('Invalid overwrite object')
|
|
text = what.text
|
|
overwrite = what.overwrite
|
|
}
|
|
|
|
if (!where.description || overwrite) {
|
|
where.description = text
|
|
}
|
|
}
|
|
|
|
// first create an index of all classes, methods and unions
|
|
const index = {}
|
|
|
|
function indexNs(ns, prefix = '') {
|
|
Object.entries(ns).forEach(([name, content]) => {
|
|
const pref = prefix + (name === '$root' ? '' : `${name}.`)
|
|
|
|
content.classes.forEach(
|
|
(obj) => (index['o_' + pref + obj.name] = obj)
|
|
)
|
|
content.methods.forEach(
|
|
(obj) => (index['o_' + pref + obj.name] = obj)
|
|
)
|
|
content.unions.forEach(
|
|
(obj) => (index['u_' + pref + obj.type] = obj)
|
|
)
|
|
})
|
|
}
|
|
|
|
indexNs(input.mtproto, 'mt_')
|
|
indexNs(input.api)
|
|
|
|
// process byObject
|
|
Object.entries(byObjects).forEach(([name, content]) => {
|
|
if (!(name in index)) {
|
|
return
|
|
}
|
|
|
|
const obj = index[name]
|
|
|
|
if (content.desc) applyOverwrite(obj, content.desc)
|
|
if (content.arguments)
|
|
Object.entries(content.arguments).forEach(([arg, repl]) => {
|
|
const argObj = (obj.arguments || []).find(
|
|
(it) => it.name === arg
|
|
)
|
|
if (!argObj) return
|
|
|
|
applyOverwrite(argObj, repl)
|
|
})
|
|
})
|
|
|
|
// process byArguments
|
|
// first create index based on `name`
|
|
const byArgumentsIndex = {}
|
|
byArguments.forEach((rule) => {
|
|
let name = rule.name
|
|
if (!Array.isArray(name)) name = [name]
|
|
|
|
name.forEach((n) => {
|
|
if (!(n in byArgumentsIndex)) byArgumentsIndex[n] = []
|
|
byArgumentsIndex[n].push(rule)
|
|
})
|
|
})
|
|
|
|
// now find all objects with these arguments and patch
|
|
Object.entries(index).forEach(([key, obj]) => {
|
|
if (!obj.arguments) return // unions
|
|
|
|
args: for (const arg of obj.arguments) {
|
|
if (!(arg.name in byArgumentsIndex)) continue
|
|
|
|
const rules = byArgumentsIndex[arg.name]
|
|
for (const rule of rules) {
|
|
if (rule.filters) {
|
|
for (const filter of rule.filters) {
|
|
if (filter.objType && filter.objType[0] !== key[0])
|
|
break args
|
|
if (
|
|
filter.type &&
|
|
!filter.type.split(' | ').includes(arg.type)
|
|
)
|
|
break args
|
|
|
|
// noinspection EqualityComparisonWithCoercionJS
|
|
if (filter.optional && arg.optional != filter.optional)
|
|
break args
|
|
}
|
|
}
|
|
|
|
applyOverwrite(arg, rule.desc)
|
|
}
|
|
}
|
|
})
|
|
|
|
// process byRegex
|
|
function replaceRegex(obj, regex) {
|
|
if (!obj.description) return
|
|
if (!regex._cached) {
|
|
let flags = regex.flags || ''
|
|
if (flags.indexOf('g') === -1) flags += 'g'
|
|
|
|
regex._cached = new RegExp(regex.regex, flags)
|
|
}
|
|
obj.description = obj.description.replace(regex._cached, regex.repl)
|
|
}
|
|
|
|
Object.values(index).forEach((obj) => {
|
|
for (const regex of byRegex) {
|
|
replaceRegex(obj, regex)
|
|
|
|
if (obj.arguments)
|
|
obj.arguments.forEach((arg) => replaceRegex(arg, regex))
|
|
}
|
|
})
|
|
|
|
return input
|
|
}
|
|
|
|
module.exports = {
|
|
applyDescriptionsFile,
|
|
}
|
|
|
|
if (require.main === module) {
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const yaml = require('js-yaml')
|
|
|
|
applyDescriptionsFile(
|
|
JSON.parse(
|
|
fs.readFileSync(path.join(__dirname, '../raw-schema.json'), 'utf-8')
|
|
),
|
|
yaml.load(
|
|
fs.readFileSync(
|
|
path.join(__dirname, '../descriptions.yaml'),
|
|
'utf-8'
|
|
)
|
|
)
|
|
)
|
|
.then((res) =>
|
|
fs.writeFileSync(
|
|
path.join(__dirname, '../raw-schema.json'),
|
|
JSON.stringify(res)
|
|
)
|
|
)
|
|
.catch((err) => {
|
|
console.error(err)
|
|
process.exit(1)
|
|
})
|
|
}
|