1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | 'use strict';
|
8 |
|
9 | const Components = require('../util/Components');
|
10 | const docsUrl = require('../util/docsUrl');
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | module.exports = {
|
17 | meta: {
|
18 | docs: {
|
19 | description: 'Enforce all defaultProps are defined and not "required" in propTypes.',
|
20 | category: 'Best Practices',
|
21 | url: docsUrl('default-props-match-prop-types')
|
22 | },
|
23 |
|
24 | schema: [{
|
25 | type: 'object',
|
26 | properties: {
|
27 | allowRequiredDefaults: {
|
28 | default: false,
|
29 | type: 'boolean'
|
30 | }
|
31 | },
|
32 | additionalProperties: false
|
33 | }]
|
34 | },
|
35 |
|
36 | create: Components.detect((context, components) => {
|
37 | const configuration = context.options[0] || {};
|
38 | const allowRequiredDefaults = configuration.allowRequiredDefaults || false;
|
39 |
|
40 | |
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | function reportInvalidDefaultProps(propTypes, defaultProps) {
|
47 |
|
48 |
|
49 |
|
50 | if (defaultProps === 'unresolved' || !propTypes || Object.keys(propTypes).length === 0) {
|
51 | return;
|
52 | }
|
53 |
|
54 | Object.keys(defaultProps).forEach((defaultPropName) => {
|
55 | const defaultProp = defaultProps[defaultPropName];
|
56 | const prop = propTypes[defaultPropName];
|
57 |
|
58 | if (prop && (allowRequiredDefaults || !prop.isRequired)) {
|
59 | return;
|
60 | }
|
61 |
|
62 | if (prop) {
|
63 | context.report({
|
64 | node: defaultProp.node,
|
65 | message: 'defaultProp "{{name}}" defined for isRequired propType.',
|
66 | data: {name: defaultPropName}
|
67 | });
|
68 | } else {
|
69 | context.report({
|
70 | node: defaultProp.node,
|
71 | message: 'defaultProp "{{name}}" has no corresponding propTypes declaration.',
|
72 | data: {name: defaultPropName}
|
73 | });
|
74 | }
|
75 | });
|
76 | }
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | return {
|
83 | 'Program:exit'() {
|
84 | const list = components.list();
|
85 |
|
86 |
|
87 | Object.keys(list).filter((component) => list[component].defaultProps).forEach((component) => {
|
88 | reportInvalidDefaultProps(
|
89 | list[component].declaredPropTypes,
|
90 | list[component].defaultProps || {}
|
91 | );
|
92 | });
|
93 | }
|
94 | };
|
95 | })
|
96 | };
|