eslint-plugin-i18next
Advanced tools
| import type { ESLint } from 'eslint'; | ||
| declare const plugin: ESLint.Plugin & { | ||
| configs: { | ||
| 'flat/recommended': ESLint.ConfigData | ||
| } | ||
| }; | ||
| export = plugin; |
+25
-8
@@ -18,11 +18,28 @@ /** | ||
| // import all rules in lib/rules | ||
| module.exports.rules = requireIndex(__dirname + '/rules'); | ||
| const rules = requireIndex(__dirname + '/rules'); | ||
| /** | ||
| * @type {import('eslint').ESLint.Plugin} | ||
| */ | ||
| const plugin = { | ||
| rules, | ||
| module.exports.configs = { | ||
| recommended: { | ||
| plugins: ['i18next'], | ||
| rules: { | ||
| 'i18next/no-literal-string': [2] | ||
| } | ||
| } | ||
| configs: { | ||
| // for ESLint v9 | ||
| 'flat/recommended': { | ||
| plugins: { i18next: { rules } }, | ||
| rules: { | ||
| 'i18next/no-literal-string': [2], | ||
| }, | ||
| }, | ||
| // for ESLint below v9 | ||
| recommended: { | ||
| plugins: ['i18next'], | ||
| rules: { | ||
| 'i18next/no-literal-string': [2], | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| module.exports = plugin; |
@@ -92,2 +92,7 @@ /** | ||
| const { esTreeNodeToTSNodeMap, program } = parserServices; | ||
| let typeChecker; | ||
| if (program && esTreeNodeToTSNodeMap) | ||
| typeChecker = program.getTypeChecker(); | ||
| function validateBeforeReport(node) { | ||
@@ -97,2 +102,26 @@ if (isValidScope()) return; | ||
| // ─── Typescript ────────────────────────────────────── | ||
| if (typeChecker) { | ||
| const tsNode = esTreeNodeToTSNodeMap.get(node); | ||
| const typeObj = typeChecker.getContextualType(tsNode); | ||
| if (typeObj) { | ||
| // var a: 'abc' = 'abc' | ||
| if (typeObj.isStringLiteral()) { | ||
| return; | ||
| } | ||
| // var a: 'abc' | 'name' = 'abc' | ||
| if (typeObj.isUnion()) { | ||
| const found = typeObj.types.some(item => { | ||
| if (item.isStringLiteral() && item.value === node.value) { | ||
| return true; | ||
| } | ||
| }); | ||
| if (found) return; | ||
| } | ||
| } | ||
| } | ||
| // ───────────────────────────────────────────────────── | ||
| report(node); | ||
@@ -99,0 +128,0 @@ } |
+3
-2
| { | ||
| "name": "eslint-plugin-i18next", | ||
| "version": "6.0.9", | ||
| "version": "6.1.0", | ||
| "description": "ESLint plugin for i18n", | ||
@@ -19,2 +19,3 @@ "keywords": [ | ||
| ], | ||
| "types": "lib/index.d.ts", | ||
| "repository": { | ||
@@ -28,3 +29,3 @@ "type": "git", | ||
| "test:watch": "npm t -- --watch", | ||
| "test": "mocha --timeout 50000 tests/lib/rules/no-literal-string/" | ||
| "test": "mocha --timeout 50000 tests/lib/rules/no-literal-string/ && pnpm --filter='./examples/*' run lint" | ||
| }, | ||
@@ -31,0 +32,0 @@ "dependencies": { |
+10
-15
@@ -15,23 +15,18 @@ # eslint-plugin-i18next | ||
| Add `i18next` to the plugins section of your `.eslintrc` configuration file. | ||
| For ESLint 9 flat configuration, | ||
| ```json | ||
| { | ||
| "plugins": ["i18next"] | ||
| } | ||
| ``` | ||
| ```js | ||
| // eslint.config.mjs | ||
| import i18next from 'eslint-plugin-i18next'; | ||
| Then configure the rules you want to use under the rules section. | ||
| ```json | ||
| { | ||
| "rules": { | ||
| "i18next/no-literal-string": 2 | ||
| } | ||
| } | ||
| export default [ | ||
| // your other configs | ||
| i18next.configs['flat/recommended'], | ||
| ]; | ||
| ``` | ||
| or | ||
| For ESLint 8 and below, | ||
| ```json | ||
| // .eslintrc | ||
| { | ||
@@ -38,0 +33,0 @@ "extends": ["plugin:i18next/recommended"] |
27469
6.14%15
7.14%974
5.07%62
-7.46%