Skip to content

Commit 72fb7a7

Browse files
committed
Adjsut schema
1 parent a2306e7 commit 72fb7a7

File tree

2 files changed

+72
-31
lines changed

2 files changed

+72
-31
lines changed

docs/rules/jsx-no-literals.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ The supported options are:
3434
- `allowedStrings` - An array of unique string values that would otherwise warn, but will be ignored.
3535
- `ignoreProps` (default: `false`) - When `true` the rule ignores literals used in props, wrapped or unwrapped.
3636
- `noAttributeStrings` (default: `false`) - Enforces no string literals used in attributes when set to `true`.
37+
- `elementOverrides` - An object where the keys are the element names and the values are objects with the same options as above. This allows you to specify different options for different elements.
3738

3839
To use, you can specify as follows:
3940

lib/rules/jsx-no-literals.js

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,28 @@ const messages = {
2525
invalidPropValue: 'Invalid prop value: "{{text}}"',
2626
noStringsInAttributes: 'Strings not allowed in attributes: "{{text}}"',
2727
noStringsInJSX: 'Strings not allowed in JSX files: "{{text}}"',
28-
literalNotInJSXExpression: 'Missing JSX expression container around literal string: "{{text}}"',
28+
literalNotInJSXExpression:
29+
'Missing JSX expression container around literal string: "{{text}}"',
30+
};
31+
32+
/** @type {import('json-schema').JSONSchema4['properties']} */
33+
const elementSchemaProperties = {
34+
noStrings: {
35+
type: 'boolean',
36+
},
37+
allowedStrings: {
38+
type: 'array',
39+
uniqueItems: true,
40+
items: {
41+
type: 'string',
42+
},
43+
},
44+
ignoreProps: {
45+
type: 'boolean',
46+
},
47+
noAttributeStrings: {
48+
type: 'boolean',
49+
},
2950
};
3051

3152
/** @type {import('eslint').Rule.RuleModule} */
@@ -40,28 +61,21 @@ module.exports = {
4061

4162
messages,
4263

43-
schema: [{
44-
type: 'object',
45-
properties: {
46-
noStrings: {
47-
type: 'boolean',
48-
},
49-
allowedStrings: {
50-
type: 'array',
51-
uniqueItems: true,
52-
items: {
53-
type: 'string',
64+
schema: [
65+
{
66+
type: 'object',
67+
properties: Object.assign(
68+
{
69+
elementOverrides: {
70+
type: 'object',
71+
properties: elementSchemaProperties,
72+
},
5473
},
55-
},
56-
ignoreProps: {
57-
type: 'boolean',
58-
},
59-
noAttributeStrings: {
60-
type: 'boolean',
61-
},
74+
elementSchemaProperties
75+
),
76+
additionalProperties: false,
6277
},
63-
additionalProperties: false,
64-
}],
78+
],
6579
},
6680

6781
create(context) {
@@ -72,7 +86,9 @@ module.exports = {
7286
noAttributeStrings: false,
7387
};
7488
const config = Object.assign({}, defaults, context.options[0] || {});
75-
config.allowedStrings = new Set(map(iterFrom(config.allowedStrings), trimIfString));
89+
config.allowedStrings = new Set(
90+
map(iterFrom(config.allowedStrings), trimIfString)
91+
);
7692

7793
function defaultMessageId(ancestorIsJSXElement) {
7894
if (config.noAttributeStrings && !ancestorIsJSXElement) {
@@ -101,9 +117,15 @@ module.exports = {
101117
const parent = getParentIgnoringBinaryExpressions(node);
102118

103119
function isParentNodeStandard() {
104-
if (!/^[\s]+$/.test(node.value) && typeof node.value === 'string' && parent.type.includes('JSX')) {
120+
if (
121+
!/^[\s]+$/.test(node.value) &&
122+
typeof node.value === 'string' &&
123+
parent.type.includes('JSX')
124+
) {
105125
if (config.noAttributeStrings) {
106-
return parent.type === 'JSXAttribute' || parent.type === 'JSXElement';
126+
return (
127+
parent.type === 'JSXAttribute' || parent.type === 'JSXElement'
128+
);
107129
}
108130
if (!config.noAttributeStrings) {
109131
return parent.type !== 'JSXAttribute';
@@ -139,7 +161,11 @@ module.exports = {
139161
const parentType = parents.parentType;
140162
const grandParentType = parents.grandParentType;
141163

142-
return parentType === 'JSXFragment' || parentType === 'JSXElement' || grandParentType === 'JSXElement';
164+
return (
165+
parentType === 'JSXFragment' ||
166+
parentType === 'JSXElement' ||
167+
grandParentType === 'JSXElement'
168+
);
143169
}
144170

145171
function reportLiteralNode(node, messageId) {
@@ -160,13 +186,21 @@ module.exports = {
160186

161187
return {
162188
Literal(node) {
163-
if (getValidation(node) && (hasJSXElementParentOrGrandParent(node) || !config.ignoreProps)) {
189+
if (
190+
getValidation(node) &&
191+
(hasJSXElementParentOrGrandParent(node) || !config.ignoreProps)
192+
) {
164193
reportLiteralNode(node);
165194
}
166195
},
167196

168197
JSXAttribute(node) {
169-
const isNodeValueString = node && node.value && node.value.type === 'Literal' && typeof node.value.value === 'string' && !config.allowedStrings.has(node.value.value);
198+
const isNodeValueString =
199+
node &&
200+
node.value &&
201+
node.value.type === 'Literal' &&
202+
typeof node.value.value === 'string' &&
203+
!config.allowedStrings.has(node.value.value);
170204

171205
if (config.noStrings && !config.ignoreProps && isNodeValueString) {
172206
const messageId = 'invalidPropValue';
@@ -184,10 +218,16 @@ module.exports = {
184218
const parents = getParentAndGrandParentType(node);
185219
const parentType = parents.parentType;
186220
const grandParentType = parents.grandParentType;
187-
const isParentJSXExpressionCont = parentType === 'JSXExpressionContainer';
188-
const isParentJSXElement = parentType === 'JSXElement' || grandParentType === 'JSXElement';
189-
190-
if (isParentJSXExpressionCont && config.noStrings && (isParentJSXElement || !config.ignoreProps)) {
221+
const isParentJSXExpressionCont =
222+
parentType === 'JSXExpressionContainer';
223+
const isParentJSXElement =
224+
parentType === 'JSXElement' || grandParentType === 'JSXElement';
225+
226+
if (
227+
isParentJSXExpressionCont &&
228+
config.noStrings &&
229+
(isParentJSXElement || !config.ignoreProps)
230+
) {
191231
reportLiteralNode(node);
192232
}
193233
},

0 commit comments

Comments
 (0)