Skip to content

Instantly share code, notes, and snippets.

@rzane
Created November 15, 2017 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rzane/18efdb1ab3629d16f3b4a479d2c9cd75 to your computer and use it in GitHub Desktop.
Save rzane/18efdb1ab3629d16f3b4a479d2c9cd75 to your computer and use it in GitHub Desktop.
An interactive script to declare react props
const fs = require('fs');
const path = require('path');
const { CLIEngine } = require('eslint');
const readline = require('readline-sync');
const cli = new CLIEngine({
parser: 'babel-eslint',
useEslintrc: false,
plugins: ['react'],
rules: { 'react/prop-types': ['error', {}] }
});
const [_node, _script, ...files] = process.argv;
const report = cli.executeOnFiles(files);
const extractName = msg => msg.message.match(/'(.*)' is missing/)[1];
const extractComponent = filePath => path.basename(filePath, '.js');
const cache = {};
const getPropTypes = names => {
const result = names
.filter(name => !name.includes('.'))
.reduce((acc, name) => {
if (name === 'children') {
acc[name] = 'PropTypes.node';
} else if (name in cache) {
acc[name] = cache[name];
} else {
const answer = readline.question(`${name}? `);
cache[name] = answer;
acc[name] = answer;
}
return acc;
}, {});
return JSON.stringify(result, null, 2)
.replace(/"/g, '')
.replace(':', ': ');
};
report.results.forEach(({ filePath, messages }) => {
if (!messages.length) {
return;
}
console.log(filePath);
const component = extractComponent(filePath);
const names = messages.map(extractName);
const propTypes = getPropTypes(names);
const line = `\n${component}.propTypes = ${propTypes};`;
console.log('Writing!');
fs.appendFileSync(filePath, line);
console.log();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment