@alexlit/config-eslint 161.3.0 → 162.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -105
- package/base.js +24 -3
- package/index.d.ts +111 -0
- package/index.js +81 -23
- package/package.json +18 -15
- package/plugins/de-morgan.js +13 -5
- package/plugins/import-x.js +54 -38
- package/plugins/javascript.js +100 -86
- package/plugins/jsdoc.js +28 -18
- package/plugins/json.js +35 -25
- package/plugins/perfectionist.js +112 -96
- package/plugins/pinia.js +21 -11
- package/plugins/prettier.js +31 -11
- package/plugins/regexp.js +20 -10
- package/plugins/sonar.js +23 -13
- package/plugins/stylistic.js +111 -101
- package/plugins/tailwindcss.js +23 -5
- package/plugins/tanstack-query.js +20 -10
- package/plugins/typescript-type-checked.js +48 -34
- package/plugins/typescript.js +27 -15
- package/plugins/unicorn.js +77 -65
- package/plugins/unocss.js +16 -6
- package/plugins/vitest.js +24 -14
- package/plugins/vue-accessibility.js +25 -13
- package/plugins/vue-i18n.js +41 -31
- package/plugins/vue.js +259 -243
- package/plugins/zod.js +21 -11
- package/rules/typescript.js +1 -1
package/plugins/tailwindcss.js
CHANGED
|
@@ -3,20 +3,32 @@ import { defineConfig } from 'eslint/config';
|
|
|
3
3
|
|
|
4
4
|
import { FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
+
const DEFAULT_CSS_CONFIG_PATH = './styles/tailwind.css';
|
|
7
|
+
|
|
6
8
|
/**
|
|
9
|
+
* Правила для Tailwind CSS.
|
|
10
|
+
*
|
|
11
|
+
* Опция `cssConfigPath` - путь к CSS-файлу с Tailwind-конфигурацией. Остальные
|
|
12
|
+
* опции - произвольные flat-опции ESLint, они добавляются отдельным блоком.
|
|
13
|
+
*
|
|
7
14
|
* @example
|
|
8
15
|
* import path from 'node:path';
|
|
9
16
|
*
|
|
10
|
-
* tailwindcss({
|
|
17
|
+
* plugins.tailwindcss({
|
|
11
18
|
* cssConfigPath: path.resolve(import.meta.dirname, 'src/tailwind.css'),
|
|
12
19
|
* });
|
|
13
20
|
*
|
|
14
|
-
* @param
|
|
21
|
+
* @param {import('eslint').Linter.Config & { cssConfigPath?: string }} [options]
|
|
22
|
+
* - Дополнительные flat-опции
|
|
23
|
+
*
|
|
24
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
15
25
|
*
|
|
16
26
|
* @see [eslint-plugin-tailwindcss](https://github.com/francoismassart/eslint-plugin-tailwindcss)
|
|
17
27
|
*/
|
|
18
|
-
export const tailwindcss = (
|
|
19
|
-
|
|
28
|
+
export const tailwindcss = (options = {}) => {
|
|
29
|
+
const { cssConfigPath, ...flat } = options;
|
|
30
|
+
|
|
31
|
+
return defineConfig([
|
|
20
32
|
{
|
|
21
33
|
files: FILES,
|
|
22
34
|
plugins: { tailwindcss: plugin },
|
|
@@ -27,7 +39,13 @@ export const tailwindcss = (settings) =>
|
|
|
27
39
|
},
|
|
28
40
|
settings: {
|
|
29
41
|
/** @type {import('eslint-plugin-tailwindcss').PluginSettings} */
|
|
30
|
-
tailwindcss: {
|
|
42
|
+
tailwindcss: {
|
|
43
|
+
cssConfigPath: DEFAULT_CSS_CONFIG_PATH,
|
|
44
|
+
...(cssConfigPath !== undefined && { cssConfigPath }),
|
|
45
|
+
},
|
|
31
46
|
},
|
|
32
47
|
},
|
|
48
|
+
|
|
49
|
+
...(Object.keys(flat).length > 0 ? [flat] : []),
|
|
33
50
|
]);
|
|
51
|
+
};
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import plugin from '@tanstack/eslint-plugin-query';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
import { DATA_FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, DATA_FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила для TanStack Query.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [@tanstack/query](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query)
|
|
14
|
+
*/
|
|
15
|
+
export const tanstackQuery = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
// The shipped config has no `files` key, so it would also cover data files.
|
|
18
|
+
...plugin.configs['flat/recommended'].map((config) => ({
|
|
19
|
+
...config,
|
|
20
|
+
ignores: [...(config.ignores ?? []), ...DATA_FILES],
|
|
21
|
+
})),
|
|
22
|
+
{ rules: { '@tanstack/query/infinite-query-property-order': 'off' } },
|
|
23
|
+
]),
|
|
24
|
+
);
|
|
@@ -1,50 +1,64 @@
|
|
|
1
1
|
import { defineConfig } from 'eslint/config';
|
|
2
2
|
import plugin from 'typescript-eslint';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createPlugin,
|
|
6
|
+
DATA_FILES,
|
|
7
|
+
FILES,
|
|
8
|
+
TEST_FILES,
|
|
9
|
+
TS_FILES,
|
|
10
|
+
} from '../base.js';
|
|
5
11
|
import { TS_RULES } from '../rules/typescript.js';
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
|
-
* Type-aware TypeScript
|
|
14
|
+
* Type-aware правила TypeScript.
|
|
9
15
|
*
|
|
10
16
|
* Opt-in: requires a `tsconfig.json` in the project and needs type information,
|
|
11
17
|
* which makes linting slower. Use it instead of `typescript`, not alongside
|
|
12
18
|
* it.
|
|
13
19
|
*
|
|
20
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
21
|
+
*
|
|
22
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
23
|
+
*
|
|
14
24
|
* @see [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint)
|
|
15
25
|
*/
|
|
16
|
-
export const typescriptTypeChecked =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
export const typescriptTypeChecked = createPlugin(() =>
|
|
27
|
+
defineConfig([
|
|
28
|
+
// The parser is needed for every JS/TS/Vue file, not only for TypeScript ones,
|
|
29
|
+
// otherwise `.js` files fall back to the default parser and modern syntax
|
|
30
|
+
// (`import.meta`, top-level await) breaks.
|
|
31
|
+
{ ...plugin.configs.base, files: FILES },
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
// Non type-aware rules - the same scope as the regular `typescript` plugin,
|
|
34
|
+
// so `.js`/`.vue` files keep the TypeScript versions of the rules.
|
|
35
|
+
// `plugin.configs.strict`/`stylistic` contain blocks without a `files` key,
|
|
36
|
+
// so they would also land on data files that are not JavaScript at all.
|
|
37
|
+
...[...plugin.configs.strict, ...plugin.configs.stylistic].map(
|
|
38
|
+
(config) => ({
|
|
39
|
+
...config,
|
|
40
|
+
ignores: [...(config.ignores ?? []), ...DATA_FILES],
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
30
43
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
// Type-aware rules only make sense where the type information is available.
|
|
45
|
+
...plugin.configs.strictTypeChecked.map((config) => ({
|
|
46
|
+
...config,
|
|
47
|
+
files: TS_FILES,
|
|
48
|
+
})),
|
|
49
|
+
...plugin.configs.stylisticTypeChecked.map((config) => ({
|
|
50
|
+
...config,
|
|
51
|
+
files: TS_FILES,
|
|
52
|
+
})),
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
])
|
|
54
|
+
{
|
|
55
|
+
files: TS_FILES,
|
|
56
|
+
languageOptions: { parserOptions: { projectService: true } },
|
|
57
|
+
rules: TS_RULES,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
files: TEST_FILES,
|
|
61
|
+
rules: { '@typescript-eslint/no-empty-function': 'off' },
|
|
62
|
+
},
|
|
63
|
+
]),
|
|
64
|
+
);
|
package/plugins/typescript.js
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { defineConfig } from 'eslint/config';
|
|
2
2
|
import plugin from 'typescript-eslint';
|
|
3
3
|
|
|
4
|
-
import { DATA_FILES, FILES, TEST_FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, DATA_FILES, FILES, TEST_FILES } from '../base.js';
|
|
5
5
|
import { TS_RULES } from '../rules/typescript.js';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Правила TypeScript без анализа типов.
|
|
9
|
+
*
|
|
10
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
11
|
+
*
|
|
12
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
13
|
+
*
|
|
14
|
+
* @see [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint)
|
|
15
|
+
*/
|
|
16
|
+
export const typescript = createPlugin(() =>
|
|
17
|
+
defineConfig([
|
|
18
|
+
// `plugin.configs.strict`/`stylistic` contain blocks without a `files` key,
|
|
19
|
+
// so they would also land on data files that are not JavaScript at all.
|
|
20
|
+
...[...plugin.configs.strict, ...plugin.configs.stylistic].map(
|
|
21
|
+
(config) => ({
|
|
22
|
+
...config,
|
|
23
|
+
ignores: [...(config.ignores ?? []), ...DATA_FILES],
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
])
|
|
27
|
+
{ files: FILES, rules: TS_RULES },
|
|
28
|
+
{
|
|
29
|
+
files: TEST_FILES,
|
|
30
|
+
rules: { '@typescript-eslint/no-empty-function': 'off' },
|
|
31
|
+
},
|
|
32
|
+
]),
|
|
33
|
+
);
|
package/plugins/unicorn.js
CHANGED
|
@@ -1,72 +1,84 @@
|
|
|
1
1
|
import plugin from 'eslint-plugin-unicorn';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
import { DTS_FILES, FILES, VUE_FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, DTS_FILES, FILES, VUE_FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила unicorn.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn)
|
|
14
|
+
*/
|
|
15
|
+
export const unicorn = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
{ ...plugin.configs.recommended, files: FILES },
|
|
18
|
+
{
|
|
19
|
+
files: FILES,
|
|
20
|
+
rules: {
|
|
21
|
+
'unicorn/comment-content': ['warn'],
|
|
22
|
+
'unicorn/consistent-function-scoping': [
|
|
23
|
+
'error',
|
|
24
|
+
{ checkArrowFunctions: false },
|
|
25
|
+
],
|
|
26
|
+
'unicorn/consistent-function-style': [
|
|
27
|
+
'error',
|
|
28
|
+
{ default: 'arrow-function' },
|
|
29
|
+
],
|
|
30
|
+
// Explicit: the default happens to be kebab case, but the intent is
|
|
31
|
+
// worth pinning down. Applies to `.vue` components too, which is why
|
|
32
|
+
// `vue/match-component-file-name` is kept in sync with it in `vue.js`.
|
|
33
|
+
'unicorn/filename-case': ['error', { case: 'kebabCase' }],
|
|
34
|
+
'unicorn/iteration-fallback-style': ['error', 'guard'],
|
|
35
|
+
'unicorn/name-replacements': 'off',
|
|
36
|
+
'unicorn/no-array-reduce': ['error', { allowSimpleOperations: true }],
|
|
37
|
+
'unicorn/no-asterisk-prefix-in-documentation-comments': 'off',
|
|
38
|
+
'unicorn/no-empty-file': 'off',
|
|
39
|
+
'unicorn/no-for-each': 'off',
|
|
40
|
+
'unicorn/no-this-outside-of-class': 'off', // used in setters/getters
|
|
41
|
+
'unicorn/no-top-level-side-effects': 'off', // Vue.js specific
|
|
42
|
+
'unicorn/no-unused-properties': 'off', // don't respect local keys
|
|
43
|
+
'unicorn/prefer-dom-node-html-methods': 'off', // Safari not supports setHTML()
|
|
44
|
+
'unicorn/prefer-export-from': ['error', { checkUsedVariables: true }],
|
|
45
|
+
'unicorn/prefer-https': 'off', // SVG need HTTP
|
|
46
|
+
'unicorn/prefer-import-meta-properties': 'warn',
|
|
47
|
+
'unicorn/prefer-iterator-concat': 'off', // ES2026 only
|
|
48
|
+
'unicorn/prefer-json-import': 'warn',
|
|
49
|
+
'unicorn/prefer-module': 'warn',
|
|
50
|
+
'unicorn/prefer-node-protocol': 'warn',
|
|
51
|
+
'unicorn/prefer-temporal': 'off', // ES2026 only
|
|
52
|
+
'unicorn/prefer-type-literal-last': 'off', // perfectionist/sort-intersection-types
|
|
53
|
+
'unicorn/prefer-uint8array-hex': 'warn',
|
|
54
|
+
'unicorn/relative-url-style': ['error', 'always'],
|
|
55
|
+
'unicorn/single-line-block-comment-style': 'off',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{ files: ['**/.*'], rules: { 'unicorn/no-null': 'off' } },
|
|
59
|
+
{ files: DTS_FILES, rules: { 'unicorn/prefer-export-from': 'off' } },
|
|
60
|
+
{
|
|
61
|
+
// `null` is part of the type contract in Vue.js SFC:
|
|
62
|
+
// `ref<Type | null>(null)` is the idiomatic way to declare an initially
|
|
63
|
+
// empty reactive value. Everywhere else `null` remains an error.
|
|
64
|
+
files: VUE_FILES,
|
|
65
|
+
rules: { 'unicorn/no-null': 'off' },
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
files: [
|
|
69
|
+
'**/*.{api,endpoints,fixtures,schemas,service,spec,test}.{js,ts}',
|
|
20
70
|
],
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'unicorn/no-asterisk-prefix-in-documentation-comments': 'off',
|
|
29
|
-
'unicorn/no-empty-file': 'off',
|
|
30
|
-
'unicorn/no-for-each': 'off',
|
|
31
|
-
'unicorn/no-this-outside-of-class': 'off', // used in setters/getters
|
|
32
|
-
'unicorn/no-top-level-side-effects': 'off', // Vue.js specific
|
|
33
|
-
'unicorn/no-unused-properties': 'off', // don't respect local keys
|
|
34
|
-
'unicorn/prefer-dom-node-html-methods': 'off', // Safari not supports setHTML()
|
|
35
|
-
'unicorn/prefer-export-from': ['error', { checkUsedVariables: true }],
|
|
36
|
-
'unicorn/prefer-https': 'off', // SVG need HTTP
|
|
37
|
-
'unicorn/prefer-import-meta-properties': 'warn',
|
|
38
|
-
'unicorn/prefer-iterator-concat': 'off', // ES2026 only
|
|
39
|
-
'unicorn/prefer-json-import': 'warn',
|
|
40
|
-
'unicorn/prefer-module': 'warn',
|
|
41
|
-
'unicorn/prefer-node-protocol': 'warn',
|
|
42
|
-
'unicorn/prefer-temporal': 'off', // ES2026 only
|
|
43
|
-
'unicorn/prefer-type-literal-last': 'off', // perfectionist/sort-intersection-types
|
|
44
|
-
'unicorn/prefer-uint8array-hex': 'warn',
|
|
45
|
-
'unicorn/relative-url-style': ['error', 'always'],
|
|
46
|
-
'unicorn/single-line-block-comment-style': 'off',
|
|
71
|
+
rules: {
|
|
72
|
+
'unicorn/max-nested-calls': 'off',
|
|
73
|
+
'unicorn/no-keyword-prefix': 'off',
|
|
74
|
+
'unicorn/no-null': 'off',
|
|
75
|
+
'unicorn/no-object-as-default-parameter': 'off',
|
|
76
|
+
'unicorn/no-useless-undefined': 'off',
|
|
77
|
+
},
|
|
47
78
|
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
// `null` is part of the type contract in Vue.js SFC:
|
|
53
|
-
// `ref<Type | null>(null)` is the idiomatic way to declare an initially
|
|
54
|
-
// empty reactive value. Everywhere else `null` remains an error.
|
|
55
|
-
files: VUE_FILES,
|
|
56
|
-
rules: { 'unicorn/no-null': 'off' },
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
files: ['**/*.{api,endpoints,fixtures,schemas,service,spec,test}.{js,ts}'],
|
|
60
|
-
rules: {
|
|
61
|
-
'unicorn/max-nested-calls': 'off',
|
|
62
|
-
'unicorn/no-keyword-prefix': 'off',
|
|
63
|
-
'unicorn/no-null': 'off',
|
|
64
|
-
'unicorn/no-object-as-default-parameter': 'off',
|
|
65
|
-
'unicorn/no-useless-undefined': 'off',
|
|
79
|
+
{
|
|
80
|
+
files: ['**/temp/**/*.vue'],
|
|
81
|
+
rules: { 'unicorn/name-replacements': 'off' },
|
|
66
82
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
files: ['**/temp/**/*.vue'],
|
|
70
|
-
rules: { 'unicorn/name-replacements': 'off' },
|
|
71
|
-
},
|
|
72
|
-
]);
|
|
83
|
+
]),
|
|
84
|
+
);
|
package/plugins/unocss.js
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import plugin from '@unocss/eslint-config/flat';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
import { FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила для UnoCSS.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [@unocss/eslint-config](https://unocss.dev/integrations/eslint)
|
|
14
|
+
*/
|
|
15
|
+
export const unocss = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
{ files: FILES, ...plugin },
|
|
18
|
+
{ files: FILES, rules: { 'unocss/order-attributify': 'off' } },
|
|
19
|
+
]),
|
|
20
|
+
);
|
package/plugins/vitest.js
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import plugin from '@vitest/eslint-plugin';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
import { TEST_FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, TEST_FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила для тестов Vitest.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest)
|
|
14
|
+
*/
|
|
15
|
+
export const vitest = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
{
|
|
18
|
+
files: TEST_FILES,
|
|
19
|
+
plugins: { vitest: plugin },
|
|
20
|
+
rules: {
|
|
21
|
+
...plugin.configs.recommended.rules,
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
'vitest/no-conditional-in-test': 'off',
|
|
24
|
+
'vitest/no-conditional-tests': 'off',
|
|
25
|
+
'vitest/no-hooks': 'off',
|
|
26
|
+
'vitest/require-to-throw-message': 'off',
|
|
27
|
+
},
|
|
18
28
|
},
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
]),
|
|
30
|
+
);
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import plugin from 'eslint-plugin-vuejs-accessibility';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
export const vueAccessibility = defineConfig([
|
|
6
|
-
...plugin.configs['flat/recommended'],
|
|
4
|
+
import { createPlugin, VUE_FILES } from '../base.js';
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила доступности Vue.js-компонентов.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [eslint-plugin-vuejs-accessibility](https://vue-a11y.github.io/eslint-plugin-vuejs-accessibility/)
|
|
14
|
+
*/
|
|
15
|
+
export const vueAccessibility = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
...plugin.configs['flat/recommended'],
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
files: VUE_FILES,
|
|
21
|
+
rules: {
|
|
22
|
+
'vuejs-accessibility/label-has-for': [
|
|
23
|
+
'warn',
|
|
24
|
+
{ allowChildren: true, required: { some: ['nesting', 'id'] } },
|
|
25
|
+
],
|
|
26
|
+
'vuejs-accessibility/no-autofocus': ['warn', { ignoreNonDOM: true }],
|
|
27
|
+
},
|
|
16
28
|
},
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
]),
|
|
30
|
+
);
|
package/plugins/vue-i18n.js
CHANGED
|
@@ -1,39 +1,49 @@
|
|
|
1
1
|
import plugin from '@intlify/eslint-plugin-vue-i18n';
|
|
2
2
|
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
|
-
import { DATA_FILES } from '../base.js';
|
|
4
|
+
import { createPlugin, DATA_FILES, VUE_FILES } from '../base.js';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Правила для Vue.js I18n.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('eslint').Linter.Config} [options] - Дополнительные flat-опции
|
|
10
|
+
*
|
|
11
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
12
|
+
*
|
|
13
|
+
* @see [eslint-plugin-vue-i18n](https://eslint-plugin-vue-i18n.intlify.dev/)
|
|
14
|
+
*/
|
|
15
|
+
export const vueI18n = createPlugin(() =>
|
|
16
|
+
defineConfig([
|
|
17
|
+
...plugin.configs['flat/recommended'].map((config) => ({
|
|
18
|
+
...config,
|
|
19
|
+
ignores: [...(config.ignores ?? []), ...DATA_FILES],
|
|
20
|
+
})),
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
{
|
|
23
|
+
files: VUE_FILES,
|
|
24
|
+
rules: {
|
|
25
|
+
'@intlify/vue-i18n/key-format-style': [
|
|
26
|
+
'error',
|
|
27
|
+
'snake_case',
|
|
28
|
+
{ allowArray: false },
|
|
29
|
+
],
|
|
30
|
+
'@intlify/vue-i18n/no-duplicate-keys-in-locale': [
|
|
31
|
+
'error',
|
|
32
|
+
{ ignoreI18nBlock: false },
|
|
33
|
+
],
|
|
34
|
+
'@intlify/vue-i18n/no-dynamic-keys': 'warn',
|
|
35
|
+
'@intlify/vue-i18n/no-raw-text': 'off',
|
|
36
|
+
'@intlify/vue-i18n/no-unused-keys': 'warn',
|
|
37
|
+
'@intlify/vue-i18n/prefer-sfc-lang-attr': 'error',
|
|
38
|
+
},
|
|
29
39
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
{
|
|
41
|
+
settings: {
|
|
42
|
+
'vue-i18n': {
|
|
43
|
+
localeDir: './**/locales/*.{json,json5,yaml,yml}',
|
|
44
|
+
messageSyntaxVersion: '^9.0.0',
|
|
45
|
+
},
|
|
36
46
|
},
|
|
37
47
|
},
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
]),
|
|
49
|
+
);
|