forbid-elements.js
2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
* @fileoverview Forbid certain elements
* @author Kenneth Chung
*/
'use strict';
const has = require('has');
const docsUrl = require('../util/docsUrl');
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: 'Forbid certain elements',
category: 'Best Practices',
recommended: false,
url: docsUrl('forbid-elements')
},
schema: [{
type: 'object',
properties: {
forbid: {
type: 'array',
items: {
anyOf: [
{type: 'string'},
{
type: 'object',
properties: {
element: {type: 'string'},
message: {type: 'string'}
},
required: ['element'],
additionalProperties: false
}
]
}
}
},
additionalProperties: false
}]
},
create(context) {
const configuration = context.options[0] || {};
const forbidConfiguration = configuration.forbid || [];
const indexedForbidConfigs = {};
forbidConfiguration.forEach((item) => {
if (typeof item === 'string') {
indexedForbidConfigs[item] = {element: item};
} else {
indexedForbidConfigs[item.element] = item;
}
});
function errorMessageForElement(name) {
const message = `<${name}> is forbidden`;
const additionalMessage = indexedForbidConfigs[name].message;
if (additionalMessage) {
return `${message}, ${additionalMessage}`;
}
return message;
}
function isValidCreateElement(node) {
return node.callee
&& node.callee.type === 'MemberExpression'
&& node.callee.object.name === 'React'
&& node.callee.property.name === 'createElement'
&& node.arguments.length > 0;
}
function reportIfForbidden(element, node) {
if (has(indexedForbidConfigs, element)) {
context.report({
node,
message: errorMessageForElement(element)
});
}
}
return {
JSXOpeningElement(node) {
reportIfForbidden(context.getSourceCode().getText(node.name), node.name);
},
CallExpression(node) {
if (!isValidCreateElement(node)) {
return;
}
const argument = node.arguments[0];
const argType = argument.type;
if (argType === 'Identifier' && /^[A-Z_]/.test(argument.name)) {
reportIfForbidden(argument.name, argument);
} else if (argType === 'Literal' && /^[a-z][^.]*$/.test(argument.value)) {
reportIfForbidden(argument.value, argument);
} else if (argType === 'MemberExpression') {
reportIfForbidden(context.getSourceCode().getText(argument), argument);
}
}
};
}
};