Socket
Socket
Sign inDemoInstall

eslint-plugin-i18next

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-i18next - npm Package Compare versions

Comparing version 2.3.0 to 3.2.0

lib/constants.js

54

CHANGELOG.md

@@ -5,2 +5,56 @@ # Changelog

## [3.2.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v3.1.1...v3.2.0) (2019-10-21)
### Features
* allow displayName property in classes ([5362281](https://github.com/edvardchen/eslint-plugin-i18next/commit/5362281))
### [3.1.1](https://github.com/edvardchen/eslint-plugin-i18next/compare/v3.1.0...v3.1.1) (2019-10-10)
### Bug Fixes
* add missing plugin in recommended config ([dde83ed](https://github.com/edvardchen/eslint-plugin-i18next/commit/dde83ed))
## [3.1.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v3.0.0...v3.1.0) (2019-10-10)
### Features
* ignore not-word string ([1752cbe](https://github.com/edvardchen/eslint-plugin-i18next/commit/1752cbe))
## [3.0.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v2.5.0...v3.0.0) (2019-10-09)
### ⚠ BREAKING CHANGES
* SInce the whitelist was cut short, it would complain when the removed attributes
were added to custom component like <Foo src="hello" />
### Features
* ignore most DOM attrs ([71483c2](https://github.com/edvardchen/eslint-plugin-i18next/commit/71483c2))
## [2.5.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v2.4.0...v2.5.0) (2019-10-08)
### Features
* add more ignored attributes and callee ([0f9e2ec](https://github.com/edvardchen/eslint-plugin-i18next/commit/0f9e2ec))
## [2.4.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v2.3.1...v2.4.0) (2019-10-08)
### Features
* add ignoreAttribute option ([c854313](https://github.com/edvardchen/eslint-plugin-i18next/commit/c854313))
### [2.3.1](https://github.com/edvardchen/eslint-plugin-i18next/compare/v2.3.0...v2.3.1) (2019-09-16)
### Bug Fixes
* whitelist addEventListener and few SVG attributes ([46241a6](https://github.com/edvardchen/eslint-plugin-i18next/commit/46241a6))
## [2.3.0](https://github.com/edvardchen/eslint-plugin-i18next/compare/v2.2.0...v2.3.0) (2019-07-26)

@@ -7,0 +61,0 @@

@@ -0,1 +1,3 @@

const { DOM_TAGS, SVG_TAGS } = require('./constants');
function isUpperCase(str) {

@@ -5,2 +7,20 @@ return /^[A-Z_-]+$/.test(str);

function isNativeDOMTag(str) {
return DOM_TAGS.includes(str);
}
function isSvgTag(str) {
return SVG_TAGS.includes(str);
}
const blacklistAttrs = ['placeholder', 'alt', 'aria-label', 'value'];
function isAllowedDOMAttr(tag, attr) {
if (isSvgTag(tag)) return true;
if (isNativeDOMTag(tag)) {
return !blacklistAttrs.includes(attr);
}
return false;
}
exports.isUpperCase = isUpperCase;
exports.isAllowedDOMAttr = isAllowedDOMAttr;

1

lib/index.js

@@ -22,2 +22,3 @@ /**

recommended: {
plugins: ['i18next'],
rules: {

@@ -24,0 +25,0 @@ 'i18next/no-literal-string': [2]

@@ -7,3 +7,3 @@ /**

const { isUpperCase } = require('../helper');
const { isUpperCase, isAllowedDOMAttr } = require('../helper');
// const { TypeFlags, SyntaxKind } = require('typescript');

@@ -37,2 +37,8 @@

}
},
ignoreAttribute: {
type: 'array',
items: {
type: 'string'
}
}

@@ -51,5 +57,6 @@ },

} = context;
const whitelists = ((option && option.ignore) || []).map(
item => new RegExp(item)
);
const whitelists = [
/^[^A-Za-z]+$/, // ignore not-word string
...((option && option.ignore) || [])
].map(item => new RegExp(item));

@@ -78,8 +85,21 @@ const calleeWhitelists = generateCalleeWhitelists(option);

if (calleeName === 'require') return true;
return calleeWhitelists.simple.indexOf(calleeName) !== -1;
}
const atts = ['className', 'style', 'styleName', 'src', 'type', 'id'];
const ignoredClassProperties = ['displayName'];
const ignoredAttributes = (option && option.ignoreAttribute) || [];
const userJSXAttrs = [
'className',
'styleName',
'type',
'id',
'width',
'height',
...ignoredAttributes
];
function isValidAttrName(name) {
return atts.includes(name);
return userJSXAttrs.includes(name);
}

@@ -143,7 +163,15 @@

const parent = getNearestAncestor(node, 'JSXAttribute');
const attrName = parent.name.name;
// allow <div className="active" />
if (isValidAttrName(parent.name.name)) {
// allow <MyComponent className="active" />
if (isValidAttrName(attrName)) {
visited.add(node);
return;
}
const jsxElement = getNearestAncestor(node, 'JSXOpeningElement');
const tagName = jsxElement.name.name;
if (isAllowedDOMAttr(tagName, attrName)) {
visited.add(node);
}
},

@@ -174,2 +202,10 @@

'ClassProperty > Literal'(node) {
const { parent } = node;
if (parent.key && ignoredClassProperties.includes(parent.key.name)) {
visited.add(node);
}
},
'VariableDeclarator > Literal'(node) {

@@ -288,2 +324,6 @@ // allow statements like const A_B = "test"

const popularCallee = [
'addEventListener',
'removeEventListener',
'postMessage',
'getElementById',
//

@@ -297,3 +337,5 @@ // ─── VUEX CALLEE ────────────────────────────────────────────────────────────────

'includes',
'indexOf'
'indexOf',
'endsWith',
'startsWith'
];

@@ -300,0 +342,0 @@ function generateCalleeWhitelists(option) {

{
"name": "eslint-plugin-i18next",
"version": "2.3.0",
"version": "3.2.0",
"description": "ESLint plugin for i18n",

@@ -35,3 +35,5 @@ "keywords": [

"husky": "^1.3.1",
"lint-staged": "^9.4.2",
"mocha": "^6.1.4",
"prettier": "^1.18.2",
"typescript": "^3.5.2",

@@ -43,4 +45,11 @@ "vue-eslint-parser": "^6.0.3"

},
"lint-staged": {
"*.js": [
"prettier --write",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"

@@ -47,0 +56,0 @@ }

@@ -189,2 +189,16 @@ # eslint-plugin-i18next

#### SwithCase
Skip switchcase statement:
```typescript
// correct
switch (type) {
case 'foo':
break;
case 'bar':
break;
}
```
### Options

@@ -215,1 +229,12 @@

```
#### ignoreAttribute
The `ignoreAttribute` option specifies exceptions not to check for JSX attributes that match one of ignored attributes.
Examples of correct code for the `{ "ignoreAttribute": ["foo"] }` option:
```jsx
/*eslint i18next/no-literal-string: ["error", { "ignoreAttribute": ["foo"] }]*/
const element = <div foo="bar" />;
```

@@ -38,4 +38,16 @@ /**

{ code: 'a.includes("ios")' },
{ code: 'a.startsWith("ios")' },
{ code: 'a.endsWith("@gmail.com")' },
{ code: 'export * from "hello_export_all";' },
{ code: 'export { a } from "hello_export";' },
{
code:
'document.addEventListener("click", (event) => { event.preventDefault() })'
},
{
code:
'document.removeEventListener("click", (event) => { event.preventDefault() })'
},
{ code: 'window.postMessage("message", "*")' },
{ code: 'document.getElementById("some-id")' },
{ code: 'require("hello");' },

@@ -45,2 +57,4 @@ { code: 'const a = require(["hello"]);' },

{ code: 'const a = 1;' },
{ code: 'const a = "?";' },
{ code: `const a = "0123456789!@#$%^&*()_+|~-=\`[]{};':\\",./<>?";` },
{ code: 'i18n("hello");' },

@@ -59,6 +73,25 @@ { code: 'dispatch("hello");' },

{ code: 'var a = {foo: "FOO"};' },
{ code: 'class Form extends Component { displayName = "FormContainer" };' },
// JSX
{ code: '<div className="primary"></div>' },
{ code: '<div className={a ? "active": "inactive"}></div>' },
{ code: '<div>{i18next.t("foo")}</div>' }
{ code: '<div>{i18next.t("foo")}</div>' },
{ code: '<svg viewBox="0 0 20 40"></svg>' },
{ code: '<line x1="0" y1="0" x2="10" y2="20" />' },
{ code: '<path d="M10 10" />' },
{
code:
'<circle width="16px" height="16px" cx="10" cy="10" r="2" fill="red" />'
},
{
code:
'<a href="https://google.com" target="_blank" rel="noreferrer noopener"></a>'
},
{
code: '<div id="some-id" tabIndex="0" aria-labelledby="label-id"></div>'
},
{ code: '<div role="button"></div>' },
{ code: '<img src="./image.png" />' },
{ code: '<button type="button" for="form-id" />' },
{ code: '<DIV foo="bar" />', options: [{ ignoreAttribute: ['foo'] }] }
],

@@ -77,5 +110,9 @@

{ code: 'const a = "afoo";', options: [{ ignore: ['^foo'] }], errors },
{ code: 'class Form extends Component { property = "Something" };', errors },
// JSX
{ code: '<div>foo</div>', errors },
{ code: '<div>FOO</div>', errors }
{ code: '<div>FOO</div>', errors },
{ code: '<DIV foo="bar" />', errors },
{ code: '<img src="./image.png" alt="some-image" />', errors },
{ code: '<button aria-label="Close" type="button" />', errors }
]

@@ -82,0 +119,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc