@ithinkdt/lint 4.0.0-5 → 4.0.0-9
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 +36 -41
- package/src/base.js +249 -155
- package/src/index.d.ts +8 -0
- package/src/index.js +236 -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 +3 -4
- package/src/tsparser-for-extra-files/transform.js +14 -14
- package/src/tsparser-for-extra-files/ts.js +78 -111
- package/src/tsparser-for-extra-files/utils/resolve-project-list.js +16 -11
- 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,255 @@
|
|
|
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 tsdoc from 'eslint-plugin-tsdoc'
|
|
6
|
+
import processorVueBlocks from 'eslint-processor-vue-blocks'
|
|
4
7
|
|
|
5
|
-
import base,
|
|
8
|
+
import { base, defaultEsFiles, defaultJsFiles, defaultTsFiles, disableTypeChecked, playwright, tsParser, vitest, vue, vueParser } from './base.js'
|
|
9
|
+
import ithinkdt from './rules/index.js'
|
|
6
10
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
export * from './base.js'
|
|
12
|
+
|
|
13
|
+
export default function config({ unocss: withUnoCSS, stylistic: withStylistic, tsconfigRootDir } = {}) {
|
|
14
|
+
const extraFileExtensions = ['.vue']
|
|
15
|
+
|
|
16
|
+
withStylistic = withStylistic === true
|
|
17
|
+
? {
|
|
18
|
+
indent: 4,
|
|
19
|
+
quotes: 'single',
|
|
20
|
+
semi: false,
|
|
21
|
+
jsx: true,
|
|
22
|
+
braceStyle: '1tbs',
|
|
23
|
+
}
|
|
24
|
+
: withStylistic
|
|
25
|
+
|
|
26
|
+
return base({ inCI: !!env.CI && env.CI !== 'false', stylistic: withStylistic })
|
|
27
|
+
.append(
|
|
28
|
+
ithinkdt.configs.recommended,
|
|
29
|
+
vue.configs['flat/recommended'].map((it) => {
|
|
30
|
+
return {
|
|
31
|
+
...it,
|
|
32
|
+
files: defaultEsFiles,
|
|
33
|
+
}
|
|
34
|
+
}),
|
|
35
|
+
{
|
|
36
|
+
files: defaultEsFiles,
|
|
37
|
+
languageOptions: {
|
|
38
|
+
parser: tsParser,
|
|
39
|
+
parserOptions: {
|
|
19
40
|
project: true,
|
|
41
|
+
tsconfigRootDir,
|
|
42
|
+
sourceType: 'module',
|
|
43
|
+
ecmaVersion: 'latest',
|
|
20
44
|
},
|
|
21
45
|
},
|
|
46
|
+
rules: {
|
|
47
|
+
'vue/block-lang': ['warn', {
|
|
48
|
+
script: {
|
|
49
|
+
lang: ['ts', 'tsx'],
|
|
50
|
+
},
|
|
51
|
+
}],
|
|
52
|
+
'vue/block-order': ['error', {
|
|
53
|
+
order: ['script', 'template', 'style'],
|
|
54
|
+
}],
|
|
55
|
+
'vue/component-name-in-template-casing': ['error',
|
|
56
|
+
'PascalCase',
|
|
57
|
+
],
|
|
58
|
+
'vue/component-options-name-casing': ['error',
|
|
59
|
+
'PascalCase',
|
|
60
|
+
],
|
|
61
|
+
// this is deprecated
|
|
62
|
+
'vue/component-tags-order': 'off',
|
|
63
|
+
'vue/custom-event-name-casing': ['error',
|
|
64
|
+
'camelCase',
|
|
65
|
+
],
|
|
66
|
+
'vue/define-macros-order': ['warn', {
|
|
67
|
+
order: ['definePage', 'defineOptions', 'defineModel', 'defineProps', 'defineEmits', 'defineSlots'],
|
|
68
|
+
}],
|
|
69
|
+
'vue/dot-location': ['error',
|
|
70
|
+
'property',
|
|
71
|
+
],
|
|
72
|
+
'vue/dot-notation': ['error', {
|
|
73
|
+
allowKeywords: true,
|
|
74
|
+
}],
|
|
75
|
+
'vue/eqeqeq': ['error',
|
|
76
|
+
'smart',
|
|
77
|
+
],
|
|
78
|
+
'vue/no-mutating-props': ['error', {
|
|
79
|
+
shallowOnly: true,
|
|
80
|
+
}],
|
|
81
|
+
'vue/html-indent': ['error',
|
|
82
|
+
withStylistic?.indent,
|
|
83
|
+
],
|
|
84
|
+
'vue/html-quotes': ['error',
|
|
85
|
+
'double',
|
|
86
|
+
],
|
|
87
|
+
'vue/max-attributes-per-line': 'off',
|
|
88
|
+
'vue/multi-word-component-names': 'off',
|
|
89
|
+
'vue/no-dupe-keys': 'off',
|
|
90
|
+
'vue/no-empty-pattern': 'error',
|
|
91
|
+
'vue/no-irregular-whitespace': 'error',
|
|
92
|
+
'vue/no-loss-of-precision': 'error',
|
|
93
|
+
'vue/no-restricted-syntax': ['error',
|
|
94
|
+
'DebuggerStatement',
|
|
95
|
+
'LabeledStatement',
|
|
96
|
+
'WithStatement',
|
|
97
|
+
],
|
|
98
|
+
'vue/no-restricted-v-bind': ['error',
|
|
99
|
+
'/^v-/',
|
|
100
|
+
],
|
|
101
|
+
'vue/no-setup-props-reactivity-loss': 'off',
|
|
102
|
+
'vue/no-sparse-arrays': 'error',
|
|
103
|
+
'vue/no-unused-refs': 'error',
|
|
104
|
+
'vue/no-useless-v-bind': 'error',
|
|
105
|
+
'vue/no-v-html': 'off',
|
|
106
|
+
'vue/object-shorthand': ['error',
|
|
107
|
+
'always',
|
|
108
|
+
{
|
|
109
|
+
avoidQuotes: true,
|
|
110
|
+
ignoreConstructors: false,
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
'vue/prefer-separate-static-class': 'error',
|
|
114
|
+
'vue/prefer-template': 'error',
|
|
115
|
+
'vue/prop-name-casing': ['error',
|
|
116
|
+
'camelCase',
|
|
117
|
+
],
|
|
118
|
+
'vue/require-default-prop': 'off',
|
|
119
|
+
'vue/require-prop-types': 'off',
|
|
120
|
+
'vue/space-infix-ops': 'error',
|
|
121
|
+
'vue/space-unary-ops': ['error', {
|
|
122
|
+
nonwords: false,
|
|
123
|
+
words: true,
|
|
124
|
+
}],
|
|
125
|
+
'vue/array-bracket-spacing': ['error',
|
|
126
|
+
'never',
|
|
127
|
+
],
|
|
128
|
+
'vue/arrow-spacing': ['error', {
|
|
129
|
+
after: true,
|
|
130
|
+
before: true,
|
|
131
|
+
}],
|
|
132
|
+
'vue/block-spacing': ['error',
|
|
133
|
+
'always',
|
|
134
|
+
],
|
|
135
|
+
'vue/block-tag-newline': ['error', {
|
|
136
|
+
multiline: 'always',
|
|
137
|
+
singleline: 'always',
|
|
138
|
+
}],
|
|
139
|
+
'vue/brace-style': ['error',
|
|
140
|
+
'stroustrup',
|
|
141
|
+
{ allowSingleLine: true },
|
|
142
|
+
],
|
|
143
|
+
'vue/comma-dangle': ['error',
|
|
144
|
+
'always-multiline',
|
|
145
|
+
],
|
|
146
|
+
'vue/comma-spacing': ['error', {
|
|
147
|
+
after: true,
|
|
148
|
+
before: false,
|
|
149
|
+
}],
|
|
150
|
+
'vue/comma-style': ['error',
|
|
151
|
+
'last',
|
|
152
|
+
],
|
|
153
|
+
'vue/html-comment-content-spacing': ['error',
|
|
154
|
+
'always',
|
|
155
|
+
{ exceptions: ['-'] },
|
|
156
|
+
],
|
|
157
|
+
'vue/key-spacing': ['error', {
|
|
158
|
+
afterColon: true,
|
|
159
|
+
beforeColon: false,
|
|
160
|
+
}],
|
|
161
|
+
'vue/keyword-spacing': ['error', {
|
|
162
|
+
after: true,
|
|
163
|
+
before: true,
|
|
164
|
+
}],
|
|
165
|
+
'vue/object-curly-newline': 'off',
|
|
166
|
+
'vue/object-curly-spacing': ['error',
|
|
167
|
+
'always',
|
|
168
|
+
],
|
|
169
|
+
'vue/object-property-newline': ['error', {
|
|
170
|
+
allowAllPropertiesOnSameLine: true,
|
|
171
|
+
}],
|
|
172
|
+
'vue/operator-linebreak': ['error',
|
|
173
|
+
'before',
|
|
174
|
+
],
|
|
175
|
+
'vue/padding-line-between-blocks': ['error',
|
|
176
|
+
'always',
|
|
177
|
+
],
|
|
178
|
+
'vue/quote-props': ['error',
|
|
179
|
+
'consistent-as-needed',
|
|
180
|
+
],
|
|
181
|
+
'vue/space-in-parens': ['error',
|
|
182
|
+
'never',
|
|
183
|
+
],
|
|
184
|
+
'vue/template-curly-spacing': 'error',
|
|
185
|
+
'vue/singleline-html-element-content-newline': ['warn', {
|
|
186
|
+
ignoreWhenNoAttributes: true,
|
|
187
|
+
ignoreWhenEmpty: true,
|
|
188
|
+
}],
|
|
189
|
+
},
|
|
22
190
|
},
|
|
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
191
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
sourceType: 'module',
|
|
75
|
-
ecmaVersion: 'latest',
|
|
76
|
-
project: true,
|
|
192
|
+
{
|
|
193
|
+
files: [...defaultJsFiles, ...defaultTsFiles],
|
|
194
|
+
rules: {
|
|
195
|
+
'vue/one-component-per-file': 'off',
|
|
77
196
|
},
|
|
78
197
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
198
|
+
|
|
199
|
+
{
|
|
200
|
+
files: ['**/*.vue'],
|
|
201
|
+
processor: mergeProcessors([
|
|
202
|
+
vue.processors['vue'],
|
|
203
|
+
processorVueBlocks({
|
|
204
|
+
blocks: {
|
|
205
|
+
styles: true,
|
|
206
|
+
customBlocks: false,
|
|
207
|
+
// Usually it's not recommended to lint <script> and <template>
|
|
208
|
+
// As eslint-plugin-vue already provides the support
|
|
209
|
+
script: false,
|
|
210
|
+
template: false,
|
|
211
|
+
},
|
|
212
|
+
}),
|
|
213
|
+
]),
|
|
214
|
+
languageOptions: {
|
|
215
|
+
parser: vueParser,
|
|
216
|
+
parserOptions: {
|
|
217
|
+
project: true,
|
|
218
|
+
extraFileExtensions,
|
|
219
|
+
sourceType: 'module',
|
|
220
|
+
ecmaVersion: 'latest',
|
|
221
|
+
parser: {
|
|
222
|
+
js: 'espree',
|
|
223
|
+
jsx: 'espree',
|
|
224
|
+
ts: tsParser,
|
|
225
|
+
tsx: tsParser,
|
|
226
|
+
},
|
|
92
227
|
},
|
|
93
|
-
|
|
228
|
+
},
|
|
229
|
+
plugins: { tsdoc },
|
|
230
|
+
rules: {
|
|
231
|
+
// 启用 tsdoc 扫描
|
|
232
|
+
'tsdoc/syntax': 'warn',
|
|
233
|
+
/** script setup 不能开启此规则 */
|
|
234
|
+
'import-x/exports-last': 'off',
|
|
235
|
+
// 不允许使用标记为 @deprecated 的代码
|
|
236
|
+
'ts/no-deprecated': 'warn',
|
|
94
237
|
},
|
|
95
238
|
},
|
|
96
|
-
rules: {
|
|
97
|
-
// 启用 tsdoc 扫描
|
|
98
|
-
'tsdoc/syntax': 'warn',
|
|
99
239
|
|
|
100
|
-
|
|
101
|
-
|
|
240
|
+
{
|
|
241
|
+
files: ['**/tests/unit/**'],
|
|
242
|
+
...vitest.configs['recommended'],
|
|
102
243
|
},
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
files: ['tests/unit/**'],
|
|
107
|
-
...vitest.configs['recommended'],
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
files: ['tests/e2e/**'],
|
|
111
|
-
...playwright.configs['flat/recommended'],
|
|
112
|
-
},
|
|
113
244
|
|
|
114
|
-
|
|
245
|
+
{
|
|
246
|
+
files: ['**/tests/e2e/**'],
|
|
247
|
+
...playwright.configs['flat/recommended'],
|
|
248
|
+
},
|
|
115
249
|
|
|
116
|
-
|
|
117
|
-
|
|
250
|
+
withUnoCSS ? unocss : {},
|
|
251
|
+
disableTypeChecked,
|
|
252
|
+
).renamePlugins({
|
|
253
|
+
vitest: 'test',
|
|
254
|
+
})
|
|
118
255
|
}
|
|
@@ -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,12 @@
|
|
|
1
1
|
import { parser as tsEslintParser } from 'typescript-eslint'
|
|
2
2
|
|
|
3
3
|
import { TSServiceManager } from './ts.js'
|
|
4
|
-
|
|
5
4
|
import { getProjectConfigFiles } from './utils/get-project-config-files.js'
|
|
6
5
|
import { resolveProjectList } from './utils/resolve-project-list.js'
|
|
7
6
|
|
|
8
7
|
export const meta = {
|
|
9
8
|
name: 'typescript-eslint-parser-for-extra-files',
|
|
10
|
-
version: '0.
|
|
9
|
+
version: '0.8.0',
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
const DEFAULT_EXTRA_FILE_EXTENSIONS = ['.vue']
|
|
@@ -19,7 +18,7 @@ export function parseForESLint(code, options = {}) {
|
|
|
19
18
|
}
|
|
20
19
|
const extraFileExtensions = options.extraFileExtensions || DEFAULT_EXTRA_FILE_EXTENSIONS
|
|
21
20
|
const programs = []
|
|
22
|
-
for (const option of
|
|
21
|
+
for (const option of _iterateOptions(options)) {
|
|
23
22
|
programs.push(tsServiceManager.getProgram(code, option))
|
|
24
23
|
}
|
|
25
24
|
const filePath = options.filePath
|
|
@@ -32,7 +31,7 @@ export function parseForESLint(code, options = {}) {
|
|
|
32
31
|
return tsEslintParser.parseForESLint(code, parserOptions)
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
function*
|
|
34
|
+
function* _iterateOptions(options) {
|
|
36
35
|
if (!options) {
|
|
37
36
|
throw new Error('`parserOptions` is required.')
|
|
38
37
|
}
|
|
@@ -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
|
+
}
|