Skip to content

Commit 01324a0

Browse files
kazuponota-meshi
andauthored
feat: support flat config (#487)
* refactor: update scripts * refactor: remove unnecesarry codes * refactor: update scripts * chore: change node register to jiti from ts-node * feat: flat config implementation * fix: update separate * fix: integration tests * fix: format * chore: bump node * chore: bump eslint * fix: forgot commit * fix: forgot lock file * fix: add ignore lint for tests * fix: test * docs: updates * Create pink-hairs-fail.md --------- Co-authored-by: Yosuke Ota <[email protected]>
1 parent 44fea72 commit 01324a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+814
-508
lines changed

.changeset/pink-hairs-fail.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@intlify/eslint-plugin-vue-i18n": minor
3+
---
4+
5+
feat: support flat config

.eslintignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
/dist
88
/docs/.vitepress/cache
99
/docs/.vitepress/dist
10+
/lib/configs/**/*.ts
1011
/node_modules
11-
# /tests/fixtures Used testcases
12-
/tests-integrations/config-recommended
12+
#/tests/fixtures # use testing
13+
/tests/integrations

.github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Setup Node.js
1818
uses: actions/setup-node@v4
1919
with:
20-
node-version: 16
20+
node-version: 18
2121
- name: Enable corepack
2222
run: corepack enable
2323
- name: Install
@@ -30,7 +30,7 @@ jobs:
3030
strategy:
3131
matrix:
3232
os: [ubuntu-latest]
33-
node: [16, 18, 20]
33+
node: [18, 20]
3434
steps:
3535
- name: Checkout
3636
uses: actions/checkout@v4

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
/tests/fixtures
1111
/tests-integrations/config-recommended
1212
/docs/.vitepress/cache
13+
/scripts/update-**.ts
1314

1415
# ignore files
1516
/CHANGELOG.md

docs/rules/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Available Rules
22

3-
- :star: mark: the rule which is enabled by `plugin:@intlify/vue-i18n/recommended` preset.
3+
- :star: mark: the rule which is enabled by `plugin:@intlify/vue-i18n/recommended` or `*.configs["flat/recommended"]` preset.
44
- :black_nib: mark: the rule which is fixable by `eslint --fix` command.
55

66
## Recommended

docs/rules/no-html-messages.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ since: v0.1.0
88

99
> disallow use HTML localization messages
1010
11-
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` property in a configuration file enables this rule.
11+
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` or `*.configs["flat/recommended"]` property in a configuration file enables this rule.
1212

1313
This rule reports in order to reduce the risk of injecting potentially unsafe localization message into the browser leading to supply-chain attack or XSS attack.
1414

docs/rules/no-missing-keys.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ since: v0.1.0
88

99
> disallow missing locale message key at localization methods
1010
11-
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` property in a configuration file enables this rule.
11+
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` or `*.configs["flat/recommended"]` property in a configuration file enables this rule.
1212

1313
This rule warns locale message key missing if the key does not exist in locale messages.
1414

docs/rules/no-raw-text.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ since: v0.2.0
88

99
> disallow to string literal in template or JSX
1010
11-
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` property in a configuration file enables this rule.
11+
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` or `*.configs["flat/recommended"]` property in a configuration file enables this rule.
1212

1313
This rule warns the usage of literal the bellow:
1414

docs/rules/no-v-html.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ since: v0.1.0
88

99
> disallow use of localization methods on v-html to prevent XSS attack
1010
11-
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` property in a configuration file enables this rule.
11+
- :star: The `"extends": "plugin:@intlify/vue-i18n/recommended"` or `*.configs["flat/recommended"]` property in a configuration file enables this rule.
1212

1313
This rule reports all uses of localization methods on `v-html` directive in order to reduce the risk of injecting potentially unsafe / unescaped html into the browser leading to Cross-Site Scripting (XSS) attacks.
1414

docs/started.md

+86-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,83 @@ npm install --save-dev eslint @intlify/eslint-plugin-vue-i18n
1717

1818
## :rocket: Usage
1919

20-
Configure your `.eslintrc.*` file.
20+
### Configuration `eslint.config.[c|m]js`
21+
22+
Use `eslint.config.[c|m]js` file to configure rules. This is the default in ESLint v9, but can be used starting from ESLint v8.57.0. See also: https://eslint.org/docs/latest/use/configure/configuration-files-new.
23+
24+
Example eslint.config.js:
25+
26+
```js
27+
import vueI18n from '@intlify/eslint-plugin-vue-i18n'
28+
29+
export default [
30+
// add more generic rulesets here, such as:
31+
// js.configs.recommended, // '@eslint/js'
32+
// ...vue.configs['flat/recommended'], // 'eslint-plugin-vue'
33+
34+
...vueI18n.configs['flat/recommended'],
35+
{
36+
rules: {
37+
// Optional.
38+
'@intlify/vue-i18n/no-dynamic-keys': 'error',
39+
'@intlify/vue-i18n/no-unused-keys': [
40+
'error',
41+
{
42+
extensions: ['.js', '.vue']
43+
}
44+
]
45+
},
46+
settings: {
47+
'vue-i18n': {
48+
localeDir: './path/to/locales/*.{json,json5,yaml,yml}', // extension is glob formatting!
49+
// or
50+
// localeDir: {
51+
// pattern: './path/to/locales/*.{json,json5,yaml,yml}', // extension is glob formatting!
52+
// localeKey: 'file' // or 'path' or 'key'
53+
// }
54+
// or
55+
// localeDir: [
56+
// {
57+
// // 'file' case
58+
// pattern: './path/to/locales1/*.{json,json5,yaml,yml}',
59+
// localeKey: 'file'
60+
// },
61+
// {
62+
// // 'path' case
63+
// pattern: './path/to/locales2/*.{json,json5,yaml,yml}',
64+
// localePattern: /^.*\/(?<locale>[A-Za-z0-9-_]+)\/.*\.(json5?|ya?ml)$/,
65+
// localeKey: 'path'
66+
// },
67+
// {
68+
// // 'key' case
69+
// pattern: './path/to/locales3/*.{json,json5,yaml,yml}',
70+
// localeKey: 'key'
71+
// },
72+
// ]
73+
74+
// Specify the version of `vue-i18n` you are using.
75+
// If not specified, the message will be parsed twice.
76+
messageSyntaxVersion: '^9.0.0'
77+
}
78+
}
79+
}
80+
]
81+
```
82+
83+
See the [rule list](./rules/index.md) to get the `configs` & `rules` that this plugin provides.
84+
85+
#### Bundle Configurations `eslint.config.[c|m]js`
86+
87+
This plugin provides some predefined configs. You can use the following configs by adding them to `eslint.config.[c|m]js`. (All flat configs in this plugin are provided as arrays, so spread syntax is required when combining them with other configs.)
88+
89+
- `*.configs["flat/base"]`: Settings and rules to enable correct ESLint parsing.
90+
- `*.configs["flat/recommended"]`: Above, plus rules to enforce subjective community defaults to ensure consistency.
91+
92+
### Configuration `.eslintrc.*`
93+
94+
Use `.eslintrc.*` file to configure rules in ESLint < v9. See also: https://eslint.org/docs/latest/use/configure/.
95+
96+
Example `.eslintrc.js`:
2197

2298
For example:
2399

@@ -74,7 +150,14 @@ module.export = {
74150
}
75151
```
76152

77-
See [the rule list](/rules/)
153+
See the [rule list](./rules/index.md) to get the `configs` & `rules` that this plugin provides.
154+
155+
#### Bundle Configurations `.eslintrc.*`
156+
157+
This plugin provides some predefined configs. You can use the following configs by adding them to `.eslintrc.*`. (All flat configs in this plugin are provided as arrays, so spread syntax is required when combining them with other configs.)
158+
159+
- `"plugin:@intlify/vue-i18n/base"`: Settings and rules to enable correct ESLint parsing.
160+
- `"plugin:@intlify/vue-i18n/recommended"`: Above, plus rules to enforce subjective community defaults to ensure consistency.
78161

79162
### `settings['vue-i18n']`
80163

@@ -102,7 +185,7 @@ If you want to run `eslint` from command line, make sure you include the `.vue`,
102185

103186
Examples:
104187

105-
```bash
188+
```sh
106189
eslint --ext .js,.vue,.json src
107190
eslint "src/**/*.{js,vue,json}"
108191
# Specify the extension you use.

lib/configs.ts

-8
This file was deleted.

lib/configs/base.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1+
/** DON'T EDIT THIS FILE; was created by scripts. */
12
export = {
23
parser: require.resolve('vue-eslint-parser'),
34
plugins: ['@intlify/vue-i18n'],
45
overrides: [
56
{
67
files: ['*.json', '*.json5'],
7-
// TODO: If you do not use vue-eslint-parser, you will get an error in vue rules.
8-
// see https://github.com/vuejs/eslint-plugin-vue/pull/1262
98
parser: require.resolve('vue-eslint-parser'),
109
parserOptions: {
1110
parser: require.resolve('jsonc-eslint-parser')
1211
}
1312
},
1413
{
1514
files: ['*.yaml', '*.yml'],
16-
// TODO: If you do not use vue-eslint-parser, you will get an error in vue rules.
17-
// see https://github.com/vuejs/eslint-plugin-vue/pull/1262
1815
parser: require.resolve('vue-eslint-parser'),
1916
parserOptions: {
2017
parser: require.resolve('yaml-eslint-parser')
2118
},
2219
rules: {
23-
// ESLint core rules known to cause problems with YAML.
24-
// https://github.com/ota-meshi/eslint-plugin-yml/blob/4e468109b9d2f4376b8d4d1221adba27c6ee04b2/src/configs/base.ts#L7-L11
2520
'no-irregular-whitespace': 'off',
2621
'spaced-comment': 'off'
2722
}

lib/configs/flat/base.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/** DON'T EDIT THIS FILE; was created by scripts. */
2+
export = [
3+
{
4+
name: '@intlify/vue-i18n:base:setup',
5+
plugins: {
6+
get '@intlify/vue-i18n'() {
7+
return require('../../index')
8+
}
9+
}
10+
},
11+
{
12+
name: '@intlify/vue-i18n:base:setup:json',
13+
files: ['*.json', '**/*.json', '*.json5', '**/*.json5'],
14+
languageOptions: {
15+
parser: require('vue-eslint-parser'),
16+
parserOptions: {
17+
parser: require('jsonc-eslint-parser')
18+
}
19+
}
20+
},
21+
{
22+
name: '@intlify/vue-i18n:base:setup:yaml',
23+
files: ['*.yaml', '**/*.yaml', '*.yml', '**/*.yml'],
24+
languageOptions: {
25+
parser: require('vue-eslint-parser'),
26+
parserOptions: {
27+
parser: require('yaml-eslint-parser')
28+
}
29+
},
30+
rules: {
31+
'no-irregular-whitespace': 'off',
32+
'spaced-comment': 'off'
33+
}
34+
}
35+
]

lib/configs/flat/recommended.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/** DON'T EDIT THIS FILE; was created by scripts. */
2+
const globals = require('globals')
3+
const config = require('./base')
4+
export = [
5+
...config,
6+
{
7+
name: '@intlify/vue-i18n:recommended:setup',
8+
languageOptions: {
9+
ecmaVersion: 2018,
10+
sourceType: 'module',
11+
globals: globals.browser,
12+
parserOptions: {
13+
ecmaFeatures: {
14+
jsx: true
15+
}
16+
}
17+
}
18+
},
19+
{
20+
name: '@intlify/vue-i18n:recommended:rules',
21+
rules: {
22+
'@intlify/vue-i18n/no-html-messages': 'warn',
23+
'@intlify/vue-i18n/no-missing-keys': 'warn',
24+
'@intlify/vue-i18n/no-raw-text': 'warn',
25+
'@intlify/vue-i18n/no-v-html': 'warn'
26+
}
27+
}
28+
]

lib/index.ts

+56-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,59 @@
1-
/**
2-
* @fileoverview ESLint plugin for vue-i18n
3-
* @author kazuya kawaguchi (a.k.a. kazupon)
4-
*/
5-
import configs from './configs'
6-
import rules from './rules'
1+
/** DON'T EDIT THIS FILE; was created by scripts. */
2+
// configs
3+
import base from './configs/base'
4+
import recommended from './configs/recommended'
5+
import flatBase from './configs/flat/base'
6+
import flatRecommended from './configs/flat/recommended'
77

8+
// rules
9+
import keyFormatStyle from './rules/key-format-style'
10+
import noDeprecatedI18nComponent from './rules/no-deprecated-i18n-component'
11+
import noDeprecatedI18nPlaceAttr from './rules/no-deprecated-i18n-place-attr'
12+
import noDeprecatedI18nPlacesProp from './rules/no-deprecated-i18n-places-prop'
13+
import noDuplicateKeysInLocale from './rules/no-duplicate-keys-in-locale'
14+
import noDynamicKeys from './rules/no-dynamic-keys'
15+
import noHtmlMessages from './rules/no-html-messages'
16+
import noI18nTPathProp from './rules/no-i18n-t-path-prop'
17+
import noMissingKeysInOtherLocales from './rules/no-missing-keys-in-other-locales'
18+
import noMissingKeys from './rules/no-missing-keys'
19+
import noRawText from './rules/no-raw-text'
20+
import noUnknownLocale from './rules/no-unknown-locale'
21+
import noUnusedKeys from './rules/no-unused-keys'
22+
import noVHtml from './rules/no-v-html'
23+
import preferLinkedKeyWithParen from './rules/prefer-linked-key-with-paren'
24+
import preferSfcLangAttr from './rules/prefer-sfc-lang-attr'
25+
import sfcLocaleAttr from './rules/sfc-locale-attr'
26+
import validMessageSyntax from './rules/valid-message-syntax'
27+
28+
// export plugin
829
export = {
9-
configs,
10-
rules
30+
configs: {
31+
// eslintrc configs
32+
base,
33+
recommended,
34+
35+
// flat configs
36+
'flat/base': flatBase,
37+
'flat/recommended': flatRecommended
38+
},
39+
rules: {
40+
'key-format-style': keyFormatStyle,
41+
'no-deprecated-i18n-component': noDeprecatedI18nComponent,
42+
'no-deprecated-i18n-place-attr': noDeprecatedI18nPlaceAttr,
43+
'no-deprecated-i18n-places-prop': noDeprecatedI18nPlacesProp,
44+
'no-duplicate-keys-in-locale': noDuplicateKeysInLocale,
45+
'no-dynamic-keys': noDynamicKeys,
46+
'no-html-messages': noHtmlMessages,
47+
'no-i18n-t-path-prop': noI18nTPathProp,
48+
'no-missing-keys-in-other-locales': noMissingKeysInOtherLocales,
49+
'no-missing-keys': noMissingKeys,
50+
'no-raw-text': noRawText,
51+
'no-unknown-locale': noUnknownLocale,
52+
'no-unused-keys': noUnusedKeys,
53+
'no-v-html': noVHtml,
54+
'prefer-linked-key-with-paren': preferLinkedKeyWithParen,
55+
'prefer-sfc-lang-attr': preferSfcLangAttr,
56+
'sfc-locale-attr': sfcLocaleAttr,
57+
'valid-message-syntax': validMessageSyntax
58+
}
1159
}

0 commit comments

Comments
 (0)