generate-config-doc.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. const fs = require('fs')
  2. const path = require('path')
  3. const schema = JSON.parse(fs.readFileSync('tooling/cli.rs/schema.json').toString())
  4. const templatePath = path.join(__dirname, '../../docs/.templates/config.md')
  5. const targetPath = path.join(__dirname, '../../docs/api/config.md')
  6. const template = fs.readFileSync(templatePath, 'utf8')
  7. function formatDescription(description) {
  8. return description ?
  9. description
  10. .replace(/`/g, '\\`')
  11. .replace(/\n/g, ' ')
  12. .replace(/ /g, ' ')
  13. .replace(/{/g, '\\{')
  14. .replace(/}/g, '\\}') :
  15. ''
  16. }
  17. function generatePropertiesEl(schema, anchorRoot, definition, tab) {
  18. const previousTabLevel = tab.replace(' ', '')
  19. const fields = [`anchorRoot="${anchorRoot}"`]
  20. if (definition.additionalProperties) {
  21. fields.push(`type="${definition.type}"`)
  22. fields.push(`description="${formatDescription(definition.description)}"`)
  23. }
  24. const rows = []
  25. for (const propertyName in definition.properties) {
  26. const property = definition.properties[propertyName]
  27. if ('type' in property) {
  28. let type
  29. if ('items' in property) {
  30. if (property.items.type) {
  31. type = `${property.items.type}[]`
  32. } else {
  33. const typeName = property.items.$ref.replace('#/definitions/', '')
  34. const propDefinition = schema.definitions[typeName]
  35. const propertyEl = generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `)
  36. rows.push({
  37. property: propertyName,
  38. optional: ('default' in property) || property.type.includes('null'),
  39. type: `${typeName}[]`,
  40. description: property.description,
  41. child: `<Array type="${typeName}">\n${tab}${propertyEl}\n${previousTabLevel}</Array>`
  42. })
  43. continue
  44. }
  45. } else if (Array.isArray(property.type)) {
  46. type = property.type.join(' | ')
  47. } else {
  48. type = property.type
  49. }
  50. rows.push({
  51. property: propertyName,
  52. optional: true,
  53. type,
  54. description: property.description,
  55. default: property.default
  56. })
  57. } else if ('anyOf' in property) {
  58. const subType = property.anyOf[0].$ref.replace('#/definitions/', '')
  59. const propDefinition = schema.definitions[subType]
  60. const propertyEl = generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `)
  61. rows.push({
  62. property: propertyName,
  63. optional: property.anyOf.length > 1 && property.anyOf[1].type === 'null',
  64. type: subType,
  65. description: property.description,
  66. child: propertyEl
  67. })
  68. } else if ('allOf' in property) {
  69. const subType = property.allOf[0].$ref.replace('#/definitions/', '')
  70. const propDefinition = schema.definitions[subType]
  71. const propertyEl = propDefinition.properties ? generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `) : undefined
  72. rows.push({
  73. property: propertyName,
  74. optional: 'default' in property,
  75. type: property.type || subType,
  76. description: property.description,
  77. child: propertyEl
  78. })
  79. }
  80. }
  81. if (rows.length > 0) {
  82. const serializedRows = rows
  83. .map(row => {
  84. const fields = [`property: "${row.property}"`, `optional: ${row.optional}`, `type: "${row.type}"`, `description: \`${formatDescription(row.description)}\``]
  85. if (row.child) {
  86. fields.push(`child: ${row.child}`)
  87. }
  88. return `{ ${fields.join(', ')} },`
  89. })
  90. .join(`\n${tab}`)
  91. fields.push(`rows={[\n${tab}${serializedRows}\n${previousTabLevel}]}`)
  92. } else {
  93. fields.push('rows={[]}')
  94. }
  95. return `<Properties ${fields.join(' ')}/>`
  96. }
  97. const output = []
  98. for (const propertyName in schema.properties) {
  99. const property = schema.properties[propertyName]
  100. const definitionName = property.allOf[0].$ref.replace('#/definitions/', '')
  101. const definition = schema.definitions[definitionName]
  102. let contents = `## \`${propertyName}\`\n\n${generatePropertiesEl(schema, propertyName, definition, ' ')}`
  103. output.push(contents)
  104. }
  105. fs.writeFileSync(targetPath, template.replace('{properties}', output.join('\n\n')))