/** * @fileoverview Require component props to be typed as read-only. * @author Luke Zapart */ 'use strict'; const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); function isFlowPropertyType(node) { return node.type === 'ObjectTypeProperty'; } function isCovariant(node) { return node.variance && node.variance.kind === 'plus'; } // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: 'Require read-only props.', category: 'Stylistic Issues', recommended: false, url: docsUrl('prefer-read-only-props') }, fixable: 'code', schema: [] }, create: Components.detect((context, components) => ({ 'Program:exit': function () { const list = components.list(); Object.keys(list).forEach((key) => { const component = list[key]; if (!component.declaredPropTypes) { return; } Object.keys(component.declaredPropTypes).forEach((propName) => { const prop = component.declaredPropTypes[propName]; if (!isFlowPropertyType(prop.node)) { return; } if (!isCovariant(prop.node)) { context.report({ node: prop.node, message: 'Prop \'{{propName}}\' should be read-only.', data: { propName }, fix: (fixer) => { if (!prop.node.variance) { // Insert covariance return fixer.insertTextBefore(prop.node, '+'); } // Replace contravariance with covariance return fixer.replaceText(prop.node.variance, '+'); } }); } }); }); } })) };