UNPKG

1.94 kBJavaScriptView Raw
1/**
2 * @fileoverview Require component props to be typed as read-only.
3 * @author Luke Zapart
4 */
5
6'use strict';
7
8const Components = require('../util/Components');
9const docsUrl = require('../util/docsUrl');
10
11function isFlowPropertyType(node) {
12 return node.type === 'ObjectTypeProperty';
13}
14
15function isCovariant(node) {
16 return node.variance && node.variance.kind === 'plus';
17}
18
19// ------------------------------------------------------------------------------
20// Rule Definition
21// ------------------------------------------------------------------------------
22
23module.exports = {
24 meta: {
25 docs: {
26 description: 'Require read-only props.',
27 category: 'Stylistic Issues',
28 recommended: false,
29 url: docsUrl('prefer-read-only-props')
30 },
31 fixable: 'code',
32 schema: []
33 },
34
35 create: Components.detect((context, components) => ({
36 'Program:exit'() {
37 const list = components.list();
38
39 Object.keys(list).forEach((key) => {
40 const component = list[key];
41
42 if (!component.declaredPropTypes) {
43 return;
44 }
45
46 Object.keys(component.declaredPropTypes).forEach((propName) => {
47 const prop = component.declaredPropTypes[propName];
48
49 if (!isFlowPropertyType(prop.node)) {
50 return;
51 }
52
53 if (!isCovariant(prop.node)) {
54 context.report({
55 node: prop.node,
56 message: 'Prop \'{{propName}}\' should be read-only.',
57 data: {
58 propName
59 },
60 fix: (fixer) => {
61 if (!prop.node.variance) {
62 // Insert covariance
63 return fixer.insertTextBefore(prop.node, '+');
64 }
65
66 // Replace contravariance with covariance
67 return fixer.replaceText(prop.node.variance, '+');
68 }
69 });
70 }
71 });
72 });
73 }
74 }))
75};