@@ -10,7 +10,6 @@ const docsUrl = require('../util/docsUrl');
10
10
// Constants
11
11
// ------------------------------------------------------------------------------
12
12
13
-
14
13
// ------------------------------------------------------------------------------
15
14
// Rule Definition
16
15
// ------------------------------------------------------------------------------
@@ -22,10 +21,25 @@ module.exports = {
22
21
category : 'Best Practices' ,
23
22
recommended : false ,
24
23
url : docsUrl ( 'forbid-foreign-prop-types' )
25
- }
24
+ } ,
25
+
26
+ schema : [
27
+ {
28
+ type : 'object' ,
29
+ properties : {
30
+ allowInPropTypes : {
31
+ type : 'boolean'
32
+ }
33
+ } ,
34
+ additionalProperties : false
35
+ }
36
+ ]
26
37
} ,
27
38
28
39
create : function ( context ) {
40
+ const config = context . options [ 0 ] || { } ;
41
+ const allowInPropTypes = config . allowInPropTypes || false ;
42
+
29
43
// --------------------------------------------------------------------------
30
44
// Helpers
31
45
// --------------------------------------------------------------------------
@@ -34,15 +48,53 @@ module.exports = {
34
48
return node . parent . type === 'AssignmentExpression' && node . parent . left === node ;
35
49
}
36
50
51
+ function findParentAssignmentExpression ( node ) {
52
+ let parent = node . parent ;
53
+
54
+ while ( parent && parent . type !== 'Program' ) {
55
+ if ( parent . type === 'AssignmentExpression' ) {
56
+ return parent ;
57
+ }
58
+ parent = parent . parent ;
59
+ }
60
+ return null ;
61
+ }
62
+
63
+ function isAllowedAssignment ( node ) {
64
+ if ( ! allowInPropTypes ) {
65
+ return false ;
66
+ }
67
+
68
+ const assignmentExpression = findParentAssignmentExpression ( node ) ;
69
+
70
+ if ( assignmentExpression &&
71
+ assignmentExpression . left &&
72
+ assignmentExpression . left . property &&
73
+ assignmentExpression . left . property . name === 'propTypes'
74
+ ) {
75
+ return true ;
76
+ }
77
+ return false ;
78
+ }
79
+
37
80
return {
38
81
MemberExpression : function ( node ) {
39
- if ( ! node . computed && node . property && node . property . type === 'Identifier' &&
40
- node . property . name === 'propTypes' && ! isLeftSideOfAssignment ( node ) ||
41
- node . property && node . property . type === 'Literal' &&
42
- node . property . value === 'propTypes' && ! isLeftSideOfAssignment ( node ) ) {
82
+ if (
83
+ ( ! node . computed &&
84
+ node . property &&
85
+ node . property . type === 'Identifier' &&
86
+ node . property . name === 'propTypes' &&
87
+ ! isLeftSideOfAssignment ( node ) &&
88
+ ! isAllowedAssignment ( node ) ) ||
89
+ ( node . property &&
90
+ node . property . type === 'Literal' &&
91
+ node . property . value === 'propTypes' &&
92
+ ! isLeftSideOfAssignment ( node ) &&
93
+ ! isAllowedAssignment ( node ) )
94
+ ) {
43
95
context . report ( {
44
96
node : node . property ,
45
- message : 'Using another component\'s propTypes is forbidden '
97
+ message : 'Using propTypes from another component is not safe because they may be removed in production builds '
46
98
} ) ;
47
99
}
48
100
} ,
@@ -53,7 +105,7 @@ module.exports = {
53
105
if ( propTypesNode ) {
54
106
context . report ( {
55
107
node : propTypesNode ,
56
- message : 'Using another component\'s propTypes is forbidden '
108
+ message : 'Using propTypes from another component is not safe because they may be removed in production builds '
57
109
} ) ;
58
110
}
59
111
}
0 commit comments