6f7686ba34
Auto-generate the documentation of the configuration options in `README.md` from `config.schema.json`.
99 lines
2.6 KiB
JavaScript
Executable file
99 lines
2.6 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
||
|
||
const { parseSchema } = require('json-schema-to-zod-with-defaults')
|
||
const { schema } = require('../config.schema.json')
|
||
const { format } = require('prettier')
|
||
const { join, basename } = require('path')
|
||
const prettierConfig = require('../prettier.config')
|
||
const { writeFileSync, readFileSync } = require('fs')
|
||
|
||
const file = join(__dirname, '../src/generated/config_boundary.ts')
|
||
|
||
console.log(`Starting code generation for ${file}`)
|
||
|
||
const zodSchema = parseSchema(schema, true)
|
||
|
||
const code = format(
|
||
`
|
||
// Auto-generated by "${join(basename(__dirname), basename(__filename))}", don’t manually edit
|
||
|
||
import { z } from 'zod'
|
||
|
||
export const ConfigBoundary = ${zodSchema}
|
||
`,
|
||
{ filepath: 'codegen.ts', ...prettierConfig },
|
||
)
|
||
|
||
writeFileSync(file, code)
|
||
|
||
const note = 'AUTOGENERATED CONFIG DOCS'
|
||
const comment = (...strings) => `<!-- ${strings.join(' ')} -->`
|
||
const readmePath = join(__dirname, '../README.md')
|
||
const readme = readFileSync(readmePath).toString()
|
||
const regex = new RegExp(`${comment(note, 'BEGIN')}.*${comment(note, 'END')}`, 'mgs')
|
||
if (!readme.match(regex)) {
|
||
console.log('Could not update README.md')
|
||
process.exit(1)
|
||
}
|
||
|
||
writeFileSync(
|
||
readmePath,
|
||
readme.replace(
|
||
regex,
|
||
`${comment(note, 'BEGIN')}\n\`\`\`json5\n${generateDocs(schema)}\n\`\`\`\n${comment(note, 'END')}`,
|
||
),
|
||
)
|
||
|
||
function generateDocs(schema) {
|
||
const doc = indent(
|
||
Object.entries(schema.properties)
|
||
.map(([property, definition]) => {
|
||
const lines = []
|
||
|
||
if (definition.title) {
|
||
lines.push(`// ${definition.title}`)
|
||
}
|
||
if (definition.description) {
|
||
lines.push(`//\n// ${wordwrap(definition.description, 80, '\n// ')}`)
|
||
}
|
||
|
||
lines.push(`${JSON.stringify(property)}: ${JSON.stringify('<' + definition.type + '>')}`)
|
||
|
||
return lines.join('\n')
|
||
})
|
||
.join(',\n\n\n'),
|
||
6,
|
||
)
|
||
|
||
return `{
|
||
// ...
|
||
"platforms": [
|
||
{
|
||
"platform": "PrometheusExporter",
|
||
|
||
|
||
${doc}
|
||
}
|
||
]
|
||
}`
|
||
}
|
||
|
||
function wordwrap(word, length, wrap = '\n') {
|
||
const wrapped = []
|
||
while (word.length > length) {
|
||
const cut = word.substring(0, length)
|
||
const pos = cut.lastIndexOf(' ')
|
||
wrapped.push(cut.substring(0, pos))
|
||
word = word.substring(pos + 1)
|
||
}
|
||
|
||
wrapped.push(word)
|
||
|
||
return wrapped.join(wrap)
|
||
}
|
||
|
||
function indent(string, indent) {
|
||
return string.replace(/^(.+)$/gm, `${' '.repeat(indent)}$1`)
|
||
}
|
||
|
||
console.log(`Finished code generation for ${file}`)
|