@trigen/oxlint-config 9.2.3 → 10.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/package.json +1 -1
- package/src/plugin/func-style.js +154 -0
- package/src/plugin/index.js +4 -0
- package/src/plugin/member-ordering.js +81 -30
- package/src/plugin/named-export-order.js +249 -0
- package/src/plugin/naming-convention.js +3 -6
- package/src/subconfigs/basic.js +1 -7
- package/src/subconfigs/import.js +11 -0
- package/src/subconfigs/typescript.js +5 -1
- package/src/test.js +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
function isFunctionExpression(node) {
|
|
2
|
+
return node?.type === 'ArrowFunctionExpression'
|
|
3
|
+
|| node?.type === 'FunctionExpression'
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function pushComputedKeys(stack, classBody) {
|
|
7
|
+
classBody.body.forEach((member) => {
|
|
8
|
+
if (member.computed) {
|
|
9
|
+
stack.push(member.key)
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function pushChildren(stack, node) {
|
|
15
|
+
Object.entries(node).forEach(([key, value]) => {
|
|
16
|
+
if (key === 'parent' || typeof value !== 'object' || value === null) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
value.forEach(item => stack.push(item))
|
|
22
|
+
} else {
|
|
23
|
+
stack.push(value)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if a function references `this`, `arguments` or `new.target` from its own scope,
|
|
30
|
+
* so it can't be converted to an arrow function.
|
|
31
|
+
* @param {object} functionNode
|
|
32
|
+
* @returns {boolean} Whether the function uses its own bindings.
|
|
33
|
+
*/
|
|
34
|
+
function usesFunctionBindings(functionNode) {
|
|
35
|
+
const stack = [...functionNode.params, functionNode.body]
|
|
36
|
+
|
|
37
|
+
while (stack.length > 0) {
|
|
38
|
+
const node = stack.pop()
|
|
39
|
+
|
|
40
|
+
if (!node || typeof node.type !== 'string') {
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
switch (node.type) {
|
|
45
|
+
case 'ThisExpression':
|
|
46
|
+
return true
|
|
47
|
+
case 'MetaProperty':
|
|
48
|
+
if (node.meta.name === 'new') {
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
continue
|
|
53
|
+
case 'Identifier':
|
|
54
|
+
if (node.name === 'arguments') {
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
continue
|
|
59
|
+
// nested regular functions and class members rebind `this` and `arguments`
|
|
60
|
+
case 'FunctionDeclaration':
|
|
61
|
+
case 'FunctionExpression':
|
|
62
|
+
continue
|
|
63
|
+
case 'ClassBody':
|
|
64
|
+
pushComputedKeys(stack, node)
|
|
65
|
+
continue
|
|
66
|
+
case 'MemberExpression':
|
|
67
|
+
stack.push(node.object)
|
|
68
|
+
|
|
69
|
+
if (node.computed) {
|
|
70
|
+
stack.push(node.property)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
continue
|
|
74
|
+
case 'Property':
|
|
75
|
+
case 'PropertyDefinition':
|
|
76
|
+
case 'MethodDefinition':
|
|
77
|
+
if (node.computed) {
|
|
78
|
+
stack.push(node.key)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
stack.push(node.value)
|
|
82
|
+
continue
|
|
83
|
+
default:
|
|
84
|
+
pushChildren(stack, node)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function checkDeclarator(context, declarator) {
|
|
92
|
+
if (
|
|
93
|
+
isFunctionExpression(declarator.init)
|
|
94
|
+
&& declarator.id.type === 'Identifier'
|
|
95
|
+
&& !declarator.id.typeAnnotation
|
|
96
|
+
) {
|
|
97
|
+
context.report({
|
|
98
|
+
node: declarator.id,
|
|
99
|
+
message: 'Use a function declaration instead of assigning a function to a constant at the top level.'
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default {
|
|
105
|
+
meta: {
|
|
106
|
+
type: 'suggestion',
|
|
107
|
+
docs: {
|
|
108
|
+
description: 'Enforce function declarations at the top level and arrow functions assigned to constants inside functions.'
|
|
109
|
+
},
|
|
110
|
+
schema: []
|
|
111
|
+
},
|
|
112
|
+
create(context) {
|
|
113
|
+
let depth = 0
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
FunctionDeclaration(node) {
|
|
117
|
+
if (depth > 0 && !node.generator && !usesFunctionBindings(node)) {
|
|
118
|
+
context.report({
|
|
119
|
+
node: node.id ?? node,
|
|
120
|
+
message: 'Use an arrow function assigned to a constant instead of a nested function declaration.'
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
depth++
|
|
125
|
+
},
|
|
126
|
+
'FunctionDeclaration:exit'() {
|
|
127
|
+
depth--
|
|
128
|
+
},
|
|
129
|
+
FunctionExpression() {
|
|
130
|
+
depth++
|
|
131
|
+
},
|
|
132
|
+
'FunctionExpression:exit'() {
|
|
133
|
+
depth--
|
|
134
|
+
},
|
|
135
|
+
ArrowFunctionExpression() {
|
|
136
|
+
depth++
|
|
137
|
+
},
|
|
138
|
+
'ArrowFunctionExpression:exit'() {
|
|
139
|
+
depth--
|
|
140
|
+
},
|
|
141
|
+
StaticBlock() {
|
|
142
|
+
depth++
|
|
143
|
+
},
|
|
144
|
+
'StaticBlock:exit'() {
|
|
145
|
+
depth--
|
|
146
|
+
},
|
|
147
|
+
VariableDeclaration(node) {
|
|
148
|
+
if (depth === 0 && node.kind === 'const') {
|
|
149
|
+
node.declarations.forEach(declarator => checkDeclarator(context, declarator))
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
package/src/plugin/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import extensionsRule from './extensions.js'
|
|
2
|
+
import funcStyleRule from './func-style.js'
|
|
2
3
|
import importOrderRule from './import-order.js'
|
|
3
4
|
import memberOrderingRule from './member-ordering.js'
|
|
5
|
+
import namedExportOrderRule from './named-export-order.js'
|
|
4
6
|
import namedImportOrderRule from './named-import-order.js'
|
|
5
7
|
import namingConventionRule from './naming-convention.js'
|
|
6
8
|
import typeImportStyleRule from './type-import-style.js'
|
|
@@ -11,8 +13,10 @@ export default {
|
|
|
11
13
|
},
|
|
12
14
|
rules: {
|
|
13
15
|
'extensions': extensionsRule,
|
|
16
|
+
'func-style': funcStyleRule,
|
|
14
17
|
'import-order': importOrderRule,
|
|
15
18
|
'member-ordering': memberOrderingRule,
|
|
19
|
+
'named-export-order': namedExportOrderRule,
|
|
16
20
|
'named-import-order': namedImportOrderRule,
|
|
17
21
|
'naming-convention': namingConventionRule,
|
|
18
22
|
'type-import-style': typeImportStyleRule
|
|
@@ -13,11 +13,15 @@ const defaultOrder = [
|
|
|
13
13
|
'private-instance-field',
|
|
14
14
|
'public-abstract-field',
|
|
15
15
|
'protected-abstract-field',
|
|
16
|
+
'field',
|
|
16
17
|
'signature',
|
|
18
|
+
'call-signature',
|
|
17
19
|
'public-constructor',
|
|
18
20
|
'protected-constructor',
|
|
19
21
|
'private-constructor',
|
|
20
|
-
'
|
|
22
|
+
'constructor',
|
|
23
|
+
'instance-method',
|
|
24
|
+
'method'
|
|
21
25
|
]
|
|
22
26
|
|
|
23
27
|
function getDefaultOptions(context) {
|
|
@@ -93,10 +97,43 @@ function getMemberType(member) {
|
|
|
93
97
|
return null
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
function
|
|
97
|
-
const
|
|
100
|
+
function getClassMemberTypes(member) {
|
|
101
|
+
const memberType = getMemberType(member)
|
|
98
102
|
|
|
99
|
-
return
|
|
103
|
+
return memberType === null ? null : [memberType]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getSignatureMemberTypes(member) {
|
|
107
|
+
switch (member.type) {
|
|
108
|
+
case 'TSPropertySignature':
|
|
109
|
+
return member.readonly
|
|
110
|
+
? ['readonly-field', 'field']
|
|
111
|
+
: ['field']
|
|
112
|
+
case 'TSMethodSignature':
|
|
113
|
+
return ['method']
|
|
114
|
+
case 'TSIndexSignature':
|
|
115
|
+
return member.readonly
|
|
116
|
+
? ['readonly-signature', 'signature']
|
|
117
|
+
: ['signature']
|
|
118
|
+
case 'TSConstructSignatureDeclaration':
|
|
119
|
+
return ['constructor']
|
|
120
|
+
case 'TSCallSignatureDeclaration':
|
|
121
|
+
return ['call-signature']
|
|
122
|
+
default:
|
|
123
|
+
return null
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function getRank(candidateTypes, memberTypes) {
|
|
128
|
+
for (const candidateType of candidateTypes) {
|
|
129
|
+
const rank = memberTypes.indexOf(candidateType)
|
|
130
|
+
|
|
131
|
+
if (rank !== -1) {
|
|
132
|
+
return rank
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return -1
|
|
100
137
|
}
|
|
101
138
|
|
|
102
139
|
function getMemberName(member) {
|
|
@@ -125,11 +162,43 @@ function getMemberName(member) {
|
|
|
125
162
|
return member.type
|
|
126
163
|
}
|
|
127
164
|
|
|
165
|
+
function checkMembers(context, memberTypes, members, getCandidateTypes) {
|
|
166
|
+
let previousMember = null
|
|
167
|
+
|
|
168
|
+
for (const member of members) {
|
|
169
|
+
const candidateTypes = getCandidateTypes(member)
|
|
170
|
+
|
|
171
|
+
if (candidateTypes === null) {
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const rank = getRank(candidateTypes, memberTypes)
|
|
176
|
+
|
|
177
|
+
if (rank === -1) {
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (previousMember && previousMember.rank > rank) {
|
|
182
|
+
context.report({
|
|
183
|
+
node: member,
|
|
184
|
+
message: `Member "${getMemberName(member)}" should be declared before "${getMemberName(previousMember.node)}".`
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
previousMember = {
|
|
191
|
+
node: member,
|
|
192
|
+
rank
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
128
197
|
export default {
|
|
129
198
|
meta: {
|
|
130
199
|
type: 'suggestion',
|
|
131
200
|
docs: {
|
|
132
|
-
description: 'Enforce configured class member ordering.'
|
|
201
|
+
description: 'Enforce configured class, interface and type literal member ordering.'
|
|
133
202
|
},
|
|
134
203
|
schema: [
|
|
135
204
|
{
|
|
@@ -160,31 +229,13 @@ export default {
|
|
|
160
229
|
|
|
161
230
|
return {
|
|
162
231
|
ClassBody(node) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const rank = getRank(memberType, memberTypes)
|
|
173
|
-
|
|
174
|
-
if (previousMember && previousMember.rank > rank) {
|
|
175
|
-
context.report({
|
|
176
|
-
node: member,
|
|
177
|
-
message: `Member "${getMemberName(member)}" should be declared before "${getMemberName(previousMember.node)}".`
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
previousMember = {
|
|
184
|
-
node: member,
|
|
185
|
-
rank
|
|
186
|
-
}
|
|
187
|
-
}
|
|
232
|
+
checkMembers(context, memberTypes, node.body, getClassMemberTypes)
|
|
233
|
+
},
|
|
234
|
+
TSInterfaceBody(node) {
|
|
235
|
+
checkMembers(context, memberTypes, node.body, getSignatureMemberTypes)
|
|
236
|
+
},
|
|
237
|
+
TSTypeLiteral(node) {
|
|
238
|
+
checkMembers(context, memberTypes, node.members, getSignatureMemberTypes)
|
|
188
239
|
}
|
|
189
240
|
}
|
|
190
241
|
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
const defaultOptions = {
|
|
2
|
+
typeExports: 'none',
|
|
3
|
+
patterns: []
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function getOptions(context) {
|
|
7
|
+
return {
|
|
8
|
+
...defaultOptions,
|
|
9
|
+
...context.options[0],
|
|
10
|
+
patterns: context.options[0]?.patterns ?? []
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getName(specifier) {
|
|
15
|
+
const exported = specifier.exported ?? specifier.local
|
|
16
|
+
|
|
17
|
+
if (exported.type === 'Identifier') {
|
|
18
|
+
return exported.name
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return String(exported.value)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isTypeSpecifier(node, specifier) {
|
|
25
|
+
return node.exportKind === 'type'
|
|
26
|
+
|| specifier.exportKind === 'type'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getTypeRank(node, specifier, options) {
|
|
30
|
+
if (options.typeExports === 'first') {
|
|
31
|
+
return isTypeSpecifier(node, specifier) ? 0 : 1
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (options.typeExports === 'last') {
|
|
35
|
+
return isTypeSpecifier(node, specifier) ? 1 : 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return 0
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getPatternRank(name, patterns) {
|
|
42
|
+
const normalizedName = name.replace(/^\$+|\$+$/g, '')
|
|
43
|
+
const rank = patterns.findIndex(pattern => new RegExp(pattern).test(
|
|
44
|
+
normalizedName
|
|
45
|
+
))
|
|
46
|
+
|
|
47
|
+
return rank === -1 ? Number.POSITIVE_INFINITY : rank
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getRank(node, specifier, options) {
|
|
51
|
+
const name = getName(specifier)
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
name,
|
|
55
|
+
typeRank: getTypeRank(node, specifier, options),
|
|
56
|
+
patternRank: getPatternRank(name, options.patterns)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function compareRanks(left, right) {
|
|
61
|
+
return left.typeRank - right.typeRank
|
|
62
|
+
|| left.patternRank - right.patternRank
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getItems(node, options) {
|
|
66
|
+
return node.specifiers
|
|
67
|
+
.filter(specifier => specifier.type === 'ExportSpecifier')
|
|
68
|
+
.map((specifier, index) => ({
|
|
69
|
+
index,
|
|
70
|
+
specifier,
|
|
71
|
+
rank: getRank(node, specifier, options)
|
|
72
|
+
}))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function compareItems(left, right) {
|
|
76
|
+
return compareRanks(left.rank, right.rank)
|
|
77
|
+
|| left.index - right.index
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getFirstUnorderedPair(items) {
|
|
81
|
+
for (let index = 1; index < items.length; index++) {
|
|
82
|
+
const previousItem = items[index - 1]
|
|
83
|
+
const item = items[index]
|
|
84
|
+
|
|
85
|
+
if (compareItems(previousItem, item) > 0) {
|
|
86
|
+
return [
|
|
87
|
+
previousItem,
|
|
88
|
+
item
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getLinebreak(text) {
|
|
97
|
+
return text.includes('\r\n') ? '\r\n' : '\n'
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getLineIndent(text, index) {
|
|
101
|
+
const lineStart = text.lastIndexOf('\n', index - 1) + 1
|
|
102
|
+
const indentMatch = /^[ \t]*/.exec(text.slice(lineStart, index))
|
|
103
|
+
|
|
104
|
+
return indentMatch[0]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getBracesRange(node, items, sourceCode) {
|
|
108
|
+
const text = sourceCode.text
|
|
109
|
+
const firstSpecifier = items[0].specifier
|
|
110
|
+
const lastSpecifier = items.at(-1).specifier
|
|
111
|
+
const openingBrace = text.lastIndexOf('{', firstSpecifier.range[0])
|
|
112
|
+
const closingBrace = text.indexOf('}', lastSpecifier.range[1])
|
|
113
|
+
const searchEnd = node.source?.range?.[0] ?? node.range[1]
|
|
114
|
+
|
|
115
|
+
if (
|
|
116
|
+
openingBrace < node.range[0]
|
|
117
|
+
|| closingBrace === -1
|
|
118
|
+
|| closingBrace > searchEnd
|
|
119
|
+
) {
|
|
120
|
+
return null
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return [
|
|
124
|
+
openingBrace + 1,
|
|
125
|
+
closingBrace
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function hasInnerComments(sourceCode, range) {
|
|
130
|
+
return sourceCode.getAllComments().some(comment => comment.range[0] > range[0]
|
|
131
|
+
&& comment.range[1] < range[1])
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function shouldBeMultiline(sourceCode, range, items) {
|
|
135
|
+
return items.length > 1
|
|
136
|
+
&& !sourceCode.text.slice(range[0], range[1]).includes('\n')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function getFixedText(node, items, options, sourceCode, range) {
|
|
140
|
+
const text = sourceCode.text
|
|
141
|
+
const content = text.slice(range[0], range[1])
|
|
142
|
+
const sortedSpecifiers = [...items]
|
|
143
|
+
.sort(compareItems)
|
|
144
|
+
.map(({ specifier }) => sourceCode.getText(specifier))
|
|
145
|
+
|
|
146
|
+
if (!content.includes('\n') && items.length < 2) {
|
|
147
|
+
return ` ${sortedSpecifiers.join(', ')} `
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const linebreak = getLinebreak(text)
|
|
151
|
+
const firstSpecifier = items[0].specifier
|
|
152
|
+
const closingIndent = getLineIndent(text, node.range[0])
|
|
153
|
+
const indent = content.includes('\n')
|
|
154
|
+
? getLineIndent(text, firstSpecifier.range[0])
|
|
155
|
+
: `${closingIndent} `
|
|
156
|
+
|
|
157
|
+
return `${linebreak}${indent}${sortedSpecifiers.join(`,${linebreak}${indent}`)}${linebreak}${closingIndent}`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getMessage(left, right) {
|
|
161
|
+
if (left.rank.typeRank !== right.rank.typeRank) {
|
|
162
|
+
return `Expected ${right.rank.name} to come before ${left.rank.name} because of export kind.`
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (left.rank.patternRank !== right.rank.patternRank) {
|
|
166
|
+
return `Expected ${right.rank.name} to come before ${left.rank.name} because of naming pattern.`
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return `Expected ${right.rank.name} to come before ${left.rank.name}.`
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export default {
|
|
173
|
+
meta: {
|
|
174
|
+
type: 'layout',
|
|
175
|
+
fixable: 'code',
|
|
176
|
+
docs: {
|
|
177
|
+
description: 'Enforce named export specifier order.'
|
|
178
|
+
},
|
|
179
|
+
schema: [
|
|
180
|
+
{
|
|
181
|
+
type: 'object',
|
|
182
|
+
properties: {
|
|
183
|
+
typeExports: {
|
|
184
|
+
enum: [
|
|
185
|
+
'first',
|
|
186
|
+
'last',
|
|
187
|
+
'none'
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
patterns: {
|
|
191
|
+
type: 'array',
|
|
192
|
+
items: {
|
|
193
|
+
type: 'string'
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
additionalProperties: true
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
create(context) {
|
|
202
|
+
const options = getOptions(context)
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
ExportNamedDeclaration(node) {
|
|
206
|
+
const items = getItems(node, options)
|
|
207
|
+
|
|
208
|
+
if (items.length < 2) {
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const unorderedPair = getFirstUnorderedPair(items)
|
|
213
|
+
const sourceCode = context.sourceCode
|
|
214
|
+
const range = getBracesRange(node, items, sourceCode)
|
|
215
|
+
const invalidMultiline = range && shouldBeMultiline(
|
|
216
|
+
sourceCode,
|
|
217
|
+
range,
|
|
218
|
+
items
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if (!unorderedPair && !invalidMultiline) {
|
|
222
|
+
return
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const fix = range && !hasInnerComments(sourceCode, range)
|
|
226
|
+
? fixer => fixer.replaceTextRange(
|
|
227
|
+
range,
|
|
228
|
+
getFixedText(node, items, options, sourceCode, range)
|
|
229
|
+
)
|
|
230
|
+
: null
|
|
231
|
+
const [
|
|
232
|
+
previousItem,
|
|
233
|
+
item
|
|
234
|
+
] = unorderedPair ?? [
|
|
235
|
+
items[0],
|
|
236
|
+
items[1]
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
context.report({
|
|
240
|
+
node: item.specifier,
|
|
241
|
+
message: unorderedPair
|
|
242
|
+
? getMessage(previousItem, item)
|
|
243
|
+
: 'Expected named exports to be multiline.',
|
|
244
|
+
fix
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
@@ -224,8 +224,7 @@ export default {
|
|
|
224
224
|
},
|
|
225
225
|
create(context) {
|
|
226
226
|
const options = context.options
|
|
227
|
-
|
|
228
|
-
function check(name, node, selector, modifiers = []) {
|
|
227
|
+
const check = (name, node, selector, modifiers = []) => {
|
|
229
228
|
const option = getSelectorOptions(options, selector, modifiers)
|
|
230
229
|
|
|
231
230
|
if (!option || isValidName(name, option)) {
|
|
@@ -237,14 +236,12 @@ export default {
|
|
|
237
236
|
message: `Name "${name}" must match one of these formats: ${getExpectedFormats(option.format)}.`
|
|
238
237
|
})
|
|
239
238
|
}
|
|
240
|
-
|
|
241
|
-
function checkPattern(pattern, selector) {
|
|
239
|
+
const checkPattern = (pattern, selector) => {
|
|
242
240
|
for (const item of getIdentifierNames(pattern)) {
|
|
243
241
|
check(item.name, item.node, selector)
|
|
244
242
|
}
|
|
245
243
|
}
|
|
246
|
-
|
|
247
|
-
function checkProperty(node, selector) {
|
|
244
|
+
const checkProperty = (node, selector) => {
|
|
248
245
|
const name = getKeyName(node.key)
|
|
249
246
|
|
|
250
247
|
if (name === null) {
|
package/src/subconfigs/basic.js
CHANGED
|
@@ -223,13 +223,6 @@ export default {
|
|
|
223
223
|
'eslint/prefer-template': 'error',
|
|
224
224
|
'eslint/symbol-description': 'error',
|
|
225
225
|
'eslint/func-names': 'error',
|
|
226
|
-
'eslint/func-style': [
|
|
227
|
-
'error',
|
|
228
|
-
'declaration',
|
|
229
|
-
{
|
|
230
|
-
allowArrowFunctions: true
|
|
231
|
-
}
|
|
232
|
-
],
|
|
233
226
|
'eslint/max-nested-callbacks': ['error', 4],
|
|
234
227
|
'eslint/max-params': ['error', 6],
|
|
235
228
|
'eslint/new-cap': [
|
|
@@ -245,6 +238,7 @@ export default {
|
|
|
245
238
|
'eslint/operator-assignment': ['error', 'always'],
|
|
246
239
|
'eslint/prefer-object-spread': 'error',
|
|
247
240
|
'eslint/unicode-bom': 'error',
|
|
241
|
+
'trigen/func-style': 'error',
|
|
248
242
|
'trigen/naming-convention': [
|
|
249
243
|
'error',
|
|
250
244
|
{
|
package/src/subconfigs/import.js
CHANGED
|
@@ -78,6 +78,17 @@ export default {
|
|
|
78
78
|
'^[a-z][a-zA-Z0-9]*$'
|
|
79
79
|
]
|
|
80
80
|
}
|
|
81
|
+
],
|
|
82
|
+
'trigen/named-export-order': [
|
|
83
|
+
'error',
|
|
84
|
+
{
|
|
85
|
+
typeExports: 'first',
|
|
86
|
+
patterns: [
|
|
87
|
+
'^[A-Z][A-Z0-9_]*$',
|
|
88
|
+
'^[A-Z][a-zA-Z0-9]*$',
|
|
89
|
+
'^[a-z][a-zA-Z0-9]*$'
|
|
90
|
+
]
|
|
91
|
+
}
|
|
81
92
|
]
|
|
82
93
|
}
|
|
83
94
|
}
|
|
@@ -103,11 +103,15 @@ export default {
|
|
|
103
103
|
'private-instance-field',
|
|
104
104
|
'public-abstract-field',
|
|
105
105
|
'protected-abstract-field',
|
|
106
|
+
'field',
|
|
106
107
|
'signature',
|
|
108
|
+
'call-signature',
|
|
107
109
|
'public-constructor',
|
|
108
110
|
'protected-constructor',
|
|
109
111
|
'private-constructor',
|
|
110
|
-
'
|
|
112
|
+
'constructor',
|
|
113
|
+
'instance-method',
|
|
114
|
+
'method'
|
|
111
115
|
]
|
|
112
116
|
}
|
|
113
117
|
}
|
package/src/test.js
CHANGED
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
'typescript/no-unsafe-call': 'off',
|
|
24
24
|
'typescript/no-unsafe-argument': 'off',
|
|
25
25
|
'typescript/no-explicit-any': 'off',
|
|
26
|
+
'typescript/await-thenable': 'off',
|
|
26
27
|
'typescript/no-floating-promises': 'off',
|
|
27
28
|
'trigen/import-order': 'off',
|
|
28
29
|
'eslint/prefer-destructuring': 'off',
|