homebridge-prometheus-exporter/code-generation/config-scheme-gen.js

100 lines
2.5 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
const { parseSchema } = require('json-schema-to-zod')
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, false)
const code = format(
`
// Auto-generated by "${join(basename(__dirname), basename(__filename))}", dont 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}`)