@alexlit/config-eslint 91.0.0 → 91.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-eslint",
3
- "version": "91.0.0",
3
+ "version": "91.0.2",
4
4
  "private": false,
5
5
  "description": "Eslint config",
6
6
  "keywords": [
@@ -24,6 +24,7 @@
24
24
  "type": "module",
25
25
  "main": "index.js",
26
26
  "files": [
27
+ "plugins",
27
28
  "README.md",
28
29
  "index.js"
29
30
  ],
@@ -0,0 +1,143 @@
1
+ /* eslint-disable sonarjs/no-duplicate-string */
2
+ import plugin from '@eslint/js';
3
+
4
+ /** @see [eslint](https://eslint.org) */
5
+ export const javascript = [
6
+ plugin.configs.recommended,
7
+
8
+ {
9
+ rules: {
10
+ 'class-methods-use-this': 'off',
11
+ curly: 'error',
12
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
13
+ 'grouped-accessor-pairs': ['error', 'getBeforeSet'],
14
+
15
+ 'lines-around-comment': [
16
+ 'warn',
17
+ {
18
+ afterBlockComment: false,
19
+ afterLineComment: false,
20
+
21
+ allowArrayEnd: true,
22
+ allowArrayStart: true,
23
+
24
+ allowBlockEnd: true,
25
+ allowBlockStart: true,
26
+
27
+ allowClassEnd: true,
28
+ allowClassStart: true,
29
+
30
+ allowObjectEnd: true,
31
+ allowObjectStart: true,
32
+
33
+ beforeBlockComment: true,
34
+ beforeLineComment: false,
35
+ },
36
+ ],
37
+
38
+ 'no-console': 'warn',
39
+
40
+ 'no-implicit-coercion': 'error',
41
+
42
+ 'no-param-reassign': ['error', { props: false }],
43
+
44
+ 'no-restricted-exports': [
45
+ 'error',
46
+ {
47
+ restrictedNamedExports: [
48
+ 'then', // this will cause tons of confusion when your module is dynamically `import()`ed, and will break in most node ESM versions
49
+ ],
50
+ },
51
+ ],
52
+
53
+ 'no-restricted-imports': [
54
+ 'error',
55
+ {
56
+ patterns: [
57
+ {
58
+ group: ['.', '..', '*/..'],
59
+ message: 'Use absolute path instead',
60
+ },
61
+ {
62
+ group: ['@/', '@@/'],
63
+ message: 'Use "~" instead of "@"',
64
+ },
65
+ ],
66
+ },
67
+ ],
68
+
69
+ 'no-return-await': 'off',
70
+ 'no-shadow': 'off',
71
+ 'no-underscore-dangle': 'off',
72
+ 'no-unused-vars': 'off',
73
+ 'no-use-before-define': 'off',
74
+ 'nonblock-statement-body-position': ['error', 'below'],
75
+ 'padding-line-between-statements': [
76
+ 'warn',
77
+ // always
78
+ { blankLine: 'always', next: '*', prev: 'block-like' },
79
+ { blankLine: 'always', next: '*', prev: 'case' },
80
+ { blankLine: 'always', next: '*', prev: 'cjs-export' },
81
+ { blankLine: 'always', next: '*', prev: 'cjs-import' },
82
+ { blankLine: 'always', next: '*', prev: 'class' },
83
+ { blankLine: 'always', next: '*', prev: 'default' },
84
+ { blankLine: 'always', next: '*', prev: 'directive' },
85
+ { blankLine: 'always', next: '*', prev: 'expression' },
86
+ { blankLine: 'always', next: '*', prev: 'iife' },
87
+ { blankLine: 'always', next: '*', prev: 'multiline-block-like' },
88
+ { blankLine: 'always', next: '*', prev: 'multiline-const' },
89
+ { blankLine: 'always', next: '*', prev: 'multiline-expression' },
90
+ { blankLine: 'always', next: '*', prev: 'multiline-let' },
91
+ { blankLine: 'always', next: '*', prev: 'multiline-var' },
92
+ { blankLine: 'always', next: '*', prev: 'singleline-const' },
93
+ { blankLine: 'always', next: '*', prev: 'singleline-let' },
94
+ { blankLine: 'always', next: '*', prev: 'singleline-var' },
95
+ { blankLine: 'always', next: 'block-like', prev: '*' },
96
+ { blankLine: 'always', next: 'cjs-export', prev: '*' },
97
+ { blankLine: 'always', next: 'cjs-import', prev: '*' },
98
+ { blankLine: 'always', next: 'class', prev: '*' },
99
+ { blankLine: 'always', next: 'expression', prev: '*' },
100
+ { blankLine: 'always', next: 'function', prev: '*' },
101
+ { blankLine: 'always', next: 'iife', prev: '*' },
102
+ { blankLine: 'always', next: 'multiline-block-like', prev: '*' },
103
+ { blankLine: 'always', next: 'multiline-const', prev: '*' },
104
+ { blankLine: 'always', next: 'multiline-expression', prev: '*' },
105
+ { blankLine: 'always', next: 'multiline-let', prev: '*' },
106
+ { blankLine: 'always', next: 'multiline-var', prev: '*' },
107
+ { blankLine: 'always', next: 'return', prev: '*' },
108
+ { blankLine: 'always', next: 'switch', prev: '*' },
109
+ // any
110
+ { blankLine: 'any', next: 'expression', prev: 'expression' },
111
+ {
112
+ blankLine: 'any',
113
+ next: 'singleline-const',
114
+ prev: 'singleline-const',
115
+ },
116
+ { blankLine: 'any', next: 'singleline-let', prev: 'singleline-let' },
117
+ { blankLine: 'any', next: 'singleline-var', prev: 'singleline-var' },
118
+ // never
119
+ { blankLine: 'never', next: 'cjs-export', prev: 'cjs-export' },
120
+ { blankLine: 'never', next: 'cjs-import', prev: 'cjs-import' },
121
+ { blankLine: 'never', next: 'directive', prev: 'directive' },
122
+ ],
123
+
124
+ quotes: ['error', 'single'],
125
+ 'require-await': 'off',
126
+
127
+ 'sort-imports': [
128
+ 'warn',
129
+ {
130
+ allowSeparatedGroups: true,
131
+ ignoreCase: true,
132
+ ignoreDeclarationSort: true,
133
+ ignoreMemberSort: false,
134
+ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
135
+ },
136
+ ],
137
+
138
+ 'sort-keys': 'off',
139
+
140
+ 'sort-vars': 'warn',
141
+ },
142
+ },
143
+ ];
@@ -0,0 +1,34 @@
1
+ import plugin from 'eslint-plugin-jsdoc';
2
+
3
+ /** @see [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) */
4
+ export const jsdoc = [
5
+ plugin.configs['flat/recommended'],
6
+ {
7
+ rules: {
8
+ 'jsdoc/no-undefined-types': 'off',
9
+
10
+ 'jsdoc/require-jsdoc': [
11
+ 'warn',
12
+ {
13
+ enableFixer: false,
14
+
15
+ require: {
16
+ ArrowFunctionExpression: false,
17
+ ClassDeclaration: true,
18
+ ClassExpression: false,
19
+ FunctionDeclaration: false,
20
+ FunctionExpression: false,
21
+ MethodDefinition: false,
22
+ },
23
+ },
24
+ ],
25
+
26
+ 'jsdoc/require-param-description': 'off',
27
+ 'jsdoc/require-param-type': 'off',
28
+ 'jsdoc/require-returns': 'off',
29
+ 'jsdoc/require-returns-description': 'off',
30
+ 'jsdoc/require-returns-type': 'off',
31
+ 'jsdoc/tag-lines': 'off',
32
+ },
33
+ },
34
+ ];
@@ -0,0 +1,17 @@
1
+ import plugin from 'eslint-plugin-perfectionist';
2
+
3
+ /** @see [eslint-plugin-perfectionist](https://perfectionist.dev) */
4
+ export const perfectionist = [
5
+ plugin.configs['recommended-natural'],
6
+ {
7
+ rules: {
8
+ 'perfectionist/sort-imports': [
9
+ 'warn',
10
+ {
11
+ internalPattern: ['#**/**', '~/**', '~~/**', '@/**', '@@/**'],
12
+ },
13
+ ],
14
+ 'perfectionist/sort-vue-attributes': 'off',
15
+ },
16
+ },
17
+ ];
@@ -0,0 +1,4 @@
1
+ import plugin from 'eslint-plugin-regexp';
2
+
3
+ /** @see [eslint-plugin-regexp](https://github.com/ota-meshi/eslint-plugin-regexp) */
4
+ export const regexp = [plugin.configs['flat/recommended']];
@@ -0,0 +1,11 @@
1
+ import plugin from 'eslint-plugin-sonarjs';
2
+
3
+ /** @see [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs) */
4
+ export const sonar = [
5
+ plugin.configs.recommended,
6
+ {
7
+ plugins: {
8
+ sonar: plugin,
9
+ },
10
+ },
11
+ ];
@@ -0,0 +1,4 @@
1
+ import plugin from '@tanstack/eslint-plugin-query';
2
+
3
+ /** @see [@tanstack/query](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query) */
4
+ export const tanstackQuery = [...plugin.configs['flat/recommended']];
@@ -0,0 +1,15 @@
1
+ import plugin from 'typescript-eslint';
2
+
3
+ /** @see [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) */
4
+ export const typescript = [
5
+ ...plugin.configs.strict,
6
+ ...plugin.configs.stylistic,
7
+
8
+ {
9
+ languageOptions: {
10
+ parserOptions: {
11
+ project: ['./tsconfig.json'],
12
+ },
13
+ },
14
+ },
15
+ ];
@@ -0,0 +1,53 @@
1
+ import plugin from 'eslint-plugin-unicorn';
2
+
3
+ /** @see [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) */
4
+ export const unicorn = [
5
+ plugin.configs['flat/all'],
6
+ {
7
+ rules: {
8
+ 'unicorn/better-regex': 'off',
9
+ 'unicorn/consistent-destructuring': 'warn',
10
+ 'unicorn/consistent-function-scoping': [
11
+ 'error',
12
+ { checkArrowFunctions: false },
13
+ ],
14
+ 'unicorn/no-array-for-each': 'off',
15
+ 'unicorn/no-array-reduce': ['error', { allowSimpleOperations: true }],
16
+ 'unicorn/no-empty-file': 'off',
17
+ 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
18
+ 'unicorn/prefer-module': 'off',
19
+ 'unicorn/prefer-node-protocol': 'off',
20
+ 'unicorn/prevent-abbreviations': [
21
+ 'warn',
22
+ {
23
+ allowList: {
24
+ args: true,
25
+ attrs: true,
26
+ env: true,
27
+ i18n: true,
28
+ ImportMetaEnv: true,
29
+ params: true,
30
+ ProcessEnv: true,
31
+ Props: true,
32
+ props: true,
33
+ ref: true,
34
+ },
35
+ checkFilenames: false,
36
+ replacements: { index18n: { i18n: true } },
37
+ },
38
+ ],
39
+ },
40
+ },
41
+ {
42
+ files: ['.*'],
43
+ rules: {
44
+ 'unicorn/no-null': 'off',
45
+ },
46
+ },
47
+ {
48
+ files: ['*.d.ts'],
49
+ rules: {
50
+ 'unicorn/prefer-export-from': 'off',
51
+ },
52
+ },
53
+ ];
@@ -0,0 +1,19 @@
1
+ import plugin from 'eslint-plugin-vitest';
2
+
3
+ /** @see [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) */
4
+ export const vitest = [
5
+ {
6
+ files: ['*.{test,spec}.{js,ts}'],
7
+ plugins: {
8
+ vitest: plugin,
9
+ },
10
+ rules: {
11
+ ...plugin.configs.all.rules,
12
+
13
+ 'vitest/no-conditional-in-test': 'off',
14
+ 'vitest/no-conditional-tests': 'off',
15
+ 'vitest/no-hooks': 'off',
16
+ 'vitest/require-to-throw-message': 'off',
17
+ },
18
+ },
19
+ ];
@@ -0,0 +1,22 @@
1
+ import plugin from 'eslint-plugin-vuejs-accessibility';
2
+
3
+ /** @see [eslint-plugin-vuejs-accessibility](https://vue-a11y.github.io/eslint-plugin-vuejs-accessibility/) */
4
+ export const vueAccessibility = [
5
+ ...plugin.configs['flat/recommended'],
6
+ {
7
+ rules: {
8
+ 'vuejs-accessibility/label-has-for': [
9
+ 'warn',
10
+ {
11
+ allowChildren: true,
12
+
13
+ required: {
14
+ some: ['nesting', 'id'],
15
+ },
16
+ },
17
+ ],
18
+
19
+ 'vuejs-accessibility/no-autofocus': ['warn', { ignoreNonDOM: true }],
20
+ },
21
+ },
22
+ ];
@@ -0,0 +1,36 @@
1
+ import plugin from '@intlify/eslint-plugin-vue-i18n';
2
+
3
+ /** @see [eslint-plugin-vue-i18n](https://eslint-plugin-vue-i18n.intlify.dev/) */
4
+ export const vueI18n = [
5
+ ...plugin.configs['flat/recommended'],
6
+ {
7
+ rules: {
8
+ '@intlify/vue-i18n/key-format-style': [
9
+ 'error',
10
+ 'snake_case',
11
+ {
12
+ allowArray: false,
13
+ },
14
+ ],
15
+
16
+ '@intlify/vue-i18n/no-duplicate-keys-in-locale': [
17
+ 'error',
18
+ {
19
+ ignoreI18nBlock: false,
20
+ },
21
+ ],
22
+
23
+ '@intlify/vue-i18n/no-dynamic-keys': 'warn',
24
+ '@intlify/vue-i18n/no-raw-text': 'off',
25
+ '@intlify/vue-i18n/no-unused-keys': 'warn',
26
+ '@intlify/vue-i18n/prefer-sfc-lang-attr': 'error',
27
+ },
28
+
29
+ settings: {
30
+ 'vue-i18n': {
31
+ localeDir: './**/locales/*.{json,json5,yaml,yml}',
32
+ messageSyntaxVersion: '^9.0.0',
33
+ },
34
+ },
35
+ },
36
+ ];
package/plugins/vue.js ADDED
@@ -0,0 +1,172 @@
1
+ import plugin from 'eslint-plugin-vue';
2
+ import typescript from 'typescript-eslint';
3
+
4
+ /** @see [eslint-plugin-vue](https://eslint.vuejs.org/rules/) */
5
+ export const vue = [
6
+ ...plugin.configs['flat/recommended'],
7
+ {
8
+ files: ['**/*.vue'],
9
+ languageOptions: { parserOptions: { parser: typescript.parser } },
10
+ },
11
+ {
12
+ files: ['**/pages/**/*', '**/layouts/**/*'],
13
+ rules: { 'vue/multi-word-component-names': 'off' },
14
+ },
15
+ {
16
+ rules: {
17
+ 'vue/attributes-order': ['error', { alphabetical: true }],
18
+ 'vue/block-lang': [
19
+ 'error',
20
+ { script: { lang: 'ts' }, style: { lang: 'scss' }, template: {} },
21
+ ],
22
+ 'vue/component-api-style': ['error', ['script-setup']],
23
+ 'vue/component-definition-name-casing': ['error', 'kebab-case'],
24
+ 'vue/component-name-in-template-casing': [
25
+ 'error',
26
+ 'PascalCase',
27
+ { registeredComponentsOnly: false },
28
+ ],
29
+ 'vue/component-options-name-casing': ['error', 'PascalCase'],
30
+ 'vue/component-tags-order': [
31
+ 'error',
32
+ { order: ['script', 'template', 'style'] },
33
+ ],
34
+ 'vue/define-emits-declaration': ['error'],
35
+ 'vue/define-macros-order': [
36
+ 'error',
37
+ {
38
+ defineExposeLast: true,
39
+ order: [
40
+ 'defineOptions',
41
+ 'defineModel',
42
+ 'defineProps',
43
+ 'defineEmits',
44
+ 'defineSlots',
45
+ ],
46
+ },
47
+ ],
48
+ 'vue/define-props-declaration': ['error'],
49
+ 'vue/dot-notation': ['error'],
50
+ 'vue/enforce-style-attribute': ['error', { allow: ['module'] }],
51
+ 'vue/eqeqeq': ['error'],
52
+ 'vue/html-button-has-type': ['error'],
53
+ 'vue/html-comment-content-newline': ['warn'],
54
+ 'vue/html-comment-content-spacing': ['warn'],
55
+ 'vue/html-comment-indent': ['warn'],
56
+ 'vue/html-end-tags': ['error'],
57
+ 'vue/html-self-closing': [
58
+ 'error',
59
+ {
60
+ html: {
61
+ component: 'always',
62
+ normal: 'never',
63
+ void: 'always',
64
+ },
65
+
66
+ math: 'always',
67
+ svg: 'always',
68
+ },
69
+ ],
70
+ 'vue/match-component-file-name': ['error'],
71
+ 'vue/match-component-import-name': ['error'],
72
+ 'vue/max-attributes-per-line': ['error', { singleline: 3 }],
73
+ 'vue/max-lines-per-block': [
74
+ 'warn',
75
+ { script: 500, skipBlankLines: true, style: 500, template: 500 },
76
+ ],
77
+ 'vue/new-line-between-multi-line-property': ['error'],
78
+ 'vue/next-tick-style': ['error', 'promise'],
79
+ 'vue/no-child-content': ['error'],
80
+ 'vue/no-console': ['error'],
81
+ 'vue/no-custom-modifiers-on-v-model': 'off',
82
+ 'vue/no-deprecated-model-definition': ['error'],
83
+ 'vue/no-deprecated-scope-attribute': ['error'],
84
+ 'vue/no-deprecated-slot-attribute': ['error'],
85
+ 'vue/no-deprecated-slot-scope-attribute': ['error'],
86
+ 'vue/no-duplicate-attr-inheritance': ['error'],
87
+ 'vue/no-empty-component-block': ['error'],
88
+ 'vue/no-invalid-model-keys': ['error'],
89
+ 'vue/no-irregular-whitespace': ['error'],
90
+ 'vue/no-loss-of-precision': ['error'],
91
+ 'vue/no-multiple-objects-in-class': ['error'],
92
+ 'vue/no-multiple-template-root': 'off',
93
+ 'vue/no-parsing-error': ['error'],
94
+ 'vue/no-potential-component-option-typo': ['error'],
95
+ 'vue/no-ref-object-reactivity-loss': ['error'],
96
+ 'vue/no-required-prop-with-default': ['error', { autofix: true }],
97
+ 'vue/no-reserved-component-names': [
98
+ 'error',
99
+ {
100
+ disallowVue3BuiltInComponents: true,
101
+ disallowVueBuiltInComponents: true,
102
+ },
103
+ ],
104
+ 'vue/no-restricted-component-names': ['error'],
105
+ 'vue/no-restricted-component-options': ['error'],
106
+ 'vue/no-restricted-props': ['error'],
107
+ 'vue/no-root-v-if': ['error'],
108
+ 'vue/no-setup-props-reactivity-loss': ['error'],
109
+ 'vue/no-static-inline-styles': ['error', { allowBinding: true }],
110
+ 'vue/no-this-in-before-route-enter': ['error'],
111
+ 'vue/no-unsupported-features': ['error'],
112
+ 'vue/no-unused-components': ['error'],
113
+ 'vue/no-unused-emit-declarations': ['error'],
114
+ 'vue/no-unused-refs': 'off',
115
+ 'vue/no-use-computed-property-like-method': ['error'],
116
+ 'vue/no-use-v-else-with-v-for': ['warn'],
117
+ 'vue/no-useless-mustaches': ['error'],
118
+ 'vue/no-useless-template-attributes': ['error'],
119
+ 'vue/no-useless-v-bind': ['error'],
120
+ 'vue/no-v-for-template-key': 'off',
121
+ 'vue/no-v-html': ['error'],
122
+ 'vue/no-v-model-argument': 'off',
123
+ 'vue/no-v-text': ['error'],
124
+ 'vue/no-v-text-v-html-on-component': ['error'],
125
+ 'vue/object-shorthand': ['error'],
126
+ 'vue/padding-line-between-blocks': ['error'],
127
+ 'vue/padding-line-between-tags': [
128
+ 'error',
129
+ [{ blankLine: 'always', next: '*', prev: '*' }],
130
+ ],
131
+ 'vue/padding-lines-in-component-definition': [
132
+ 'error',
133
+ { groupSingleLineProperties: true },
134
+ ],
135
+ 'vue/prefer-define-options': ['error'],
136
+ 'vue/prefer-prop-type-boolean-first': ['error'],
137
+ 'vue/prefer-separate-static-class': ['error'],
138
+ 'vue/prefer-true-attribute-shorthand': ['error'],
139
+ 'vue/quote-props': ['error', 'as-needed'],
140
+ 'vue/require-direct-export': 'off',
141
+ 'vue/require-explicit-slots': ['warn'],
142
+ 'vue/require-macro-variable-name': [
143
+ 'error',
144
+ {
145
+ defineEmits: '$emit',
146
+ defineProps: '$props',
147
+ defineSlots: '$slots',
148
+ useAttrs: '$attrs',
149
+ useSlots: '$slots',
150
+ },
151
+ ],
152
+ 'vue/require-typed-object-prop': ['error'],
153
+ 'vue/require-typed-ref': ['error'],
154
+ 'vue/sort-keys': 'off',
155
+ 'vue/static-class-names-order': ['warn'],
156
+ 'vue/this-in-template': ['error', 'never'],
157
+ 'vue/v-bind-style': [
158
+ 'error',
159
+ 'shorthand',
160
+ { sameNameShorthand: 'always' },
161
+ ],
162
+ 'vue/v-for-delimiter-style': ['error'],
163
+ 'vue/v-if-else-key': ['error'],
164
+ 'vue/v-on-event-hyphenation': ['error'],
165
+ 'vue/v-on-handler-style': ['error', 'inline-function'],
166
+ 'vue/valid-define-options': ['error'],
167
+ 'vue/valid-next-tick': ['error'],
168
+ 'vue/valid-v-bind-sync': ['error'],
169
+ 'vue/valid-v-slot': ['error'],
170
+ },
171
+ },
172
+ ];