1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | const docsUrl = require('../util/docsUrl');
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | const DEFAULTS = ['className', 'style'];
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | module.exports = {
|
21 | meta: {
|
22 | docs: {
|
23 | description: 'Forbid certain props on components',
|
24 | category: 'Best Practices',
|
25 | recommended: false,
|
26 | url: docsUrl('forbid-component-props')
|
27 | },
|
28 |
|
29 | schema: [{
|
30 | type: 'object',
|
31 | properties: {
|
32 | forbid: {
|
33 | type: 'array',
|
34 | items: {
|
35 | oneOf: [{
|
36 | type: 'string'
|
37 | }, {
|
38 | type: 'object',
|
39 | properties: {
|
40 | propName: {
|
41 | type: 'string'
|
42 | },
|
43 | allowedFor: {
|
44 | type: 'array',
|
45 | uniqueItems: true,
|
46 | items: {
|
47 | type: 'string'
|
48 | }
|
49 | },
|
50 | message: {
|
51 | type: 'string'
|
52 | }
|
53 | }
|
54 | }]
|
55 | }
|
56 | }
|
57 | }
|
58 | }]
|
59 | },
|
60 |
|
61 | create(context) {
|
62 | const configuration = context.options[0] || {};
|
63 | const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
|
64 | const propName = typeof value === 'string' ? value : value.propName;
|
65 | const options = {
|
66 | allowList: typeof value === 'string' ? [] : (value.allowedFor || []),
|
67 | message: typeof value === 'string' ? null : value.message
|
68 | };
|
69 | return [propName, options];
|
70 | }));
|
71 |
|
72 | function isForbidden(prop, tagName) {
|
73 | const options = forbid.get(prop);
|
74 | const allowList = options ? options.allowList : undefined;
|
75 |
|
76 | return typeof allowList !== 'undefined' && (typeof tagName === 'undefined' || allowList.indexOf(tagName) === -1);
|
77 | }
|
78 |
|
79 | return {
|
80 | JSXAttribute(node) {
|
81 | const tag = node.parent.name.name;
|
82 | if (tag && tag[0] !== tag[0].toUpperCase()) {
|
83 |
|
84 | return;
|
85 | }
|
86 |
|
87 | const prop = node.name.name;
|
88 |
|
89 | if (!isForbidden(prop, tag)) {
|
90 | return;
|
91 | }
|
92 |
|
93 | const customMessage = forbid.get(prop).message;
|
94 | const errorMessage = customMessage || `Prop \`${prop}\` is forbidden on Components`;
|
95 |
|
96 | context.report({
|
97 | node,
|
98 | message: errorMessage
|
99 | });
|
100 | }
|
101 | };
|
102 | }
|
103 | };
|