Created
January 23, 2021 21:15
-
-
Save lierdakil/696ee408dbf27e2346765a5441787687 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ts-node | |
const path = require('path') | |
const fs = require('fs') | |
if (!process.argv[2]) { | |
process.stderr.write(`Usage: ${process.argv[1]} <filename>\n`) | |
return -1 | |
} | |
const filePath = path.join(process.cwd(), process.argv[2]) | |
let outfile | |
let config | |
const packageJson = require(path.join(process.cwd(), 'package.json')) | |
if (packageJson.configSchema) { | |
config = packageJson.configSchema | |
outfile = "export {}" | |
} else { | |
config = require(filePath).config | |
outfile = fs.readFileSync(filePath) | |
} | |
const pn = packageJson.name | |
const output = { | |
buffer: [], | |
write: function(str) { | |
output.buffer.push(str) | |
} | |
} | |
const indentOne = ' ' | |
output.write(` | |
// generated by typed-config.js | |
declare module 'atom' { | |
interface ConfigValues { | |
`) | |
function writeFlat(pn, config, indentLevel) { | |
const indent = indentOne.repeat(indentLevel) | |
for (const k of Object.keys(config)) { | |
if (config[k].type === 'object') { | |
writeFlat(`${pn}.${k}`, config[k].properties, indentLevel) | |
writeDeep(`${pn}.${k}`, config[k].properties, indentLevel) | |
} else { | |
output.write(`${indent}'${pn}.${k}': ${getType(config[k])}\n`) | |
} | |
} | |
} | |
writeFlat(pn, config, 2) | |
function writeDeep(pn, config, indentLevel) { | |
const indent = indentOne.repeat(indentLevel) | |
const indent2 = indentOne.repeat(indentLevel + 1) | |
output.write(`${indent}'${pn}': {\n`) | |
for (const k of Object.keys(config)) { | |
if (config[k].type === 'object') { | |
writeFlat(k, config[k].properties, indentLevel + 1) | |
writeDeep(k, config[k].properties, indentLevel + 1) | |
} else { | |
output.write(`${indent2}${needQuote(k)}: ${getType(config[k])}\n`) | |
} | |
} | |
output.write(`${indent}}\n`) | |
} | |
writeDeep(pn, config, 2) | |
function needQuote(str) { | |
if (str.match(/^[A-Za-z]\w+$/)) return str | |
else return `'${str}'` | |
} | |
function getType(t, useDefaultRule = true) { | |
let type | |
if (t.enum) { | |
const vals = [] | |
for (const v of t.enum) { | |
if (v.value !== undefined) { | |
vals.push(v.value) | |
} else { | |
vals.push(v) | |
} | |
} | |
type = vals | |
.map(x => { | |
if (typeof x === 'string') return `'${x}'` | |
else if (typeof x.value === 'string') return `'${x.value}'` | |
else if (x.value) return x.value | |
else return x | |
}) | |
.join(' | ') | |
return type | |
} | |
switch (t.type) { | |
case 'string': | |
type = 'string' | |
break | |
case 'integer': | |
type = 'number' | |
break | |
case 'number': | |
type = 'number' | |
break | |
case 'boolean': | |
type = 'boolean' | |
break | |
case 'array': | |
if (t.items) { | |
const rt = getType(t.items, false) | |
if (rt.includes(' ')) type = `Array<${rt}>` | |
else type = `${rt}[]` | |
} else { | |
type = 'any[]' | |
} | |
break | |
case 'color': | |
type = 'string' | |
break | |
case 'object': | |
type = 'object' | |
break | |
} | |
if (!type) throw new Error(`Unknown occured: ${JSON.stringify(t)}`) | |
if (useDefaultRule && t.default === undefined) type += ' | undefined' | |
return type | |
} | |
output.write(`\ | |
} | |
} | |
`) | |
let result = output.buffer.join('') | |
result = outfile.toString().replace(/(:?\n\/\/ generated by typed-config\.js[^]*)?$/, result) | |
fs.writeFileSync(filePath, result, {encoding: 'utf8'}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment