@ithinkdt/lint 4.0.0-6 → 4.0.0-700
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 +1 -20
- package/package.json +37 -41
- package/src/base.js +271 -163
- package/src/index.d.ts +8 -0
- package/src/index.js +230 -99
- package/src/rules/index.js +26 -0
- package/src/rules/no-relative-parent-imports.js +54 -0
- package/src/rules/prefer-import-alias.js +66 -0
- package/src/stylelint.d.ts +1 -1
- package/src/stylelint.js +18 -42
- package/src/tsparser-for-extra-files/index.js +6 -5
- package/src/tsparser-for-extra-files/transform.js +14 -14
- package/src/tsparser-for-extra-files/ts.js +81 -113
- package/src/tsparser-for-extra-files/utils/resolve-project-list.js +18 -12
- package/src/prettier-fix-vue.js +0 -54
- package/src/prettier.d.ts +0 -4
- package/src/prettier.js +0 -15
- package/tsconfig.json +0 -14
package/src/index.js
CHANGED
|
@@ -1,118 +1,249 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { env } from 'node:process'
|
|
2
2
|
|
|
3
3
|
import unocss from '@unocss/eslint-config/flat'
|
|
4
|
+
import { mergeProcessors } from 'eslint-merge-processors'
|
|
5
|
+
import processorVueBlocks from 'eslint-processor-vue-blocks'
|
|
4
6
|
|
|
5
|
-
import base,
|
|
7
|
+
import { base, defaultEsFiles, defaultJsFiles, defaultTsFiles, disableTypeChecked, playwright, tsParser, vitest, vue, vueParser } from './base.js'
|
|
8
|
+
import ithinkdt from './rules/index.js'
|
|
6
9
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
export * from './base.js'
|
|
11
|
+
|
|
12
|
+
export default function config({ unocss: withUnoCSS, stylistic: withStylistic, tsconfigRootDir } = {}) {
|
|
13
|
+
const extraFileExtensions = ['.vue']
|
|
14
|
+
|
|
15
|
+
withStylistic = withStylistic === true
|
|
16
|
+
? {
|
|
17
|
+
indent: 4,
|
|
18
|
+
quotes: 'single',
|
|
19
|
+
semi: false,
|
|
20
|
+
jsx: true,
|
|
21
|
+
braceStyle: '1tbs',
|
|
22
|
+
}
|
|
23
|
+
: withStylistic
|
|
24
|
+
|
|
25
|
+
return base({ inCI: !!env.CI && env.CI !== 'false', stylistic: withStylistic })
|
|
26
|
+
.append(
|
|
27
|
+
ithinkdt.configs.recommended,
|
|
28
|
+
vue.configs['flat/recommended'].map((it) => {
|
|
29
|
+
return {
|
|
30
|
+
...it,
|
|
31
|
+
files: defaultEsFiles,
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
{
|
|
35
|
+
files: defaultEsFiles,
|
|
36
|
+
languageOptions: {
|
|
37
|
+
parser: tsParser,
|
|
38
|
+
parserOptions: {
|
|
19
39
|
project: true,
|
|
40
|
+
tsconfigRootDir,
|
|
41
|
+
sourceType: 'module',
|
|
42
|
+
ecmaVersion: 'latest',
|
|
20
43
|
},
|
|
21
44
|
},
|
|
45
|
+
rules: {
|
|
46
|
+
'vue/block-lang': ['warn', {
|
|
47
|
+
script: {
|
|
48
|
+
lang: ['ts', 'tsx'],
|
|
49
|
+
},
|
|
50
|
+
}],
|
|
51
|
+
'vue/block-order': ['error', {
|
|
52
|
+
order: ['script', 'template', 'style'],
|
|
53
|
+
}],
|
|
54
|
+
'vue/component-name-in-template-casing': ['error',
|
|
55
|
+
'PascalCase',
|
|
56
|
+
],
|
|
57
|
+
'vue/component-options-name-casing': ['error',
|
|
58
|
+
'PascalCase',
|
|
59
|
+
],
|
|
60
|
+
// this is deprecated
|
|
61
|
+
'vue/component-tags-order': 'off',
|
|
62
|
+
'vue/custom-event-name-casing': ['error',
|
|
63
|
+
'camelCase',
|
|
64
|
+
],
|
|
65
|
+
'vue/define-macros-order': ['warn', {
|
|
66
|
+
order: ['definePage', 'defineOptions', 'defineModel', 'defineProps', 'defineEmits', 'defineSlots'],
|
|
67
|
+
}],
|
|
68
|
+
'vue/dot-location': ['error',
|
|
69
|
+
'property',
|
|
70
|
+
],
|
|
71
|
+
'vue/dot-notation': ['error', {
|
|
72
|
+
allowKeywords: true,
|
|
73
|
+
}],
|
|
74
|
+
'vue/eqeqeq': ['error',
|
|
75
|
+
'smart',
|
|
76
|
+
],
|
|
77
|
+
'vue/no-mutating-props': ['error', {
|
|
78
|
+
shallowOnly: true,
|
|
79
|
+
}],
|
|
80
|
+
'vue/html-indent': ['error',
|
|
81
|
+
withStylistic?.indent,
|
|
82
|
+
],
|
|
83
|
+
'vue/html-quotes': ['error',
|
|
84
|
+
'double',
|
|
85
|
+
],
|
|
86
|
+
'vue/max-attributes-per-line': 'off',
|
|
87
|
+
'vue/multi-word-component-names': 'off',
|
|
88
|
+
'vue/no-dupe-keys': 'off',
|
|
89
|
+
'vue/no-empty-pattern': 'error',
|
|
90
|
+
'vue/no-irregular-whitespace': 'error',
|
|
91
|
+
'vue/no-loss-of-precision': 'error',
|
|
92
|
+
'vue/no-restricted-syntax': ['error',
|
|
93
|
+
'DebuggerStatement',
|
|
94
|
+
'LabeledStatement',
|
|
95
|
+
'WithStatement',
|
|
96
|
+
],
|
|
97
|
+
'vue/no-restricted-v-bind': ['error',
|
|
98
|
+
'/^v-/',
|
|
99
|
+
],
|
|
100
|
+
'vue/no-setup-props-reactivity-loss': 'off',
|
|
101
|
+
'vue/no-sparse-arrays': 'error',
|
|
102
|
+
'vue/no-unused-refs': 'error',
|
|
103
|
+
'vue/no-useless-v-bind': 'error',
|
|
104
|
+
'vue/no-v-html': 'off',
|
|
105
|
+
'vue/object-shorthand': ['error',
|
|
106
|
+
'always',
|
|
107
|
+
{
|
|
108
|
+
avoidQuotes: true,
|
|
109
|
+
ignoreConstructors: false,
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
'vue/prefer-separate-static-class': 'error',
|
|
113
|
+
'vue/prefer-template': 'error',
|
|
114
|
+
'vue/prop-name-casing': ['error',
|
|
115
|
+
'camelCase',
|
|
116
|
+
],
|
|
117
|
+
'vue/require-default-prop': 'off',
|
|
118
|
+
'vue/require-prop-types': 'off',
|
|
119
|
+
'vue/space-infix-ops': 'error',
|
|
120
|
+
'vue/space-unary-ops': ['error', {
|
|
121
|
+
nonwords: false,
|
|
122
|
+
words: true,
|
|
123
|
+
}],
|
|
124
|
+
'vue/array-bracket-spacing': ['error',
|
|
125
|
+
'never',
|
|
126
|
+
],
|
|
127
|
+
'vue/arrow-spacing': ['error', {
|
|
128
|
+
after: true,
|
|
129
|
+
before: true,
|
|
130
|
+
}],
|
|
131
|
+
'vue/block-spacing': ['error',
|
|
132
|
+
'always',
|
|
133
|
+
],
|
|
134
|
+
'vue/block-tag-newline': ['error', {
|
|
135
|
+
multiline: 'always',
|
|
136
|
+
singleline: 'always',
|
|
137
|
+
}],
|
|
138
|
+
'vue/brace-style': ['error',
|
|
139
|
+
'stroustrup',
|
|
140
|
+
{ allowSingleLine: true },
|
|
141
|
+
],
|
|
142
|
+
'vue/comma-dangle': ['error',
|
|
143
|
+
'always-multiline',
|
|
144
|
+
],
|
|
145
|
+
'vue/comma-spacing': ['error', {
|
|
146
|
+
after: true,
|
|
147
|
+
before: false,
|
|
148
|
+
}],
|
|
149
|
+
'vue/comma-style': ['error',
|
|
150
|
+
'last',
|
|
151
|
+
],
|
|
152
|
+
'vue/html-comment-content-spacing': ['error',
|
|
153
|
+
'always',
|
|
154
|
+
{ exceptions: ['-'] },
|
|
155
|
+
],
|
|
156
|
+
'vue/key-spacing': ['error', {
|
|
157
|
+
afterColon: true,
|
|
158
|
+
beforeColon: false,
|
|
159
|
+
}],
|
|
160
|
+
'vue/keyword-spacing': ['error', {
|
|
161
|
+
after: true,
|
|
162
|
+
before: true,
|
|
163
|
+
}],
|
|
164
|
+
'vue/object-curly-newline': 'off',
|
|
165
|
+
'vue/object-curly-spacing': ['error',
|
|
166
|
+
'always',
|
|
167
|
+
],
|
|
168
|
+
'vue/object-property-newline': ['error', {
|
|
169
|
+
allowAllPropertiesOnSameLine: true,
|
|
170
|
+
}],
|
|
171
|
+
'vue/operator-linebreak': ['error',
|
|
172
|
+
'before',
|
|
173
|
+
],
|
|
174
|
+
'vue/padding-line-between-blocks': ['error',
|
|
175
|
+
'always',
|
|
176
|
+
],
|
|
177
|
+
'vue/quote-props': ['error',
|
|
178
|
+
'consistent-as-needed',
|
|
179
|
+
],
|
|
180
|
+
'vue/space-in-parens': ['error',
|
|
181
|
+
'never',
|
|
182
|
+
],
|
|
183
|
+
'vue/template-curly-spacing': 'error',
|
|
184
|
+
'vue/singleline-html-element-content-newline': ['warn', {
|
|
185
|
+
ignoreWhenNoAttributes: true,
|
|
186
|
+
ignoreWhenEmpty: true,
|
|
187
|
+
}],
|
|
188
|
+
},
|
|
22
189
|
},
|
|
23
|
-
rules: {
|
|
24
|
-
// 将 禁止使用null文字 设为警告
|
|
25
|
-
'unicorn/no-null': 'warn',
|
|
26
|
-
|
|
27
|
-
// 关闭 vue 代码风格规则
|
|
28
|
-
'vue/html-self-closing': 'off',
|
|
29
|
-
'vue/max-len': 'off',
|
|
30
|
-
'vue/array-bracket-newline': 'off',
|
|
31
|
-
'vue/array-bracket-spacing': 'off',
|
|
32
|
-
'vue/array-element-newline': 'off',
|
|
33
|
-
'vue/arrow-spacing': 'off',
|
|
34
|
-
'vue/block-spacing': 'off',
|
|
35
|
-
'vue/block-tag-newline': 'off',
|
|
36
|
-
'vue/brace-style': 'off',
|
|
37
|
-
'vue/comma-dangle': 'off',
|
|
38
|
-
'vue/comma-spacing': 'off',
|
|
39
|
-
'vue/comma-style': 'off',
|
|
40
|
-
'vue/dot-location': 'off',
|
|
41
|
-
'vue/func-call-spacing': 'off',
|
|
42
|
-
'vue/html-closing-bracket-newline': 'off',
|
|
43
|
-
'vue/html-closing-bracket-spacing': 'off',
|
|
44
|
-
'vue/html-end-tags': 'off',
|
|
45
|
-
'vue/html-indent': 'off',
|
|
46
|
-
'vue/html-quotes': 'off',
|
|
47
|
-
'vue/key-spacing': 'off',
|
|
48
|
-
'vue/keyword-spacing': 'off',
|
|
49
|
-
'vue/max-attributes-per-line': 'off',
|
|
50
|
-
'vue/multiline-html-element-content-newline': 'off',
|
|
51
|
-
'vue/multiline-ternary': 'off',
|
|
52
|
-
'vue/mustache-interpolation-spacing': 'off',
|
|
53
|
-
'vue/no-extra-parens': 'off',
|
|
54
|
-
'vue/no-multi-spaces': 'off',
|
|
55
|
-
'vue/no-spaces-around-equal-signs-in-attribute': 'off',
|
|
56
|
-
'vue/object-curly-newline': 'off',
|
|
57
|
-
'vue/object-curly-spacing': 'off',
|
|
58
|
-
'vue/object-property-newline': 'off',
|
|
59
|
-
'vue/operator-linebreak': 'off',
|
|
60
|
-
'vue/quote-props': 'off',
|
|
61
|
-
'vue/script-indent': 'off',
|
|
62
|
-
'vue/singleline-html-element-content-newline': 'off',
|
|
63
|
-
'vue/space-in-parens': 'off',
|
|
64
|
-
'vue/space-infix-ops': 'off',
|
|
65
|
-
'vue/space-unary-ops': 'off',
|
|
66
|
-
'vue/template-curly-spacing': 'off',
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
190
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
sourceType: 'module',
|
|
75
|
-
ecmaVersion: 'latest',
|
|
76
|
-
project: true,
|
|
191
|
+
{
|
|
192
|
+
files: [...defaultJsFiles, ...defaultTsFiles],
|
|
193
|
+
rules: {
|
|
194
|
+
'vue/one-component-per-file': 'off',
|
|
77
195
|
},
|
|
78
196
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
197
|
+
|
|
198
|
+
{
|
|
199
|
+
files: ['**/*.vue'],
|
|
200
|
+
processor: mergeProcessors([
|
|
201
|
+
vue.processors['vue'],
|
|
202
|
+
processorVueBlocks({
|
|
203
|
+
blocks: {
|
|
204
|
+
styles: true,
|
|
205
|
+
customBlocks: false,
|
|
206
|
+
// Usually it's not recommended to lint <script> and <template>
|
|
207
|
+
// As eslint-plugin-vue already provides the support
|
|
208
|
+
script: false,
|
|
209
|
+
template: false,
|
|
210
|
+
},
|
|
211
|
+
}),
|
|
212
|
+
]),
|
|
213
|
+
languageOptions: {
|
|
214
|
+
parser: vueParser,
|
|
215
|
+
parserOptions: {
|
|
216
|
+
project: true,
|
|
217
|
+
extraFileExtensions,
|
|
218
|
+
sourceType: 'module',
|
|
219
|
+
ecmaVersion: 'latest',
|
|
220
|
+
parser: {
|
|
221
|
+
js: 'espree',
|
|
222
|
+
jsx: 'espree',
|
|
223
|
+
ts: tsParser,
|
|
224
|
+
tsx: tsParser,
|
|
225
|
+
},
|
|
92
226
|
},
|
|
93
|
-
|
|
227
|
+
},
|
|
228
|
+
rules: {
|
|
229
|
+
/** script setup 不能开启此规则 */
|
|
230
|
+
'import-x/exports-last': 'off',
|
|
94
231
|
},
|
|
95
232
|
},
|
|
96
|
-
rules: {
|
|
97
|
-
// 启用 tsdoc 扫描
|
|
98
|
-
'tsdoc/syntax': 'warn',
|
|
99
233
|
|
|
100
|
-
|
|
101
|
-
|
|
234
|
+
{
|
|
235
|
+
files: ['**/tests/unit/**'],
|
|
236
|
+
...vitest.configs['recommended'],
|
|
102
237
|
},
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
files: ['tests/unit/**'],
|
|
107
|
-
...vitest.configs['recommended'],
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
files: ['tests/e2e/**'],
|
|
111
|
-
...playwright.configs['flat/recommended'],
|
|
112
|
-
},
|
|
113
238
|
|
|
114
|
-
|
|
239
|
+
{
|
|
240
|
+
files: ['**/tests/e2e/**'],
|
|
241
|
+
...playwright.configs['flat/recommended'],
|
|
242
|
+
},
|
|
115
243
|
|
|
116
|
-
|
|
117
|
-
|
|
244
|
+
withUnoCSS ? unocss : {},
|
|
245
|
+
disableTypeChecked,
|
|
246
|
+
).renamePlugins({
|
|
247
|
+
vitest: 'test',
|
|
248
|
+
})
|
|
118
249
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { noRelativeParentImportRule } from './no-relative-parent-imports.js'
|
|
2
|
+
import { preferImportAliasRule } from './prefer-import-alias.js'
|
|
3
|
+
|
|
4
|
+
const rules = {
|
|
5
|
+
'no-relative-parent-imports': noRelativeParentImportRule,
|
|
6
|
+
'prefer-import-alias': preferImportAliasRule,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const configs = {
|
|
10
|
+
recommended: {
|
|
11
|
+
plugins: {
|
|
12
|
+
'@ithinkdt': { rules },
|
|
13
|
+
},
|
|
14
|
+
rules: {
|
|
15
|
+
'@ithinkdt/no-relative-parent-imports': 'warn',
|
|
16
|
+
'@ithinkdt/prefer-import-alias': 'warn',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const plugin = {
|
|
22
|
+
rules,
|
|
23
|
+
configs,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default plugin
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
export const noRelativeParentImportRule = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'suggestion',
|
|
6
|
+
hasSuggestions: true,
|
|
7
|
+
docs: {
|
|
8
|
+
description: 'Suggests import use project path',
|
|
9
|
+
category: 'Suggestions',
|
|
10
|
+
recommended: true,
|
|
11
|
+
suggestion: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
create: (context) => {
|
|
16
|
+
const aliasModuleDeclarations = (node) => {
|
|
17
|
+
const importModuleName = node.source?.value
|
|
18
|
+
if (
|
|
19
|
+
!node.source?.range
|
|
20
|
+
|| typeof importModuleName !== 'string'
|
|
21
|
+
|| importModuleName[0] !== '.'
|
|
22
|
+
|| importModuleName[1] !== '.'
|
|
23
|
+
)
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
const moduleFilename = path
|
|
27
|
+
.resolve(path.dirname(context.filename), importModuleName)
|
|
28
|
+
.slice(context.cwd.length + 1)
|
|
29
|
+
|
|
30
|
+
return context.report({
|
|
31
|
+
node,
|
|
32
|
+
message: `relative parent import not suggested`,
|
|
33
|
+
suggest: [
|
|
34
|
+
{
|
|
35
|
+
desc: `replace '${importModuleName}' with '${moduleFilename}'`,
|
|
36
|
+
fix: (fixer) => {
|
|
37
|
+
return fixer.replaceTextRange(
|
|
38
|
+
[node.source.range[0] + 1, node.source.range[1] - 1],
|
|
39
|
+
moduleFilename,
|
|
40
|
+
)
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
ExportAllDeclaration: aliasModuleDeclarations,
|
|
49
|
+
ExportNamedDeclaration: aliasModuleDeclarations,
|
|
50
|
+
ImportDeclaration: aliasModuleDeclarations,
|
|
51
|
+
ImportExpression: aliasModuleDeclarations,
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const getAliasSuggestion = (importModuleName, range, pathAlias) => {
|
|
2
|
+
if (!range || typeof importModuleName !== 'string' || importModuleName[0] === '.' || importModuleName[0] === '/')
|
|
3
|
+
return
|
|
4
|
+
|
|
5
|
+
let matchedAlias
|
|
6
|
+
for (const alias of pathAlias) {
|
|
7
|
+
if (
|
|
8
|
+
(importModuleName === alias[1] || importModuleName.startsWith(alias[1] + '/'))
|
|
9
|
+
&& (!matchedAlias || matchedAlias.length < alias[0].length)
|
|
10
|
+
) {
|
|
11
|
+
matchedAlias = alias
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (!matchedAlias) return
|
|
15
|
+
|
|
16
|
+
const aliasSuggestion = matchedAlias[0] + importModuleName.slice(matchedAlias[1].length)
|
|
17
|
+
|
|
18
|
+
if (aliasSuggestion) {
|
|
19
|
+
return {
|
|
20
|
+
message: `import ${importModuleName} can be written as ${aliasSuggestion}`,
|
|
21
|
+
suggest: [
|
|
22
|
+
{
|
|
23
|
+
desc: `replace '${importModuleName}' with '${aliasSuggestion}'`,
|
|
24
|
+
fix: (fixer) => {
|
|
25
|
+
return fixer.replaceTextRange([range[0] + 1, range[1] - 1], aliasSuggestion)
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const preferImportAliasRule = {
|
|
34
|
+
meta: {
|
|
35
|
+
type: 'suggestion',
|
|
36
|
+
hasSuggestions: true,
|
|
37
|
+
docs: {
|
|
38
|
+
description: 'Suggests shortest matching alias',
|
|
39
|
+
category: 'Suggestions',
|
|
40
|
+
recommended: true,
|
|
41
|
+
suggestion: true,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
create: (context) => {
|
|
46
|
+
const pathAlias = (context.settings['import/resolver'] ?? context.settings['import-x/resolver'])?.['custom-alias']?.alias
|
|
47
|
+
|
|
48
|
+
if (!pathAlias) {
|
|
49
|
+
return {}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const aliasModuleDeclarations = (node) => {
|
|
53
|
+
const problem = getAliasSuggestion(node.source?.value, node.source?.range, Object.entries(pathAlias))
|
|
54
|
+
if (problem) {
|
|
55
|
+
context.report({ ...problem, node })
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
ExportAllDeclaration: aliasModuleDeclarations,
|
|
61
|
+
ExportNamedDeclaration: aliasModuleDeclarations,
|
|
62
|
+
ImportDeclaration: aliasModuleDeclarations,
|
|
63
|
+
ImportExpression: aliasModuleDeclarations,
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
}
|
package/src/stylelint.d.ts
CHANGED
package/src/stylelint.js
CHANGED
|
@@ -1,49 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import scss from 'stylelint-config-standard-scss'
|
|
1
|
+
import std from 'stylelint-config-standard'
|
|
4
2
|
import vue from 'stylelint-config-standard-vue'
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import postcsshtml from 'postcss-html'
|
|
8
|
-
import postcssscss from 'postcss-scss'
|
|
3
|
+
import order from 'stylelint-order'
|
|
9
4
|
|
|
10
5
|
/**
|
|
11
6
|
* @type {import('stylelint').Config}
|
|
12
7
|
*/
|
|
13
|
-
export default {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
export default function config(config = {}) {
|
|
9
|
+
return {
|
|
10
|
+
extends: [std, vue, config],
|
|
11
|
+
plugins: [...order],
|
|
12
|
+
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
|
|
13
|
+
rules: {
|
|
14
|
+
'selector-class-pattern': [
|
|
15
|
+
/^([a-z][\da-z]*)((-{1,2}|_{1,2})[\da-z]+)*$/,
|
|
16
|
+
{
|
|
17
|
+
message: selector => `Expected class selector "${selector}" to be kebab-case or bem`,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
'custom-property-empty-line-before': [
|
|
21
|
+
'never',
|
|
22
|
+
],
|
|
24
23
|
},
|
|
25
|
-
|
|
26
|
-
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
|
|
27
|
-
rules: {
|
|
28
|
-
'no-descending-specificity': [false],
|
|
29
|
-
'selector-pseudo-element-no-unknown': [
|
|
30
|
-
true,
|
|
31
|
-
{
|
|
32
|
-
ignorePseudoElements: ['v-deep'],
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
'selector-pseudo-class-no-unknown': [
|
|
36
|
-
true,
|
|
37
|
-
{
|
|
38
|
-
ignorePseudoClasses: ['deep'],
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
'selector-class-pattern': [
|
|
43
|
-
/^([a-z][\da-z]*)((-{1,2}|_{1,2})[\da-z]+)*$/,
|
|
44
|
-
{
|
|
45
|
-
message: (selector) => `Expected class selector "${selector}" to be kebab-case or bem`,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
24
|
+
}
|
|
49
25
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { cwd } from 'node:process'
|
|
2
|
+
|
|
1
3
|
import { parser as tsEslintParser } from 'typescript-eslint'
|
|
2
4
|
|
|
3
5
|
import { TSServiceManager } from './ts.js'
|
|
4
|
-
|
|
5
6
|
import { getProjectConfigFiles } from './utils/get-project-config-files.js'
|
|
6
7
|
import { resolveProjectList } from './utils/resolve-project-list.js'
|
|
7
8
|
|
|
8
9
|
export const meta = {
|
|
9
10
|
name: 'typescript-eslint-parser-for-extra-files',
|
|
10
|
-
version: '0.
|
|
11
|
+
version: '0.8.0',
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
const DEFAULT_EXTRA_FILE_EXTENSIONS = ['.vue']
|
|
@@ -19,7 +20,7 @@ export function parseForESLint(code, options = {}) {
|
|
|
19
20
|
}
|
|
20
21
|
const extraFileExtensions = options.extraFileExtensions || DEFAULT_EXTRA_FILE_EXTENSIONS
|
|
21
22
|
const programs = []
|
|
22
|
-
for (const option of
|
|
23
|
+
for (const option of _iterateOptions(options)) {
|
|
23
24
|
programs.push(tsServiceManager.getProgram(code, option))
|
|
24
25
|
}
|
|
25
26
|
const filePath = options.filePath
|
|
@@ -32,7 +33,7 @@ export function parseForESLint(code, options = {}) {
|
|
|
32
33
|
return tsEslintParser.parseForESLint(code, parserOptions)
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
function*
|
|
36
|
+
function* _iterateOptions(options) {
|
|
36
37
|
if (!options) {
|
|
37
38
|
throw new Error('`parserOptions` is required.')
|
|
38
39
|
}
|
|
@@ -42,7 +43,7 @@ function* iterateOptions(options) {
|
|
|
42
43
|
if (!options.project) {
|
|
43
44
|
throw new Error('Specify `parserOptions.project`. Otherwise there is no point in using this parser.')
|
|
44
45
|
}
|
|
45
|
-
const tsconfigRootDir = typeof options.tsconfigRootDir === 'string' ? options.tsconfigRootDir :
|
|
46
|
+
const tsconfigRootDir = typeof options.tsconfigRootDir === 'string' ? options.tsconfigRootDir : cwd()
|
|
46
47
|
|
|
47
48
|
for (const project of resolveProjectList({
|
|
48
49
|
project: getProjectConfigFiles({
|
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { compileScript, parse } from '@vue/compiler-sfc'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const ext = path.extname(context.filePath)
|
|
7
|
-
const transform = ext === '.vue' ? transformForVue : () => code
|
|
8
|
-
try {
|
|
9
|
-
return transform(code, context)
|
|
10
|
-
} catch {
|
|
11
|
-
// ignore
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return code
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function transformForVue(code, context) {
|
|
5
|
+
function _transformForVue(code, context) {
|
|
18
6
|
if (context.current) {
|
|
19
7
|
return code
|
|
20
8
|
}
|
|
@@ -26,3 +14,15 @@ function transformForVue(code, context) {
|
|
|
26
14
|
|
|
27
15
|
return compiled.content
|
|
28
16
|
}
|
|
17
|
+
|
|
18
|
+
export function transformExtraFile(code, context) {
|
|
19
|
+
const ext = path.extname(context.filePath)
|
|
20
|
+
const transform = ext === '.vue' ? _transformForVue : () => code
|
|
21
|
+
try {
|
|
22
|
+
return transform(code, context)
|
|
23
|
+
} catch {
|
|
24
|
+
// ignore
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return code
|
|
28
|
+
}
|