Skip to content

Commit 21c7e1b

Browse files
author
Ell Bradshaw
committed
Add both allowList and disallowList to forbid-*-props
1 parent f56851b commit 21c7e1b

File tree

3 files changed

+57
-23
lines changed

3 files changed

+57
-23
lines changed

lib/rules/forbid-component-props.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
const docsUrl = require('../util/docsUrl');
99
const report = require('../util/report');
10+
const isForbidden = require('../util/isForbidden');
1011

1112
// ------------------------------------------------------------------------------
1213
// Constants
@@ -54,6 +55,13 @@ module.exports = {
5455
type: 'string',
5556
},
5657
},
58+
disallowedFor: {
59+
type: 'array',
60+
uniqueItems: true,
61+
items: {
62+
type: 'string',
63+
},
64+
},
5765
message: {
5866
type: 'string',
5967
},
@@ -68,21 +76,19 @@ module.exports = {
6876
create(context) {
6977
const configuration = context.options[0] || {};
7078
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
79+
if (value.allowedFor && value.disallowedFor) {
80+
throw new Error('Must specify either allowedFor or disallowedFor, not both');
81+
}
82+
7183
const propName = typeof value === 'string' ? value : value.propName;
7284
const options = {
7385
allowList: typeof value === 'string' ? [] : (value.allowedFor || []),
86+
disallowList: typeof value === 'string' ? null : (value.disallowedFor || null),
7487
message: typeof value === 'string' ? null : value.message,
7588
};
7689
return [propName, options];
7790
}));
7891

79-
function isForbidden(prop, tagName) {
80-
const options = forbid.get(prop);
81-
const allowList = options ? options.allowList : undefined;
82-
// if the tagName is undefined (`<this.something>`), we assume it's a forbidden element
83-
return typeof allowList !== 'undefined' && (typeof tagName === 'undefined' || allowList.indexOf(tagName) === -1);
84-
}
85-
8692
return {
8793
JSXAttribute(node) {
8894
const parentName = node.parent.name;
@@ -96,7 +102,7 @@ module.exports = {
96102

97103
const prop = node.name.name;
98104

99-
if (!isForbidden(prop, tag)) {
105+
if (!isForbidden(forbid, prop, tag)) {
100106
return;
101107
}
102108

lib/rules/forbid-dom-props.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
const docsUrl = require('../util/docsUrl');
99
const report = require('../util/report');
10+
const isForbidden = require('../util/isForbidden');
1011

1112
// ------------------------------------------------------------------------------
1213
// Constants
@@ -18,21 +19,6 @@ const DEFAULTS = [];
1819
// Rule Definition
1920
// ------------------------------------------------------------------------------
2021

21-
/**
22-
* @param {Map<string, object>} forbidMap // { disallowList: null | string[], message: null | string }
23-
* @param {string} prop
24-
* @param {string} tagName
25-
* @returns {boolean}
26-
*/
27-
function isForbidden(forbidMap, prop, tagName) {
28-
const options = forbidMap.get(prop);
29-
return options && (
30-
typeof tagName === 'undefined'
31-
|| !options.disallowList
32-
|| options.disallowList.indexOf(tagName) !== -1
33-
);
34-
}
35-
3622
const messages = {
3723
propIsForbidden: 'Prop "{{prop}}" is forbidden on DOM Nodes',
3824
};
@@ -62,6 +48,13 @@ module.exports = {
6248
propName: {
6349
type: 'string',
6450
},
51+
allowedFor: {
52+
type: 'array',
53+
uniqueItems: true,
54+
items: {
55+
type: 'string',
56+
},
57+
},
6558
disallowedFor: {
6659
type: 'array',
6760
uniqueItems: true,
@@ -86,8 +79,13 @@ module.exports = {
8679
create(context) {
8780
const configuration = context.options[0] || {};
8881
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
82+
if (value.allowedFor && value.disallowedFor) {
83+
throw new Error('Must specify either allowedFor or disallowedFor, not both');
84+
}
85+
8986
const propName = typeof value === 'string' ? value : value.propName;
9087
return [propName, {
88+
allowList: typeof value === 'string' ? null : (value.allowedFor || null),
9189
disallowList: typeof value === 'string' ? null : (value.disallowedFor || null),
9290
message: typeof value === 'string' ? null : value.message,
9391
}];

lib/util/isForbidden.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
/**
4+
* @typedef {Object} ForbidOptions
5+
* @property {string[]} [allowList]
6+
* @property {string[]} [disallowList]
7+
* @property {string} [message]
8+
*/
9+
10+
/**
11+
* @param {Map<string, ForbidOptions>} forbidMap
12+
* @param {string} prop
13+
* @param {string} tagName
14+
* @returns {boolean}
15+
*/
16+
function isForbidden(forbidMap, prop, tagName) {
17+
const options = forbidMap.get(prop);
18+
if (!options) { return false; }
19+
20+
if (options.allowList) {
21+
return (typeof tagName === 'undefined') || options.allowList.indexOf(tagName) === -1;
22+
}
23+
if (options.disallowList) {
24+
return (typeof tagName === 'undefined') || options.disallowList.indexOf(tagName) !== -1;
25+
}
26+
27+
return true;
28+
}
29+
30+
module.exports = isForbidden;

0 commit comments

Comments
 (0)