@trigen/oxlint-config 9.0.2 → 9.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@trigen/oxlint-config",
3
3
  "type": "module",
4
- "version": "9.0.2",
4
+ "version": "9.1.0",
5
5
  "description": "Trigen's Oxlint config.",
6
6
  "author": "dangreen",
7
7
  "license": "MIT",
package/src/module.js CHANGED
@@ -9,13 +9,14 @@ import {
9
9
  } from './subconfigs/files.js'
10
10
 
11
11
  export default {
12
+ jsPlugins: ['@trigen/oxlint-config/plugin'],
12
13
  overrides: [
13
14
  ...bundlerConfig.overrides,
14
15
  {
15
16
  files: not(commonjsFiles),
16
17
  plugins: ['import'],
17
18
  rules: {
18
- 'import/extensions': ['error', 'ignorePackages']
19
+ 'trigen/extensions': ['error', 'ignorePackages']
19
20
  }
20
21
  }
21
22
  ]
@@ -0,0 +1,72 @@
1
+ import { posix as path } from 'node:path'
2
+
3
+ function getOptions(context) {
4
+ return {
5
+ ignorePackages: context.options[0] === 'ignorePackages'
6
+ }
7
+ }
8
+
9
+ function isPackageImport(source) {
10
+ return !source.startsWith('.')
11
+ && !source.startsWith('/')
12
+ }
13
+
14
+ function hasExtension(source) {
15
+ const cleanSource = source.split(/[?#]/)[0]
16
+ const basename = path.basename(cleanSource)
17
+
18
+ return path.extname(basename) !== ''
19
+ }
20
+
21
+ function checkSource(context, options, node) {
22
+ const source = node.source?.value
23
+
24
+ if (typeof source !== 'string') {
25
+ return
26
+ }
27
+
28
+ if (options.ignorePackages && isPackageImport(source)) {
29
+ return
30
+ }
31
+
32
+ if (hasExtension(source)) {
33
+ return
34
+ }
35
+
36
+ context.report({
37
+ node: node.source,
38
+ message: `Missing file extension for "${source}".`
39
+ })
40
+ }
41
+
42
+ export default {
43
+ meta: {
44
+ type: 'problem',
45
+ docs: {
46
+ description: 'Require import and export paths to include any file extension.'
47
+ },
48
+ schema: [
49
+ {
50
+ enum: [
51
+ 'always',
52
+ 'ignorePackages'
53
+ ]
54
+ }
55
+ ]
56
+ },
57
+ create(context) {
58
+ const options = getOptions(context)
59
+
60
+ return {
61
+ ExportAllDeclaration(node) {
62
+ checkSource(context, options, node)
63
+ },
64
+ ExportNamedDeclaration(node) {
65
+ checkSource(context, options, node)
66
+ },
67
+ ImportDeclaration(node) {
68
+ checkSource(context, options, node)
69
+ }
70
+ }
71
+ }
72
+ }
@@ -161,11 +161,13 @@ function getOptions(context) {
161
161
  }
162
162
 
163
163
  function getImportItems(imports, options) {
164
- return imports.map((node, index) => ({
165
- index,
166
- node,
167
- rank: getRank(node, options)
168
- }))
164
+ return imports
165
+ .filter(node => node.specifiers.length > 0)
166
+ .map((node, index) => ({
167
+ index,
168
+ node,
169
+ rank: getRank(node, options)
170
+ }))
169
171
  }
170
172
 
171
173
  function compareImportItems(left, right) {
@@ -189,23 +191,36 @@ function getFirstUnorderedPair(items) {
189
191
  return null
190
192
  }
191
193
 
192
- function hasInvalidNewlines(items, options) {
194
+ function hasBlankLineBetween(sourceCode, left, right) {
195
+ return sourceCode.text
196
+ .slice(left.node.range[1], right.node.range[0])
197
+ .split(/\r?\n/)
198
+ .slice(1, -1)
199
+ .some(line => line.trim() === '')
200
+ }
201
+
202
+ function getInvalidNewlinePair(sourceCode, items, options) {
193
203
  if (options['newlines-between'] === 'ignore') {
194
- return false
204
+ return null
195
205
  }
196
206
 
197
- return items.some((item, index) => {
198
- if (index === 0) {
199
- return false
200
- }
201
-
207
+ for (let index = 1; index < items.length; index++) {
202
208
  const previousItem = items[index - 1]
203
- const hasEmptyLine = item.node.loc.start.line - previousItem.node.loc.end.line > 1
209
+ const item = items[index]
210
+ const hasBlankLine = hasBlankLineBetween(sourceCode, previousItem, item)
211
+ const invalid = options['newlines-between'] === 'never'
212
+ ? hasBlankLine
213
+ : !hasBlankLine
204
214
 
205
- return options['newlines-between'] === 'never'
206
- ? hasEmptyLine
207
- : !hasEmptyLine
208
- })
215
+ if (invalid) {
216
+ return [
217
+ previousItem,
218
+ item
219
+ ]
220
+ }
221
+ }
222
+
223
+ return null
209
224
  }
210
225
 
211
226
  function hasInnerComments(sourceCode, items) {
@@ -216,13 +231,20 @@ function hasInnerComments(sourceCode, items) {
216
231
  && comment.range[1] < lastNode.range[1])
217
232
  }
218
233
 
219
- function hasSideEffectImports(items) {
220
- return items.some(({ node }) => node.specifiers.length === 0)
234
+ function canFix(sourceCode, items) {
235
+ return !hasInnerComments(sourceCode, items)
221
236
  }
222
237
 
223
- function canFix(sourceCode, items) {
224
- return !hasSideEffectImports(items)
225
- && !hasInnerComments(sourceCode, items)
238
+ function hasSkippedImportsBetween(imports, items) {
239
+ const itemNodes = new Set(items.map(({ node }) => node))
240
+ const [
241
+ start,
242
+ end
243
+ ] = getImportBlockRange(items)
244
+
245
+ return imports.some(node => !itemNodes.has(node)
246
+ && node.range[0] > start
247
+ && node.range[1] < end)
226
248
  }
227
249
 
228
250
  function getFixedImportText(sourceCode, items, options) {
@@ -316,21 +338,30 @@ export default {
316
338
 
317
339
  imports.push(node)
318
340
  },
319
- 'Program:exit'(node) {
341
+ 'Program:exit'() {
320
342
  if (imports.length < 2) {
321
343
  return
322
344
  }
323
345
 
324
346
  const sourceCode = context.sourceCode
325
347
  const items = getImportItems(imports, options)
348
+
349
+ if (items.length < 2) {
350
+ return
351
+ }
352
+
353
+ const hasSkippedImports = hasSkippedImportsBetween(imports, items)
326
354
  const unorderedPair = getFirstUnorderedPair(items)
327
- const invalidNewlines = hasInvalidNewlines(items, options)
355
+ const invalidNewlinePair = hasSkippedImports
356
+ ? null
357
+ : getInvalidNewlinePair(sourceCode, items, options)
328
358
 
329
- if (!unorderedPair && !invalidNewlines) {
359
+ if (!unorderedPair && !invalidNewlinePair) {
330
360
  return
331
361
  }
332
362
 
333
363
  const fix = canFix(sourceCode, items)
364
+ && !hasSkippedImports
334
365
  ? fixer => fixer.replaceTextRange(
335
366
  getImportBlockRange(items),
336
367
  getFixedImportText(sourceCode, items, options)
@@ -339,13 +370,10 @@ export default {
339
370
  const [
340
371
  previousItem,
341
372
  item
342
- ] = unorderedPair ?? [
343
- items[0],
344
- items[1]
345
- ]
373
+ ] = unorderedPair ?? invalidNewlinePair
346
374
 
347
375
  context.report({
348
- node,
376
+ node: item.node,
349
377
  message: unorderedPair
350
378
  ? getMessage(previousItem.rank, item.rank)
351
379
  : 'Import declarations have invalid empty lines.',
@@ -1,16 +1,20 @@
1
+ import extensionsRule from './extensions.js'
1
2
  import importOrderRule from './import-order.js'
2
3
  import memberOrderingRule from './member-ordering.js'
3
4
  import namedImportOrderRule from './named-import-order.js'
4
5
  import namingConventionRule from './naming-convention.js'
6
+ import typeImportStyleRule from './type-import-style.js'
5
7
 
6
8
  export default {
7
9
  meta: {
8
- name: '@trigen/oxlint-config/plugin'
10
+ name: 'trigen'
9
11
  },
10
12
  rules: {
13
+ 'extensions': extensionsRule,
11
14
  'import-order': importOrderRule,
12
15
  'member-ordering': memberOrderingRule,
13
16
  'named-import-order': namedImportOrderRule,
14
- 'naming-convention': namingConventionRule
17
+ 'naming-convention': namingConventionRule,
18
+ 'type-import-style': typeImportStyleRule
15
19
  }
16
20
  }
@@ -39,7 +39,10 @@ function getTypeRank(node, specifier, options) {
39
39
  }
40
40
 
41
41
  function getPatternRank(name, patterns) {
42
- const rank = patterns.findIndex(pattern => new RegExp(pattern).test(name))
42
+ const normalizedName = name.replace(/^\$+|\$+$/g, '')
43
+ const rank = patterns.findIndex(pattern => new RegExp(pattern).test(
44
+ normalizedName
45
+ ))
43
46
 
44
47
  return rank === -1 ? Number.POSITIVE_INFINITY : rank
45
48
  }
@@ -33,11 +33,21 @@ function getSelectorOptions(options, selector, modifiers = []) {
33
33
  }
34
34
 
35
35
  function getNormalizedName(name, option) {
36
+ let normalizedName = name
37
+
36
38
  if (option.leadingUnderscore === 'allow') {
37
- return name.replace(/^_+/, '')
39
+ normalizedName = normalizedName.replace(/^_+/, '')
40
+ }
41
+
42
+ if (option.leadingDollar === 'allow') {
43
+ normalizedName = normalizedName.replace(/^\$+/, '')
44
+ }
45
+
46
+ if (option.trailingDollar === 'allow') {
47
+ normalizedName = normalizedName.replace(/\$+$/, '')
38
48
  }
39
49
 
40
- return name
50
+ return normalizedName
41
51
  }
42
52
 
43
53
  function matchesFormat(name, format) {
@@ -194,6 +204,12 @@ export default {
194
204
  leadingUnderscore: {
195
205
  type: 'string'
196
206
  },
207
+ leadingDollar: {
208
+ type: 'string'
209
+ },
210
+ trailingDollar: {
211
+ type: 'string'
212
+ },
197
213
  modifiers: {
198
214
  type: 'array',
199
215
  items: {
@@ -0,0 +1,166 @@
1
+ function shouldConvert(node) {
2
+ return node.importKind !== 'type'
3
+ && !hasImportAttributes(node)
4
+ && node.specifiers.length > 0
5
+ && node.specifiers.every(specifier => specifier.type === 'ImportSpecifier'
6
+ && specifier.importKind === 'type')
7
+ }
8
+
9
+ function isNamedImport(node) {
10
+ return node.specifiers.length > 0
11
+ && node.specifiers.every(specifier => specifier.type === 'ImportSpecifier')
12
+ }
13
+
14
+ function isTypeImport(node) {
15
+ return node.importKind === 'type'
16
+ || (
17
+ isNamedImport(node)
18
+ && node.specifiers.every(specifier => specifier.importKind === 'type')
19
+ )
20
+ }
21
+
22
+ function hasImportAttributes(node) {
23
+ return (node.attributes?.length ?? 0) > 0
24
+ || (node.assertions?.length ?? 0) > 0
25
+ }
26
+
27
+ function hasCommentsBetween(sourceCode, left, right) {
28
+ return sourceCode.getAllComments().some(comment => comment.range[0] > left.range[1]
29
+ && comment.range[1] < right.range[0])
30
+ }
31
+
32
+ function getLocalName(specifier) {
33
+ return specifier.local?.name ?? null
34
+ }
35
+
36
+ function hasOverlappingLocalNames(left, right) {
37
+ const leftNames = new Set(left.specifiers.map(getLocalName))
38
+
39
+ return right.specifiers.some(specifier => leftNames.has(getLocalName(specifier)))
40
+ }
41
+
42
+ function canMerge(sourceCode, typeNode, valueNode) {
43
+ return typeNode.source.value === valueNode.source.value
44
+ && isTypeImport(typeNode)
45
+ && isNamedImport(typeNode)
46
+ && isNamedImport(valueNode)
47
+ && !isTypeImport(valueNode)
48
+ && !hasImportAttributes(typeNode)
49
+ && !hasImportAttributes(valueNode)
50
+ && !hasOverlappingLocalNames(typeNode, valueNode)
51
+ && !hasCommentsBetween(sourceCode, typeNode, valueNode)
52
+ }
53
+
54
+ function getMergePair(imports, sourceCode) {
55
+ for (let index = 1; index < imports.length; index++) {
56
+ const previousImport = imports[index - 1]
57
+ const importNode = imports[index]
58
+
59
+ if (canMerge(sourceCode, previousImport, importNode)) {
60
+ return [
61
+ previousImport,
62
+ importNode
63
+ ]
64
+ }
65
+ }
66
+
67
+ return null
68
+ }
69
+
70
+ function getConvertNode(imports) {
71
+ return imports.find(shouldConvert)
72
+ }
73
+
74
+ function getTypeSpecifierText(specifier, sourceCode) {
75
+ const text = sourceCode.getText(specifier)
76
+
77
+ return text.startsWith('type ')
78
+ ? text
79
+ : `type ${text}`
80
+ }
81
+
82
+ function getMergedText(typeNode, valueNode, sourceCode) {
83
+ const typeSpecifiers = typeNode.specifiers.map(specifier => getTypeSpecifierText(
84
+ specifier,
85
+ sourceCode
86
+ ))
87
+ const valueSpecifiers = valueNode.specifiers.map(specifier => sourceCode.getText(
88
+ specifier
89
+ ))
90
+ const source = sourceCode.getText(valueNode.source)
91
+
92
+ return `import { ${[
93
+ ...typeSpecifiers,
94
+ ...valueSpecifiers
95
+ ].join(', ')} } from ${source}`
96
+ }
97
+
98
+ function getFixedText(node, sourceCode) {
99
+ return sourceCode.getText(node)
100
+ .replace(/^import\b/, 'import type')
101
+ .replace(/([,{]\s*)type\s+/g, '$1')
102
+ }
103
+
104
+ export default {
105
+ meta: {
106
+ type: 'layout',
107
+ fixable: 'code',
108
+ docs: {
109
+ description: 'Prefer import type and merge duplicate type/value imports.'
110
+ },
111
+ schema: []
112
+ },
113
+ create(context) {
114
+ const sourceCode = context.sourceCode
115
+ const imports = []
116
+
117
+ return {
118
+ ImportDeclaration(node) {
119
+ if (typeof node.source.value !== 'string') {
120
+ return
121
+ }
122
+
123
+ imports.push(node)
124
+ },
125
+ 'Program:exit'() {
126
+ const mergePair = getMergePair(imports, sourceCode)
127
+
128
+ if (mergePair) {
129
+ const [
130
+ typeNode,
131
+ valueNode
132
+ ] = mergePair
133
+
134
+ context.report({
135
+ node: valueNode.source,
136
+ message: 'Merge type and value imports from the same source.',
137
+ fix: fixer => fixer.replaceTextRange(
138
+ [
139
+ typeNode.range[0],
140
+ valueNode.range[1]
141
+ ],
142
+ getMergedText(typeNode, valueNode, sourceCode)
143
+ )
144
+ })
145
+
146
+ return
147
+ }
148
+
149
+ const convertNode = getConvertNode(imports)
150
+
151
+ if (!convertNode) {
152
+ return
153
+ }
154
+
155
+ context.report({
156
+ node: convertNode.source,
157
+ message: 'Use import type when all named imports are type imports.',
158
+ fix: fixer => fixer.replaceTextRange(
159
+ convertNode.range,
160
+ getFixedText(convertNode, sourceCode)
161
+ )
162
+ })
163
+ }
164
+ }
165
+ }
166
+ }
package/src/storybook.js CHANGED
@@ -8,6 +8,11 @@ export default {
8
8
  overrides: [
9
9
  {
10
10
  files: storiesFiles,
11
+ plugins: [
12
+ 'import',
13
+ 'react',
14
+ 'typescript'
15
+ ],
11
16
  rules: {
12
17
  'eslint/max-classes-per-file': 'off',
13
18
  'eslint/no-magic-numbers': 'off',
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  export default {
6
+ jsPlugins: ['@trigen/oxlint-config/plugin'],
6
7
  rules: {
7
8
  'eslint/constructor-super': 'error',
8
9
  'eslint/for-direction': 'error',
@@ -160,7 +161,12 @@ export default {
160
161
  'eslint/no-useless-call': 'error',
161
162
  'eslint/no-useless-concat': 'error',
162
163
  'eslint/no-useless-return': 'error',
163
- 'eslint/no-void': 'error',
164
+ 'eslint/no-void': [
165
+ 'error',
166
+ {
167
+ allowAsStatement: true
168
+ }
169
+ ],
164
170
  'eslint/prefer-promise-reject-errors': 'error',
165
171
  'eslint/prefer-regex-literals': 'error',
166
172
  'eslint/preserve-caught-error': 'error',
@@ -237,6 +243,73 @@ export default {
237
243
  'eslint/no-unneeded-ternary': 'error',
238
244
  'eslint/operator-assignment': ['error', 'always'],
239
245
  'eslint/prefer-object-spread': 'error',
240
- 'eslint/unicode-bom': 'error'
246
+ 'eslint/unicode-bom': 'error',
247
+ 'trigen/naming-convention': [
248
+ 'error',
249
+ {
250
+ selector: 'default',
251
+ format: [
252
+ 'camelCase',
253
+ 'PascalCase',
254
+ 'UPPER_CASE'
255
+ ],
256
+ leadingDollar: 'allow',
257
+ trailingDollar: 'allow'
258
+ },
259
+ {
260
+ selector: 'variable',
261
+ format: [
262
+ 'camelCase',
263
+ 'UPPER_CASE',
264
+ 'PascalCase'
265
+ ],
266
+ leadingDollar: 'allow',
267
+ trailingDollar: 'allow'
268
+ },
269
+ {
270
+ selector: 'function',
271
+ format: ['camelCase', 'PascalCase'],
272
+ leadingDollar: 'allow',
273
+ trailingDollar: 'allow'
274
+ },
275
+ {
276
+ selector: 'parameter',
277
+ format: ['camelCase', 'PascalCase'],
278
+ leadingUnderscore: 'allow',
279
+ leadingDollar: 'allow',
280
+ trailingDollar: 'allow'
281
+ },
282
+ {
283
+ selector: 'typeLike',
284
+ format: ['PascalCase'],
285
+ trailingDollar: 'allow'
286
+ },
287
+ {
288
+ selector: 'interface',
289
+ format: ['PascalCase'],
290
+ trailingDollar: 'allow'
291
+ },
292
+ {
293
+ selector: 'enumMember',
294
+ format: ['PascalCase'],
295
+ trailingDollar: 'allow'
296
+ },
297
+ {
298
+ selector: 'classProperty',
299
+ format: [
300
+ 'camelCase',
301
+ 'UPPER_CASE',
302
+ 'PascalCase'
303
+ ],
304
+ modifiers: ['static'],
305
+ leadingDollar: 'allow',
306
+ trailingDollar: 'allow'
307
+ },
308
+ {
309
+ selector: ['objectLiteralProperty', 'objectLiteralMethod'],
310
+ format: null,
311
+ modifiers: ['requiresQuotes']
312
+ }
313
+ ]
241
314
  }
242
315
  }
@@ -8,6 +8,7 @@ export default {
8
8
  overrides: [
9
9
  {
10
10
  files: configFiles,
11
+ plugins: ['import'],
11
12
  rules: {
12
13
  'import/no-default-export': 'off',
13
14
  'import/no-anonymous-default-export': 'off'
@@ -4,12 +4,7 @@
4
4
 
5
5
  export default {
6
6
  plugins: ['import'],
7
- jsPlugins: [
8
- {
9
- name: 'trigen',
10
- specifier: '@trigen/oxlint-config/plugin'
11
- }
12
- ],
7
+ jsPlugins: ['@trigen/oxlint-config/plugin'],
13
8
  rules: {
14
9
  'import/no-absolute-path': 'error',
15
10
  'import/no-dynamic-require': 'error',
@@ -32,6 +32,7 @@ export default {
32
32
  overrides: [
33
33
  {
34
34
  files: tsFiles,
35
+ plugins: ['jsdoc'],
35
36
  rules: {
36
37
  'jsdoc/require-param': 'off',
37
38
  'jsdoc/require-yields-type': 'off'
@@ -11,6 +11,7 @@ export default {
11
11
  overrides: [
12
12
  {
13
13
  files: jsxFiles,
14
+ plugins: ['jsdoc'],
14
15
  rules: {
15
16
  'jsdoc/require-param': 'off',
16
17
  'jsdoc/require-returns': 'off'
@@ -19,7 +19,14 @@ export default {
19
19
  'stylistic-js/jsx-child-element-spacing': 'error',
20
20
  'stylistic-js/jsx-closing-bracket-location': 'error',
21
21
  'stylistic-js/jsx-closing-tag-location': 'error',
22
- 'react/jsx-curly-brace-presence': ['error', 'never'],
22
+ 'react/jsx-curly-brace-presence': [
23
+ 'error',
24
+ {
25
+ children: 'never',
26
+ propElementValues: 'always',
27
+ props: 'never'
28
+ }
29
+ ],
23
30
  'stylistic-js/jsx-curly-newline': 'error',
24
31
  'stylistic-js/jsx-curly-spacing': 'error',
25
32
  'stylistic-js/jsx-equals-spacing': 'error',
@@ -53,7 +53,6 @@ export default {
53
53
  'typescript/no-unnecessary-qualifier': 'error',
54
54
  'typescript/no-unnecessary-template-expression': 'error',
55
55
  'typescript/no-unnecessary-type-arguments': 'error',
56
- 'typescript/consistent-type-imports': 'error',
57
56
  'typescript/prefer-includes': 'error',
58
57
  'typescript/prefer-nullish-coalescing': 'off',
59
58
  'typescript/prefer-optional-chain': 'error',
@@ -12,12 +12,7 @@ export default {
12
12
  {
13
13
  files: tsFiles,
14
14
  plugins: ['typescript'],
15
- jsPlugins: [
16
- {
17
- name: 'trigen',
18
- specifier: '@trigen/oxlint-config/plugin'
19
- }
20
- ],
15
+ jsPlugins: ['@trigen/oxlint-config/plugin'],
21
16
  rules: {
22
17
  // Recommended
23
18
  'typescript/ban-ts-comment': [
@@ -73,13 +68,21 @@ export default {
73
68
  fixMixedExportsWithInlineTypeSpecifier: true
74
69
  }
75
70
  ],
71
+ 'typescript/consistent-type-imports': 'error',
76
72
  'typescript/explicit-module-boundary-types': 'off',
77
73
  'typescript/no-dynamic-delete': 'error',
78
74
  'typescript/no-extraneous-class': 'error',
79
- 'typescript/no-invalid-void-type': 'error',
75
+ 'typescript/no-invalid-void-type': [
76
+ 'error',
77
+ {
78
+ allowAsThisParameter: true,
79
+ allowInGenericTypeArguments: true
80
+ }
81
+ ],
80
82
  'typescript/prefer-for-of': 'error',
81
83
  'typescript/prefer-function-type': 'error',
82
84
  'typescript/unified-signatures': 'error',
85
+ 'trigen/type-import-style': 'error',
83
86
  'trigen/member-ordering': [
84
87
  'error',
85
88
  {
@@ -108,65 +111,12 @@ export default {
108
111
  ]
109
112
  }
110
113
  }
111
- ],
112
- 'trigen/naming-convention': [
113
- 'error',
114
- {
115
- selector: 'default',
116
- format: [
117
- 'camelCase',
118
- 'PascalCase',
119
- 'UPPER_CASE'
120
- ]
121
- },
122
- {
123
- selector: 'variable',
124
- format: [
125
- 'camelCase',
126
- 'UPPER_CASE',
127
- 'PascalCase'
128
- ]
129
- },
130
- {
131
- selector: 'function',
132
- format: ['camelCase', 'PascalCase']
133
- },
134
- {
135
- selector: 'parameter',
136
- format: ['camelCase', 'PascalCase'],
137
- leadingUnderscore: 'allow'
138
- },
139
- {
140
- selector: 'typeLike',
141
- format: ['PascalCase']
142
- },
143
- {
144
- selector: 'interface',
145
- format: ['PascalCase']
146
- },
147
- {
148
- selector: 'enumMember',
149
- format: ['PascalCase']
150
- },
151
- {
152
- selector: 'classProperty',
153
- format: [
154
- 'camelCase',
155
- 'UPPER_CASE',
156
- 'PascalCase'
157
- ],
158
- modifiers: ['static']
159
- },
160
- {
161
- selector: ['objectLiteralProperty', 'objectLiteralMethod'],
162
- format: null,
163
- modifiers: ['requiresQuotes']
164
- }
165
114
  ]
166
115
  }
167
116
  },
168
117
  {
169
118
  files: dtsFiles,
119
+ plugins: ['import'],
170
120
  rules: {
171
121
  'import/unambiguous': 'off'
172
122
  }
package/src/test.js CHANGED
@@ -11,6 +11,8 @@ export default {
11
11
  env: {
12
12
  vitest: true
13
13
  },
14
+ plugins: ['typescript'],
15
+ jsPlugins: ['@trigen/oxlint-config/plugin'],
14
16
  rules: {
15
17
  'eslint/max-classes-per-file': 'off',
16
18
  'eslint/no-magic-numbers': 'off',
@@ -25,7 +27,10 @@ export default {
25
27
  'trigen/import-order': 'off',
26
28
  'eslint/prefer-destructuring': 'off',
27
29
  'eslint/no-loop-func': 'off',
28
- 'typescript/no-misused-promises': 'off'
30
+ 'typescript/no-misused-promises': 'off',
31
+ 'eslint/no-use-before-define': 'off',
32
+ 'eslint/no-useless-assignment': 'off',
33
+ 'eslint/no-empty-function': 'off'
29
34
 
30
35
  // Unsupported by Oxlint
31
36
  // 'eslint/camelcase': 'off',