diff --git a/docs/rules/index.md b/docs/rules/index.md index 80651d6..eb45a48 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -25,6 +25,7 @@ | Rule ID | Description | | |:--------|:------------|:---| | [@intlify/vue-i18n/key-format-style](./key-format-style.html) | enforce specific casing for localization keys | | +| [@intlify/vue-i18n/no-deprecated-tc](./no-deprecated-tc.html) | disallow using deprecated `tc` or `$tc` (Deprecated in Vue I18n 10.0.0, removed fully in Vue I18n 11.0.0) | | | [@intlify/vue-i18n/no-duplicate-keys-in-locale](./no-duplicate-keys-in-locale.html) | disallow duplicate localization keys within the same locale | | | [@intlify/vue-i18n/no-dynamic-keys](./no-dynamic-keys.html) | disallow localization dynamic keys at localization methods | | | [@intlify/vue-i18n/no-missing-keys-in-other-locales](./no-missing-keys-in-other-locales.html) | disallow missing locale message keys in other locales | | diff --git a/docs/rules/no-deprecated-tc.md b/docs/rules/no-deprecated-tc.md new file mode 100644 index 0000000..a5bc232 --- /dev/null +++ b/docs/rules/no-deprecated-tc.md @@ -0,0 +1,64 @@ +--- +title: '@intlify/vue-i18n/no-deprecated-tc' +description: disallow using deprecated `tc` or `$tc` (Deprecated in Vue I18n 10.0.0, removed fully in Vue I18n 11.0.0) +since: v3.0.0 +--- + +# @intlify/vue-i18n/no-deprecated-tc + +> disallow using deprecated `tc` or `$tc` (Deprecated in Vue I18n 10.0.0, removed fully in Vue I18n 11.0.0) + +If you are migrating from Vue I18n v9 to v10, `tc` or `$tc` should be replaced with `t` or `$t`. + +## :book: Rule Details + +This rule reports use of deprecated `tc` or `$tc` (Deprecated in Vue I18n 10.0.0, removed fully in Vue I18n 11.0.0) + +:-1: Examples of **incorrect** code for this rule: + + + + + +```vue + + +``` + + + +:+1: Examples of **correct** code for this rule: + + + + + +```vue + + +``` + + + +## :books: Further reading + +- [Vue I18n > Breaking Changes in v10 - Deprecate tc and $tc for Legacy API mode](https://vue-i18n.intlify.dev/guide/migration/breaking10.html#deprecate-tc-and-tc-for-legacy-api-mode) + +## :rocket: Version + +This rule was introduced in `@intlify/eslint-plugin-vue-i18n` v3.0.0 + +## :mag: Implementation + +- [Rule source](https://github.com/intlify/eslint-plugin-vue-i18n/blob/master/lib/rules/no-deprecated-tc.ts) +- [Test source](https://github.com/intlify/eslint-plugin-vue-i18n/tree/master/tests/lib/rules/no-deprecated-tc.ts) diff --git a/lib/index.ts b/lib/index.ts index dbd5a84..3bad70a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -11,6 +11,7 @@ import noDeprecatedI18nComponent from './rules/no-deprecated-i18n-component' import noDeprecatedI18nPlaceAttr from './rules/no-deprecated-i18n-place-attr' import noDeprecatedI18nPlacesProp from './rules/no-deprecated-i18n-places-prop' import noDeprecatedModuloSyntax from './rules/no-deprecated-modulo-syntax' +import noDeprecatedTc from './rules/no-deprecated-tc' import noDuplicateKeysInLocale from './rules/no-duplicate-keys-in-locale' import noDynamicKeys from './rules/no-dynamic-keys' import noHtmlMessages from './rules/no-html-messages' @@ -43,6 +44,7 @@ export = { 'no-deprecated-i18n-place-attr': noDeprecatedI18nPlaceAttr, 'no-deprecated-i18n-places-prop': noDeprecatedI18nPlacesProp, 'no-deprecated-modulo-syntax': noDeprecatedModuloSyntax, + 'no-deprecated-tc': noDeprecatedTc, 'no-duplicate-keys-in-locale': noDuplicateKeysInLocale, 'no-dynamic-keys': noDynamicKeys, 'no-html-messages': noHtmlMessages, diff --git a/lib/rules/no-deprecated-tc.ts b/lib/rules/no-deprecated-tc.ts new file mode 100644 index 0000000..63de6d5 --- /dev/null +++ b/lib/rules/no-deprecated-tc.ts @@ -0,0 +1,60 @@ +/** + * @author kazuya kawaguchi (a.k.a. kazupon) + */ +import { defineTemplateBodyVisitor } from '../utils/index' +import { createRule } from '../utils/rule' + +import type { RuleContext, RuleListener } from '../types' +import type { AST as VAST } from 'vue-eslint-parser' + +function checkCallExpression( + context: RuleContext, + node: VAST.ESLintCallExpression +) { + const funcName = + (node.callee.type === 'MemberExpression' && + node.callee.property.type === 'Identifier' && + node.callee.property.name) || + (node.callee.type === 'Identifier' && node.callee.name) || + '' + + if (/^(\$tc|tc)$/.test(funcName)) { + context.report({ + node, + message: `'${funcName}' is used, but it is deprecated. Use 't' or '$t' instead.` + }) + return + } +} + +function create(context: RuleContext): RuleListener { + return defineTemplateBodyVisitor( + context, + { + CallExpression(node: VAST.ESLintCallExpression) { + checkCallExpression(context, node) + } + }, + { + CallExpression(node: VAST.ESLintCallExpression) { + checkCallExpression(context, node) + } + } + ) +} + +export = createRule({ + meta: { + type: 'suggestion', + docs: { + description: + 'disallow using deprecated `tc` or `$tc` (Deprecated in Vue I18n 10.0.0, removed fully in Vue I18n 11.0.0)', + category: 'Best Practices', + url: 'https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-tc.html', + recommended: false + }, + fixable: null, + schema: [] + }, + create +}) diff --git a/tests/lib/rules/no-deprecated-tc.ts b/tests/lib/rules/no-deprecated-tc.ts new file mode 100644 index 0000000..22b0cb1 --- /dev/null +++ b/tests/lib/rules/no-deprecated-tc.ts @@ -0,0 +1,38 @@ +/** + * @author kazuya kawaguchi (a.k.a. kazupon) + */ +import { RuleTester } from '../eslint-compat' +import rule from '../../../lib/rules/no-deprecated-tc' +import * as vueParser from 'vue-eslint-parser' + +const tester = new RuleTester({ + languageOptions: { parser: vueParser, ecmaVersion: 2015 } +}) + +tester.run('no-deprecated-tc', rule as never, { + valid: [], + invalid: [ + { + // tc key + code: `tc('banana')`, + errors: [`'tc' is used, but it is deprecated. Use 't' or '$t' instead.`] + }, + { + // $tc key + code: `$tc('banana')`, + errors: [`'$tc' is used, but it is deprecated. Use 't' or '$t' instead.`] + }, + { + // via i18n instance + code: `i18n.tc('banana')`, + errors: [`'tc' is used, but it is deprecated. Use 't' or '$t' instead.`] + }, + { + // using mustaches in template block + code: ``, + errors: [`'$tc' is used, but it is deprecated. Use 't' or '$t' instead.`] + } + ] +})