const fs = require('fs')
const path = require('path')
const schema = JSON.parse(
fs.readFileSync('tooling/cli.rs/schema.json').toString()
)
const templatePath = path.join(__dirname, '../../docs/.templates/config.md')
const targetPath = path.join(__dirname, '../../docs/api/config.md')
const template = fs.readFileSync(templatePath, 'utf8')
function formatDescription(description) {
return description
? description
.replace(/`/g, '\\`')
.replace(/\n/g, ' ')
.replace(/ /g, ' ')
.replace(/{/g, '\\{')
.replace(/}/g, '\\}')
: ''
}
function generatePropertiesEl(schema, anchorRoot, definition, tab) {
const previousTabLevel = tab.replace(' ', '')
const fields = [`anchorRoot="${anchorRoot}"`]
if (definition.additionalProperties) {
fields.push(`type="${definition.type}"`)
fields.push(`description="${formatDescription(definition.description)}"`)
}
const rows = []
for (const propertyName in definition.properties) {
const property = definition.properties[propertyName]
if ('type' in property) {
let type
if ('items' in property) {
if (property.items.type) {
type = `${property.items.type}[]`
} else {
const typeName = property.items.$ref.replace('#/definitions/', '')
const propDefinition = schema.definitions[typeName]
const propertyEl = generatePropertiesEl(
schema,
`${anchorRoot}.${propertyName}`,
propDefinition,
`${tab} `
)
rows.push({
property: propertyName,
optional: 'default' in property || property.type.includes('null'),
type: `${typeName}[]`,
description: property.description,
child: `\n${tab}${propertyEl}\n${previousTabLevel}`
})
continue
}
} else if (Array.isArray(property.type)) {
type = property.type.join(' | ')
} else {
type = property.type
}
rows.push({
property: propertyName,
optional: true,
type,
description: property.description,
default: property.default
})
} else if ('anyOf' in property) {
const subType = property.anyOf[0].$ref.replace('#/definitions/', '')
const propDefinition = schema.definitions[subType]
const propertyEl = generatePropertiesEl(
schema,
`${anchorRoot}.${propertyName}`,
propDefinition,
`${tab} `
)
rows.push({
property: propertyName,
optional:
property.anyOf.length > 1 && property.anyOf[1].type === 'null',
type: subType,
description: property.description,
child: propertyEl
})
} else if ('allOf' in property) {
const subType = property.allOf[0].$ref.replace('#/definitions/', '')
const propDefinition = schema.definitions[subType]
const propertyEl = propDefinition.properties
? generatePropertiesEl(
schema,
`${anchorRoot}.${propertyName}`,
propDefinition,
`${tab} `
)
: undefined
rows.push({
property: propertyName,
optional: 'default' in property,
type: property.type || subType,
description: property.description,
child: propertyEl
})
}
}
if (rows.length > 0) {
const serializedRows = rows
.map((row) => {
const fields = [
`property: "${row.property}"`,
`optional: ${row.optional}`,
`type: "${row.type}"`,
`description: \`${formatDescription(row.description)}\``
]
if (row.child) {
fields.push(`child: ${row.child}`)
}
return `{ ${fields.join(', ')} },`
})
.join(`\n${tab}`)
fields.push(`rows={[\n${tab}${serializedRows}\n${previousTabLevel}]}`)
} else {
fields.push('rows={[]}')
}
return ``
}
const output = []
for (const propertyName in schema.properties) {
const property = schema.properties[propertyName]
const definitionName = property.allOf[0].$ref.replace('#/definitions/', '')
const definition = schema.definitions[definitionName]
let contents = `## \`${propertyName}\`\n\n${generatePropertiesEl(
schema,
propertyName,
definition,
' '
)}`
output.push(contents)
}
fs.writeFileSync(
targetPath,
template.replace('{properties}', output.join('\n\n'))
)