eslint-plugin-perfectionist 3.4.0 → 3.6.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.
Files changed (37) hide show
  1. package/dist/index.d.ts +14 -9
  2. package/dist/rules/sort-astro-attributes.js +8 -1
  3. package/dist/rules/sort-astro-attributes.mjs +8 -1
  4. package/dist/rules/sort-classes.js +10 -5
  5. package/dist/rules/sort-classes.mjs +7 -5
  6. package/dist/rules/sort-enums.js +9 -7
  7. package/dist/rules/sort-enums.mjs +7 -5
  8. package/dist/rules/sort-imports.js +32 -15
  9. package/dist/rules/sort-imports.mjs +31 -14
  10. package/dist/rules/sort-interfaces.js +16 -1
  11. package/dist/rules/sort-interfaces.mjs +10 -1
  12. package/dist/rules/sort-intersection-types.js +8 -1
  13. package/dist/rules/sort-intersection-types.mjs +8 -1
  14. package/dist/rules/sort-jsx-props.js +8 -1
  15. package/dist/rules/sort-jsx-props.mjs +8 -1
  16. package/dist/rules/sort-object-types.js +8 -1
  17. package/dist/rules/sort-object-types.mjs +8 -1
  18. package/dist/rules/sort-objects.js +84 -50
  19. package/dist/rules/sort-objects.mjs +78 -50
  20. package/dist/rules/sort-svelte-attributes.js +8 -1
  21. package/dist/rules/sort-svelte-attributes.mjs +8 -1
  22. package/dist/rules/sort-union-types.js +8 -1
  23. package/dist/rules/sort-union-types.mjs +8 -1
  24. package/dist/rules/sort-variable-declarations.js +39 -9
  25. package/dist/rules/sort-variable-declarations.mjs +39 -9
  26. package/dist/rules/sort-vue-attributes.js +8 -1
  27. package/dist/rules/sort-vue-attributes.mjs +8 -1
  28. package/dist/utils/get-comments-before.js +12 -0
  29. package/dist/utils/get-comments-before.mjs +10 -0
  30. package/dist/utils/get-node-range.js +26 -12
  31. package/dist/utils/get-node-range.mjs +26 -12
  32. package/dist/utils/is-partition-comment.js +3 -0
  33. package/dist/utils/is-partition-comment.mjs +3 -1
  34. package/package.json +4 -4
  35. package/readme.md +1 -0
  36. package/dist/utils/get-comment-before.js +0 -23
  37. package/dist/utils/get-comment-before.mjs +0 -21
package/dist/index.d.ts CHANGED
@@ -120,7 +120,8 @@ declare const _default: {
120
120
  RuleListener
121
121
  >
122
122
  'sort-intersection-types': RuleModule<
123
- 'unexpectedIntersectionTypesOrder',
123
+ | 'unexpectedIntersectionTypesGroupOrder'
124
+ | 'unexpectedIntersectionTypesOrder',
124
125
  [
125
126
  Partial<{
126
127
  type: 'alphabetical' | 'line-length' | 'natural'
@@ -164,7 +165,8 @@ declare const _default: {
164
165
  RuleListener
165
166
  >
166
167
  'sort-svelte-attributes': RuleModule<
167
- 'unexpectedSvelteAttributesOrder',
168
+ | 'unexpectedSvelteAttributesGroupOrder'
169
+ | 'unexpectedSvelteAttributesOrder',
168
170
  [
169
171
  Partial<{
170
172
  customGroups: {
@@ -180,7 +182,7 @@ declare const _default: {
180
182
  RuleListener
181
183
  >
182
184
  'sort-astro-attributes': RuleModule<
183
- 'unexpectedAstroAttributesOrder',
185
+ 'unexpectedAstroAttributesGroupOrder' | 'unexpectedAstroAttributesOrder',
184
186
  [
185
187
  Partial<{
186
188
  customGroups: {
@@ -196,7 +198,7 @@ declare const _default: {
196
198
  RuleListener
197
199
  >
198
200
  'sort-vue-attributes': RuleModule<
199
- 'unexpectedVueAttributesOrder',
201
+ 'unexpectedVueAttributesGroupOrder' | 'unexpectedVueAttributesOrder',
200
202
  [
201
203
  Partial<{
202
204
  customGroups: {
@@ -245,7 +247,7 @@ declare const _default: {
245
247
  RuleListener
246
248
  >
247
249
  'sort-object-types': RuleModule<
248
- 'unexpectedObjectTypesOrder',
250
+ 'unexpectedObjectTypesGroupOrder' | 'unexpectedObjectTypesOrder',
249
251
  [
250
252
  Partial<{
251
253
  groupKind: 'required-first' | 'optional-first' | 'mixed'
@@ -263,7 +265,7 @@ declare const _default: {
263
265
  RuleListener
264
266
  >
265
267
  'sort-union-types': RuleModule<
266
- 'unexpectedUnionTypesOrder',
268
+ 'unexpectedUnionTypesGroupOrder' | 'unexpectedUnionTypesOrder',
267
269
  [
268
270
  Partial<{
269
271
  type: 'alphabetical' | 'line-length' | 'natural'
@@ -319,7 +321,8 @@ declare const _default: {
319
321
  RuleListener
320
322
  >
321
323
  'sort-interfaces': RuleModule<
322
- 'unexpectedInterfacePropertiesOrder',
324
+ | 'unexpectedInterfacePropertiesGroupOrder'
325
+ | 'unexpectedInterfacePropertiesOrder',
323
326
  [
324
327
  Partial<{
325
328
  groupKind: 'optional-first' | 'required-first' | 'mixed'
@@ -338,7 +341,7 @@ declare const _default: {
338
341
  RuleListener
339
342
  >
340
343
  'sort-jsx-props': RuleModule<
341
- 'unexpectedJSXPropsOrder',
344
+ 'unexpectedJSXPropsGroupOrder' | 'unexpectedJSXPropsOrder',
342
345
  [
343
346
  Partial<{
344
347
  customGroups: {
@@ -362,6 +365,7 @@ declare const _default: {
362
365
  >
363
366
  'sort-imports': RuleModule<
364
367
  | 'missedSpacingBetweenImports'
368
+ | 'unexpectedImportsGroupOrder'
365
369
  | 'extraSpacingBetweenImports'
366
370
  | 'unexpectedImportsOrder',
367
371
  [
@@ -383,6 +387,7 @@ declare const _default: {
383
387
  groups: (string | string[])[]
384
388
  environment: 'node' | 'bun'
385
389
  internalPattern: string[]
390
+ sortSideEffects: boolean
386
391
  maxLineLength?: number
387
392
  order: 'desc' | 'asc'
388
393
  ignoreCase: boolean
@@ -404,7 +409,7 @@ declare const _default: {
404
409
  RuleListener
405
410
  >
406
411
  'sort-objects': RuleModule<
407
- 'unexpectedObjectsOrder',
412
+ 'unexpectedObjectsGroupOrder' | 'unexpectedObjectsOrder',
408
413
  [
409
414
  Partial<{
410
415
  customGroups: {
@@ -80,6 +80,8 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
80
80
  },
81
81
  ],
82
82
  messages: {
83
+ unexpectedAstroAttributesGroupOrder:
84
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
83
85
  unexpectedAstroAttributesOrder:
84
86
  'Expected "{{right}}" to come before "{{left}}".',
85
87
  },
@@ -162,10 +164,15 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
162
164
  isPositive.isPositive(compare.compare(left, right, options)))
163
165
  ) {
164
166
  context.report({
165
- messageId: 'unexpectedAstroAttributesOrder',
167
+ messageId:
168
+ leftNum !== rightNum
169
+ ? 'unexpectedAstroAttributesGroupOrder'
170
+ : 'unexpectedAstroAttributesOrder',
166
171
  data: {
167
172
  left: left.name,
168
173
  right: right.name,
174
+ leftGroup: left.group,
175
+ rightGroup: right.group,
169
176
  },
170
177
  node: right.node,
171
178
  fix: fixer => {
@@ -79,6 +79,8 @@ const sortAstroAttributes = createEslintRule({
79
79
  },
80
80
  ],
81
81
  messages: {
82
+ unexpectedAstroAttributesGroupOrder:
83
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
82
84
  unexpectedAstroAttributesOrder:
83
85
  'Expected "{{right}}" to come before "{{left}}".',
84
86
  },
@@ -159,10 +161,15 @@ const sortAstroAttributes = createEslintRule({
159
161
  isPositive(compare(left, right, options)))
160
162
  ) {
161
163
  context.report({
162
- messageId: 'unexpectedAstroAttributesOrder',
164
+ messageId:
165
+ leftNum !== rightNum
166
+ ? 'unexpectedAstroAttributesGroupOrder'
167
+ : 'unexpectedAstroAttributesOrder',
163
168
  data: {
164
169
  left: left.name,
165
170
  right: right.name,
171
+ leftGroup: left.group,
172
+ rightGroup: right.group,
166
173
  },
167
174
  node: right.node,
168
175
  fix: fixer => {
@@ -3,7 +3,7 @@ const sortClassesUtils = require('./sort-classes-utils.js')
3
3
  const sortClasses_types = require('./sort-classes.types.js')
4
4
  const sortNodesByDependencies = require('../utils/sort-nodes-by-dependencies.js')
5
5
  const isPartitionComment = require('../utils/is-partition-comment.js')
6
- const getCommentBefore = require('../utils/get-comment-before.js')
6
+ const getCommentsBefore = require('../utils/get-comments-before.js')
7
7
  const createEslintRule = require('../utils/create-eslint-rule.js')
8
8
  const getGroupNumber = require('../utils/get-group-number.js')
9
9
  const getSourceCode = require('../utils/get-source-code.js')
@@ -292,6 +292,9 @@ const sortClasses = createEslintRule.createEslintRule({
292
292
  if ('properties' in nodeValue) {
293
293
  nodeValue.properties.forEach(traverseNode)
294
294
  }
295
+ if ('expressions' in nodeValue) {
296
+ nodeValue.expressions.forEach(traverseNode)
297
+ }
295
298
  }
296
299
  let traverseNode = nodeValue => {
297
300
  if (Array.isArray(nodeValue)) {
@@ -308,13 +311,15 @@ const sortClasses = createEslintRule.createEslintRule({
308
311
  let formattedNodes = node.body.reduce(
309
312
  (accumulator, member) => {
310
313
  var _a2, _b, _c, _d
311
- let comment = getCommentBefore.getCommentBefore(member, sourceCode)
314
+ let comments = getCommentsBefore.getCommentsBefore(
315
+ member,
316
+ sourceCode,
317
+ )
312
318
  if (
313
319
  options.partitionByComment &&
314
- comment &&
315
- isPartitionComment.isPartitionComment(
320
+ isPartitionComment.hasPartitionComment(
316
321
  options.partitionByComment,
317
- comment.value,
322
+ comments,
318
323
  )
319
324
  ) {
320
325
  accumulator.push([])
@@ -10,8 +10,8 @@ import {
10
10
  singleCustomGroupJsonSchema,
11
11
  } from './sort-classes.types.mjs'
12
12
  import { sortNodesByDependencies } from '../utils/sort-nodes-by-dependencies.mjs'
13
- import { isPartitionComment } from '../utils/is-partition-comment.mjs'
14
- import { getCommentBefore } from '../utils/get-comment-before.mjs'
13
+ import { hasPartitionComment } from '../utils/is-partition-comment.mjs'
14
+ import { getCommentsBefore } from '../utils/get-comments-before.mjs'
15
15
  import { createEslintRule } from '../utils/create-eslint-rule.mjs'
16
16
  import { getGroupNumber } from '../utils/get-group-number.mjs'
17
17
  import { getSourceCode } from '../utils/get-source-code.mjs'
@@ -300,6 +300,9 @@ const sortClasses = createEslintRule({
300
300
  if ('properties' in nodeValue) {
301
301
  nodeValue.properties.forEach(traverseNode)
302
302
  }
303
+ if ('expressions' in nodeValue) {
304
+ nodeValue.expressions.forEach(traverseNode)
305
+ }
303
306
  }
304
307
  let traverseNode = nodeValue => {
305
308
  if (Array.isArray(nodeValue)) {
@@ -315,11 +318,10 @@ const sortClasses = createEslintRule({
315
318
  let formattedNodes = node.body.reduce(
316
319
  (accumulator, member) => {
317
320
  var _a2, _b, _c, _d
318
- let comment = getCommentBefore(member, sourceCode)
321
+ let comments = getCommentsBefore(member, sourceCode)
319
322
  if (
320
323
  options.partitionByComment &&
321
- comment &&
322
- isPartitionComment(options.partitionByComment, comment.value)
324
+ hasPartitionComment(options.partitionByComment, comments)
323
325
  ) {
324
326
  accumulator.push([])
325
327
  }
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
  const sortNodesByDependencies = require('../utils/sort-nodes-by-dependencies.js')
3
3
  const isPartitionComment = require('../utils/is-partition-comment.js')
4
+ const getCommentsBefore = require('../utils/get-comments-before.js')
4
5
  const createEslintRule = require('../utils/create-eslint-rule.js')
5
- const getCommentBefore = require('../utils/get-comment-before.js')
6
6
  const getSourceCode = require('../utils/get-source-code.js')
7
7
  const toSingleLine = require('../utils/to-single-line.js')
8
8
  const rangeToDiff = require('../utils/range-to-diff.js')
@@ -131,20 +131,22 @@ const sortEnums = createEslintRule.createEslintRule({
131
131
  if ('right' in nodeValue) {
132
132
  checkNode(nodeValue.right)
133
133
  }
134
+ if ('expressions' in nodeValue) {
135
+ nodeValue.expressions.forEach(checkNode)
136
+ }
134
137
  }
135
138
  checkNode(expression)
136
139
  return dependencies
137
140
  }
138
141
  let formattedMembers = members.reduce(
139
142
  (accumulator, member) => {
140
- let comment = getCommentBefore.getCommentBefore(member, sourceCode)
143
+ let comments = getCommentsBefore.getCommentsBefore(
144
+ member,
145
+ sourceCode,
146
+ )
141
147
  if (
142
148
  partitionComment &&
143
- comment &&
144
- isPartitionComment.isPartitionComment(
145
- partitionComment,
146
- comment.value,
147
- )
149
+ isPartitionComment.hasPartitionComment(partitionComment, comments)
148
150
  ) {
149
151
  accumulator.push([])
150
152
  }
@@ -1,7 +1,7 @@
1
1
  import { sortNodesByDependencies } from '../utils/sort-nodes-by-dependencies.mjs'
2
- import { isPartitionComment } from '../utils/is-partition-comment.mjs'
2
+ import { hasPartitionComment } from '../utils/is-partition-comment.mjs'
3
+ import { getCommentsBefore } from '../utils/get-comments-before.mjs'
3
4
  import { createEslintRule } from '../utils/create-eslint-rule.mjs'
4
- import { getCommentBefore } from '../utils/get-comment-before.mjs'
5
5
  import { getSourceCode } from '../utils/get-source-code.mjs'
6
6
  import { toSingleLine } from '../utils/to-single-line.mjs'
7
7
  import { rangeToDiff } from '../utils/range-to-diff.mjs'
@@ -130,17 +130,19 @@ const sortEnums = createEslintRule({
130
130
  if ('right' in nodeValue) {
131
131
  checkNode(nodeValue.right)
132
132
  }
133
+ if ('expressions' in nodeValue) {
134
+ nodeValue.expressions.forEach(checkNode)
135
+ }
133
136
  }
134
137
  checkNode(expression)
135
138
  return dependencies
136
139
  }
137
140
  let formattedMembers = members.reduce(
138
141
  (accumulator, member) => {
139
- let comment = getCommentBefore(member, sourceCode)
142
+ let comments = getCommentsBefore(member, sourceCode)
140
143
  if (
141
144
  partitionComment &&
142
- comment &&
143
- isPartitionComment(partitionComment, comment.value)
145
+ hasPartitionComment(partitionComment, comments)
144
146
  ) {
145
147
  accumulator.push([])
146
148
  }
@@ -2,7 +2,7 @@
2
2
  const node_module = require('node:module')
3
3
  const minimatch = require('minimatch')
4
4
  const validateGroupsConfiguration = require('../utils/validate-groups-configuration.js')
5
- const getCommentBefore = require('../utils/get-comment-before.js')
5
+ const getCommentsBefore = require('../utils/get-comments-before.js')
6
6
  const createEslintRule = require('../utils/create-eslint-rule.js')
7
7
  const getLinesBetween = require('../utils/get-lines-between.js')
8
8
  const getGroupNumber = require('../utils/get-group-number.js')
@@ -52,6 +52,11 @@ const sortImports = createEslintRule.createEslintRule({
52
52
  },
53
53
  type: 'array',
54
54
  },
55
+ sortSideEffects: {
56
+ description:
57
+ 'Controls whether side-effect imports should be sorted.',
58
+ type: 'boolean',
59
+ },
55
60
  newlinesBetween: {
56
61
  description:
57
62
  'Specifies how new lines should be handled between import groups.',
@@ -135,6 +140,8 @@ const sortImports = createEslintRule.createEslintRule({
135
140
  },
136
141
  ],
137
142
  messages: {
143
+ unexpectedImportsGroupOrder:
144
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
138
145
  unexpectedImportsOrder: 'Expected "{{right}}" to come before "{{left}}".',
139
146
  missedSpacingBetweenImports:
140
147
  'Missed spacing between "{{left}}" and "{{right}}" imports.',
@@ -148,6 +155,7 @@ const sortImports = createEslintRule.createEslintRule({
148
155
  order: 'asc',
149
156
  ignoreCase: true,
150
157
  internalPattern: ['~/**'],
158
+ sortSideEffects: false,
151
159
  newlinesBetween: 'always',
152
160
  maxLineLength: void 0,
153
161
  groups: [
@@ -180,6 +188,7 @@ const sortImports = createEslintRule.createEslintRule({
180
188
  customGroups: { type: {}, value: {} },
181
189
  internalPattern: ['~/**'],
182
190
  newlinesBetween: 'always',
191
+ sortSideEffects: false,
183
192
  type: 'alphabetical',
184
193
  environment: 'node',
185
194
  ignoreCase: true,
@@ -402,14 +411,11 @@ const sortImports = createEslintRule.createEslintRule({
402
411
  'Program:exit': () => {
403
412
  var _a
404
413
  let hasContentBetweenNodes = (left, right) =>
405
- !!sourceCode.getTokensBetween(
406
- left.node,
407
- getCommentBefore.getCommentBefore(right.node, sourceCode) ||
408
- right.node,
409
- {
410
- includeComments: true,
411
- },
412
- ).length
414
+ getCommentsBefore.getCommentsBefore(right.node, sourceCode).length >
415
+ 0 ||
416
+ !!sourceCode.getTokensBetween(left.node, right.node, {
417
+ includeComments: false,
418
+ }).length
413
419
  let fix = (fixer, nodesToFix) => {
414
420
  let fixes = []
415
421
  let grouped = {}
@@ -418,10 +424,14 @@ const sortImports = createEslintRule.createEslintRule({
418
424
  if (!(groupNum in grouped)) {
419
425
  grouped[groupNum] = [node]
420
426
  } else {
421
- grouped[groupNum] = sortNodes.sortNodes(
422
- [...grouped[groupNum], node],
423
- options,
424
- )
427
+ if (!options.sortSideEffects && isSideEffectImport(node.node)) {
428
+ grouped[groupNum] = [...grouped[groupNum], node]
429
+ } else {
430
+ grouped[groupNum] = sortNodes.sortNodes(
431
+ [...grouped[groupNum], node],
432
+ options,
433
+ )
434
+ }
425
435
  }
426
436
  }
427
437
  let formatted = Object.keys(grouped)
@@ -529,7 +539,9 @@ const sortImports = createEslintRule.createEslintRule({
529
539
  )
530
540
  if (
531
541
  !(
532
- isSideEffectImport(left.node) && isSideEffectImport(right.node)
542
+ !options.sortSideEffects &&
543
+ isSideEffectImport(left.node) &&
544
+ isSideEffectImport(right.node)
533
545
  ) &&
534
546
  !hasContentBetweenNodes(left, right) &&
535
547
  (leftNum > rightNum ||
@@ -537,10 +549,15 @@ const sortImports = createEslintRule.createEslintRule({
537
549
  isPositive.isPositive(compare.compare(left, right, options))))
538
550
  ) {
539
551
  context.report({
540
- messageId: 'unexpectedImportsOrder',
552
+ messageId:
553
+ leftNum !== rightNum
554
+ ? 'unexpectedImportsGroupOrder'
555
+ : 'unexpectedImportsOrder',
541
556
  data: {
542
557
  left: left.name,
558
+ leftGroup: left.group,
543
559
  right: right.name,
560
+ rightGroup: right.group,
544
561
  },
545
562
  node: right.node,
546
563
  fix: fixer => fix(fixer, nodeList),
@@ -1,7 +1,7 @@
1
1
  import { builtinModules } from 'node:module'
2
2
  import { minimatch } from 'minimatch'
3
3
  import { validateGroupsConfiguration } from '../utils/validate-groups-configuration.mjs'
4
- import { getCommentBefore } from '../utils/get-comment-before.mjs'
4
+ import { getCommentsBefore } from '../utils/get-comments-before.mjs'
5
5
  import { createEslintRule } from '../utils/create-eslint-rule.mjs'
6
6
  import { getLinesBetween } from '../utils/get-lines-between.mjs'
7
7
  import { getGroupNumber } from '../utils/get-group-number.mjs'
@@ -51,6 +51,11 @@ const sortImports = createEslintRule({
51
51
  },
52
52
  type: 'array',
53
53
  },
54
+ sortSideEffects: {
55
+ description:
56
+ 'Controls whether side-effect imports should be sorted.',
57
+ type: 'boolean',
58
+ },
54
59
  newlinesBetween: {
55
60
  description:
56
61
  'Specifies how new lines should be handled between import groups.',
@@ -134,6 +139,8 @@ const sortImports = createEslintRule({
134
139
  },
135
140
  ],
136
141
  messages: {
142
+ unexpectedImportsGroupOrder:
143
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
137
144
  unexpectedImportsOrder: 'Expected "{{right}}" to come before "{{left}}".',
138
145
  missedSpacingBetweenImports:
139
146
  'Missed spacing between "{{left}}" and "{{right}}" imports.',
@@ -147,6 +154,7 @@ const sortImports = createEslintRule({
147
154
  order: 'asc',
148
155
  ignoreCase: true,
149
156
  internalPattern: ['~/**'],
157
+ sortSideEffects: false,
150
158
  newlinesBetween: 'always',
151
159
  maxLineLength: void 0,
152
160
  groups: [
@@ -179,6 +187,7 @@ const sortImports = createEslintRule({
179
187
  customGroups: { type: {}, value: {} },
180
188
  internalPattern: ['~/**'],
181
189
  newlinesBetween: 'always',
190
+ sortSideEffects: false,
182
191
  type: 'alphabetical',
183
192
  environment: 'node',
184
193
  ignoreCase: true,
@@ -397,13 +406,10 @@ const sortImports = createEslintRule({
397
406
  'Program:exit': () => {
398
407
  var _a
399
408
  let hasContentBetweenNodes = (left, right) =>
400
- !!sourceCode.getTokensBetween(
401
- left.node,
402
- getCommentBefore(right.node, sourceCode) || right.node,
403
- {
404
- includeComments: true,
405
- },
406
- ).length
409
+ getCommentsBefore(right.node, sourceCode).length > 0 ||
410
+ !!sourceCode.getTokensBetween(left.node, right.node, {
411
+ includeComments: false,
412
+ }).length
407
413
  let fix = (fixer, nodesToFix) => {
408
414
  let fixes = []
409
415
  let grouped = {}
@@ -412,10 +418,14 @@ const sortImports = createEslintRule({
412
418
  if (!(groupNum in grouped)) {
413
419
  grouped[groupNum] = [node]
414
420
  } else {
415
- grouped[groupNum] = sortNodes(
416
- [...grouped[groupNum], node],
417
- options,
418
- )
421
+ if (!options.sortSideEffects && isSideEffectImport(node.node)) {
422
+ grouped[groupNum] = [...grouped[groupNum], node]
423
+ } else {
424
+ grouped[groupNum] = sortNodes(
425
+ [...grouped[groupNum], node],
426
+ options,
427
+ )
428
+ }
419
429
  }
420
430
  }
421
431
  let formatted = Object.keys(grouped)
@@ -514,7 +524,9 @@ const sortImports = createEslintRule({
514
524
  )
515
525
  if (
516
526
  !(
517
- isSideEffectImport(left.node) && isSideEffectImport(right.node)
527
+ !options.sortSideEffects &&
528
+ isSideEffectImport(left.node) &&
529
+ isSideEffectImport(right.node)
518
530
  ) &&
519
531
  !hasContentBetweenNodes(left, right) &&
520
532
  (leftNum > rightNum ||
@@ -522,10 +534,15 @@ const sortImports = createEslintRule({
522
534
  isPositive(compare(left, right, options))))
523
535
  ) {
524
536
  context.report({
525
- messageId: 'unexpectedImportsOrder',
537
+ messageId:
538
+ leftNum !== rightNum
539
+ ? 'unexpectedImportsGroupOrder'
540
+ : 'unexpectedImportsOrder',
526
541
  data: {
527
542
  left: left.name,
543
+ leftGroup: left.group,
528
544
  right: right.name,
545
+ rightGroup: right.group,
529
546
  },
530
547
  node: right.node,
531
548
  fix: fixer => fix(fixer, nodeList),
@@ -101,6 +101,8 @@ const sortInterfaces = createEslintRule.createEslintRule({
101
101
  },
102
102
  ],
103
103
  messages: {
104
+ unexpectedInterfacePropertiesGroupOrder:
105
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
104
106
  unexpectedInterfacePropertiesOrder:
105
107
  'Expected "{{right}}" to come before "{{left}}".',
106
108
  },
@@ -271,11 +273,24 @@ const sortInterfaces = createEslintRule.createEslintRule({
271
273
  for (let nodes of formattedMembers) {
272
274
  pairwise.pairwise(nodes, (left, right, iteration) => {
273
275
  if (checkOrder(nodes, left, right, iteration)) {
276
+ let leftNum = getGroupNumber.getGroupNumber(
277
+ options.groups,
278
+ left,
279
+ )
280
+ let rightNum = getGroupNumber.getGroupNumber(
281
+ options.groups,
282
+ right,
283
+ )
274
284
  context.report({
275
- messageId: 'unexpectedInterfacePropertiesOrder',
285
+ messageId:
286
+ leftNum !== rightNum
287
+ ? 'unexpectedInterfacePropertiesGroupOrder'
288
+ : 'unexpectedInterfacePropertiesOrder',
276
289
  data: {
277
290
  left: toSingleLine.toSingleLine(left.name),
291
+ leftGroup: left.group,
278
292
  right: toSingleLine.toSingleLine(right.name),
293
+ rightGroup: right.group,
279
294
  },
280
295
  node: right.node,
281
296
  fix: fixer => {
@@ -100,6 +100,8 @@ const sortInterfaces = createEslintRule({
100
100
  },
101
101
  ],
102
102
  messages: {
103
+ unexpectedInterfacePropertiesGroupOrder:
104
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
103
105
  unexpectedInterfacePropertiesOrder:
104
106
  'Expected "{{right}}" to come before "{{left}}".',
105
107
  },
@@ -260,11 +262,18 @@ const sortInterfaces = createEslintRule({
260
262
  for (let nodes of formattedMembers) {
261
263
  pairwise(nodes, (left, right, iteration) => {
262
264
  if (checkOrder(nodes, left, right, iteration)) {
265
+ let leftNum = getGroupNumber(options.groups, left)
266
+ let rightNum = getGroupNumber(options.groups, right)
263
267
  context.report({
264
- messageId: 'unexpectedInterfacePropertiesOrder',
268
+ messageId:
269
+ leftNum !== rightNum
270
+ ? 'unexpectedInterfacePropertiesGroupOrder'
271
+ : 'unexpectedInterfacePropertiesOrder',
265
272
  data: {
266
273
  left: toSingleLine(left.name),
274
+ leftGroup: left.group,
267
275
  right: toSingleLine(right.name),
276
+ rightGroup: right.group,
268
277
  },
269
278
  node: right.node,
270
279
  fix: fixer => {
@@ -63,6 +63,8 @@ const sortIntersectionTypes = createEslintRule.createEslintRule({
63
63
  },
64
64
  ],
65
65
  messages: {
66
+ unexpectedIntersectionTypesGroupOrder:
67
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
66
68
  unexpectedIntersectionTypesOrder:
67
69
  'Expected "{{right}}" to come before "{{left}}".',
68
70
  },
@@ -180,10 +182,15 @@ const sortIntersectionTypes = createEslintRule.createEslintRule({
180
182
  isPositive.isPositive(compare.compare(left, right, options)))
181
183
  ) {
182
184
  context.report({
183
- messageId: 'unexpectedIntersectionTypesOrder',
185
+ messageId:
186
+ leftNum !== rightNum
187
+ ? 'unexpectedIntersectionTypesGroupOrder'
188
+ : 'unexpectedIntersectionTypesOrder',
184
189
  data: {
185
190
  left: toSingleLine.toSingleLine(left.name),
191
+ leftGroup: left.group,
186
192
  right: toSingleLine.toSingleLine(right.name),
193
+ rightGroup: right.group,
187
194
  },
188
195
  node: right.node,
189
196
  fix: fixer => {
@@ -62,6 +62,8 @@ const sortIntersectionTypes = createEslintRule({
62
62
  },
63
63
  ],
64
64
  messages: {
65
+ unexpectedIntersectionTypesGroupOrder:
66
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
65
67
  unexpectedIntersectionTypesOrder:
66
68
  'Expected "{{right}}" to come before "{{left}}".',
67
69
  },
@@ -178,10 +180,15 @@ const sortIntersectionTypes = createEslintRule({
178
180
  (leftNum === rightNum && isPositive(compare(left, right, options)))
179
181
  ) {
180
182
  context.report({
181
- messageId: 'unexpectedIntersectionTypesOrder',
183
+ messageId:
184
+ leftNum !== rightNum
185
+ ? 'unexpectedIntersectionTypesGroupOrder'
186
+ : 'unexpectedIntersectionTypesOrder',
182
187
  data: {
183
188
  left: toSingleLine(left.name),
189
+ leftGroup: left.group,
184
190
  right: toSingleLine(right.name),
191
+ rightGroup: right.group,
185
192
  },
186
193
  node: right.node,
187
194
  fix: fixer => {
@@ -88,6 +88,8 @@ const sortJsxProps = createEslintRule.createEslintRule({
88
88
  },
89
89
  ],
90
90
  messages: {
91
+ unexpectedJSXPropsGroupOrder:
92
+ 'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
91
93
  unexpectedJSXPropsOrder:
92
94
  'Expected "{{right}}" to come before "{{left}}".',
93
95
  },
@@ -171,10 +173,15 @@ const sortJsxProps = createEslintRule.createEslintRule({
171
173
  isPositive.isPositive(compare.compare(left, right, options)))
172
174
  ) {
173
175
  context.report({
174
- messageId: 'unexpectedJSXPropsOrder',
176
+ messageId:
177
+ leftNum !== rightNum
178
+ ? 'unexpectedJSXPropsGroupOrder'
179
+ : 'unexpectedJSXPropsOrder',
175
180
  data: {
176
181
  left: left.name,
182
+ leftGroup: left.group,
177
183
  right: right.name,
184
+ rightGroup: right.group,
178
185
  },
179
186
  node: right.node,
180
187
  fix: fixer => {