eslint-plugin-i18next
Advanced tools
Comparing version 6.0.0-4 to 6.0.0-6
@@ -5,2 +5,12 @@ # Changelog | ||
## [6.0.0-6](https://github.com/edvardchen/eslint-plugin-i18next/compare/v6.0.0-5...v6.0.0-6) (2022-11-21) | ||
## [6.0.0-5](https://github.com/edvardchen/eslint-plugin-i18next/compare/v6.0.0-4...v6.0.0-5) (2022-07-14) | ||
### Bug Fixes | ||
* corrected typo ([9fba5c2](https://github.com/edvardchen/eslint-plugin-i18next/commit/9fba5c287f9f55f2e71c3e41f163ae8793fe5cc1)) | ||
* remove the problematic typescript validation ([a021fe0](https://github.com/edvardchen/eslint-plugin-i18next/commit/a021fe06c0db26d732739bb56604bcbf28aad431)) | ||
## [6.0.0-4](https://github.com/edvardchen/eslint-plugin-i18next/compare/v6.0.0-3...v6.0.0-4) (2022-05-31) | ||
@@ -7,0 +17,0 @@ |
@@ -55,13 +55,68 @@ # disallow literal string (no-literal-string) | ||
For selectors, | ||
### Option `words` | ||
- `words` controls plain text | ||
- `jsx-components` controls JSX elements | ||
- `jsx-attributes` controls JSX elements' attributes | ||
- `callees` controls function calls | ||
- `object-properties` controls objects' properties | ||
- `class-properties` controls classes' properties | ||
`words` decides whether literal strings are allowed (in any situation), solely based on **the content of the string** | ||
Other options, | ||
e.g. if `.*foo.*` is excluded, the following literals are allowed no matter where they are used | ||
```js | ||
method('afoo'); | ||
const message = 'foob'; | ||
<Component value="foo" />; | ||
``` | ||
### Selector options | ||
- `jsx-components` decides whether literal strings as children within a component are allowed, based on the component name | ||
e.g. by default, `Trans` is excluded, so `Hello World` in the following is allowed. | ||
```jsx | ||
<Trans i18nKey="greeting">Hello World</Trans> | ||
``` | ||
- `jsx-attributes` decides whether literal strings are allowed as JSX attribute values, based on the name of the attribute | ||
e.g. if `data-testid` is excluded, `important-button` in the following is allowed | ||
```jsx | ||
<button data-testid="important-button" onClick={handleClick}> | ||
{t('importantButton.label')} | ||
</button> | ||
``` | ||
- `callees` decides whether literal strings are allowed as function arguments, based on the identifier of the function being called | ||
e.g. if `window.open` is excluded, `http://example.com` in the following is allowed | ||
```js | ||
window.open('http://example.com'); | ||
``` | ||
`callees` also covers object constructors, such as `new Error('string')` or `new URL('string')` | ||
- `object-properties` decides whether literal strings are allowed as object property values, based on the property key | ||
e.g. if `fieldName` is excluded but `label` is not, `currency_code` is allowed but `Currency` is not: | ||
```js | ||
const fieldConfig = { | ||
fieldName: 'currency_code', | ||
label: 'Currency', | ||
}; | ||
``` | ||
- `class-properties` decides whether literal strings are allowed as class property values, based on the property key | ||
e.g. by default, `displayName` is excluded, so `MyComponent` is allowed | ||
```js | ||
class My extends Component { | ||
displayName = 'MyComponent'; | ||
} | ||
``` | ||
### Other options | ||
- `mode` provides a straightforward way to decides the range you want to validate literal strings. | ||
@@ -68,0 +123,0 @@ It defaults to `jsx-text-only` which only forbids to write plain text in JSX markup |
@@ -33,17 +33,2 @@ /** | ||
function isValidTypeScriptAnnotation(esTreeNodeToTSNodeMap, typeChecker, node) { | ||
const tsNode = esTreeNodeToTSNodeMap.get(node); | ||
const typeObj = typeChecker.getTypeAtLocation(tsNode.parent); | ||
// var a: 'abc' | 'name' = 'abc' | ||
if (typeObj.isUnion()) { | ||
const found = typeObj.types.some(item => { | ||
if (item.isStringLiteral() && item.value === node.value) { | ||
return true; | ||
} | ||
}); | ||
return found; | ||
} | ||
} | ||
//------------------------------------------------------------------------------ | ||
@@ -100,7 +85,2 @@ // Rule Definition | ||
const { esTreeNodeToTSNodeMap, program } = parserServices; | ||
let typeChecker; | ||
if (program && esTreeNodeToTSNodeMap) | ||
typeChecker = program.getTypeChecker(); | ||
function report(node) { | ||
@@ -117,9 +97,2 @@ context.report({ | ||
if ( | ||
typeChecker && | ||
isValidTypeScriptAnnotation(esTreeNodeToTSNodeMap, typeChecker, node) | ||
) { | ||
return; | ||
} | ||
report(node); | ||
@@ -169,20 +142,2 @@ } | ||
'JSXElement Literal'(node) { | ||
if (mode === 'jsx-only') { | ||
validateBeforeReport(node); | ||
} | ||
}, | ||
'JSXElement > Literal'(node) { | ||
if (mode === 'jsx-text-only') { | ||
validateBeforeReport(node); | ||
} | ||
}, | ||
'JSXFragment > Literal'(node) { | ||
if (onlyValidateJSX) { | ||
validateBeforeReport(node); | ||
} | ||
}, | ||
JSXAttribute(node) { | ||
@@ -317,6 +272,20 @@ const attrName = node.name.name; | ||
'Literal:exit'(node) { | ||
// skip if it only validates jsx | ||
// checking if a literal is contained in a JSX element is hard to be performant | ||
// instead, we validate in jsx-related visitors | ||
if (onlyValidateJSX) return; | ||
const ancestors = context.getAncestors(); | ||
for (let i = ancestors.length - 1; i >= 0; i--) { | ||
const ancestor = ancestors[i]; | ||
if (['JSXElement', 'JSXFragment'].includes(ancestor.type)) { | ||
if (mode === 'jsx-text-only' && i !== ancestors.length - 1) { | ||
// the direct parent isn't JSXElement or JSXFragment under mode jsx-text-only | ||
// then skip | ||
return; | ||
} | ||
break; | ||
} | ||
if (i === 0) { | ||
// traversed to the root node and didn't find JSX element | ||
if (onlyValidateJSX) { | ||
return; | ||
} | ||
} | ||
} | ||
@@ -323,0 +292,0 @@ // ignore `var a = { "foo": 123 }` |
{ | ||
"name": "eslint-plugin-i18next", | ||
"version": "6.0.0-4", | ||
"version": "6.0.0-6", | ||
"description": "ESLint plugin for i18n", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -65,3 +65,3 @@ # eslint-plugin-i18next | ||
By default, it wil only validate the plain text in JSX markup instead of all literal strings in previous versions. | ||
By default, it will only validate the plain text in JSX markup instead of all literal strings in previous versions. | ||
[You can change it easily](./docs/rules/no-literal-string.md) |
@@ -7,3 +7,3 @@ declare module 'country-emoji' {} | ||
// var aa: 'abc' = 'abc'; | ||
var a4: 'abc' | 'name' | undefined = 'abc'; | ||
// var a4: 'abc' | 'name' | undefined = 'abc'; | ||
@@ -10,0 +10,0 @@ // type T = { name: 'b' }; |
const testFile = require('../../helpers/testFile'); | ||
const runTest = require('../../helpers/runTest'); | ||
const cases = { | ||
@@ -8,11 +7,8 @@ valid: [ | ||
code: '<DIV foo="bar" />', | ||
options: [ | ||
{ | ||
mode: 'jsx-only', | ||
'jsx-attributes': { | ||
exclude: ['foo'], | ||
}, | ||
}, | ||
], | ||
options: [{ mode: 'jsx-only', 'jsx-attributes': { exclude: ['foo'] } }], | ||
}, | ||
{ | ||
code: `<div>{[].map((a) => { switch (a) { case 'abc': return null; default: return null; } })}</div>`, | ||
options: [{ mode: 'jsx-only' }], | ||
}, | ||
], | ||
@@ -27,3 +23,2 @@ invalid: [ | ||
}; | ||
runTest('no-literal-string: mode jsx-only', cases); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60479
1166