eslint-plugin-perfectionist 2.8.0 → 2.9.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 (84) hide show
  1. package/dist/configs/recommended-alphabetical.js +9 -1
  2. package/dist/configs/recommended-alphabetical.mjs +5 -11
  3. package/dist/configs/recommended-line-length.js +9 -1
  4. package/dist/configs/recommended-line-length.mjs +5 -11
  5. package/dist/configs/recommended-natural.js +9 -1
  6. package/dist/configs/recommended-natural.mjs +5 -11
  7. package/dist/index.js +135 -3
  8. package/dist/index.mjs +76 -2244
  9. package/dist/package.json.js +4 -0
  10. package/dist/package.json.mjs +4 -0
  11. package/dist/rules/sort-array-includes.js +129 -0
  12. package/dist/rules/sort-array-includes.mjs +129 -0
  13. package/dist/rules/sort-astro-attributes.js +161 -0
  14. package/dist/rules/sort-astro-attributes.mjs +161 -0
  15. package/dist/rules/sort-classes.js +213 -0
  16. package/dist/rules/sort-classes.mjs +213 -0
  17. package/dist/rules/sort-enums.js +117 -0
  18. package/dist/rules/sort-enums.mjs +117 -0
  19. package/dist/rules/sort-exports.js +104 -0
  20. package/dist/rules/sort-exports.mjs +104 -0
  21. package/dist/rules/sort-imports.js +439 -0
  22. package/dist/rules/sort-imports.mjs +439 -0
  23. package/dist/rules/sort-interfaces.js +253 -0
  24. package/dist/rules/sort-interfaces.mjs +253 -0
  25. package/dist/rules/sort-intersection-types.js +92 -0
  26. package/dist/rules/sort-intersection-types.mjs +92 -0
  27. package/dist/rules/sort-jsx-props.js +156 -0
  28. package/dist/rules/sort-jsx-props.mjs +156 -0
  29. package/dist/rules/sort-maps.js +125 -0
  30. package/dist/rules/sort-maps.mjs +125 -0
  31. package/dist/rules/sort-named-exports.js +105 -0
  32. package/dist/rules/sort-named-exports.mjs +105 -0
  33. package/dist/rules/sort-named-imports.js +123 -0
  34. package/dist/rules/sort-named-imports.mjs +123 -0
  35. package/dist/rules/sort-object-types.js +189 -0
  36. package/dist/rules/sort-object-types.mjs +189 -0
  37. package/dist/rules/sort-objects.js +265 -0
  38. package/dist/rules/sort-objects.mjs +265 -0
  39. package/dist/rules/sort-svelte-attributes.js +168 -0
  40. package/dist/rules/sort-svelte-attributes.mjs +168 -0
  41. package/dist/rules/sort-union-types.js +120 -0
  42. package/dist/rules/sort-union-types.mjs +120 -0
  43. package/dist/rules/sort-vue-attributes.js +165 -0
  44. package/dist/rules/sort-vue-attributes.mjs +165 -0
  45. package/dist/typings/index.js +29 -0
  46. package/dist/typings/index.mjs +29 -0
  47. package/dist/utils/compare.js +38 -0
  48. package/dist/utils/compare.mjs +38 -0
  49. package/dist/utils/complete.js +4 -0
  50. package/dist/utils/complete.mjs +4 -0
  51. package/dist/utils/create-eslint-rule.js +7 -0
  52. package/dist/utils/create-eslint-rule.mjs +7 -0
  53. package/dist/utils/get-comment-after.js +13 -0
  54. package/dist/utils/get-comment-after.mjs +13 -0
  55. package/dist/utils/get-comment-before.js +14 -0
  56. package/dist/utils/get-comment-before.mjs +14 -0
  57. package/dist/utils/get-group-number.js +12 -0
  58. package/dist/utils/get-group-number.mjs +12 -0
  59. package/dist/utils/get-lines-between.js +10 -0
  60. package/dist/utils/get-lines-between.mjs +10 -0
  61. package/dist/utils/get-node-parent.js +14 -0
  62. package/dist/utils/get-node-parent.mjs +14 -0
  63. package/dist/utils/get-node-range.js +41 -0
  64. package/dist/utils/get-node-range.mjs +41 -0
  65. package/dist/utils/is-member-optional.js +12 -0
  66. package/dist/utils/is-member-optional.mjs +12 -0
  67. package/dist/utils/is-partition-comment.js +11 -0
  68. package/dist/utils/is-partition-comment.mjs +11 -0
  69. package/dist/utils/is-positive.js +4 -0
  70. package/dist/utils/is-positive.mjs +4 -0
  71. package/dist/utils/make-fixes.js +38 -0
  72. package/dist/utils/make-fixes.mjs +38 -0
  73. package/dist/utils/pairwise.js +14 -0
  74. package/dist/utils/pairwise.mjs +14 -0
  75. package/dist/utils/range-to-diff.js +7 -0
  76. package/dist/utils/range-to-diff.mjs +7 -0
  77. package/dist/utils/sort-nodes.js +5 -0
  78. package/dist/utils/sort-nodes.mjs +5 -0
  79. package/dist/utils/to-single-line.js +4 -0
  80. package/dist/utils/to-single-line.mjs +4 -0
  81. package/dist/utils/use-groups.js +35 -0
  82. package/dist/utils/use-groups.mjs +35 -0
  83. package/package.json +1 -1
  84. package/readme.md +20 -19
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const name = "eslint-plugin-perfectionist";
4
+ exports.name = name;
@@ -0,0 +1,4 @@
1
+ const name = "eslint-plugin-perfectionist";
2
+ export {
3
+ name
4
+ };
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const createEslintRule = require("../utils/create-eslint-rule.js");
4
+ const toSingleLine = require("../utils/to-single-line.js");
5
+ const rangeToDiff = require("../utils/range-to-diff.js");
6
+ const isPositive = require("../utils/is-positive.js");
7
+ const index = require("../typings/index.js");
8
+ const sortNodes = require("../utils/sort-nodes.js");
9
+ const makeFixes = require("../utils/make-fixes.js");
10
+ const complete = require("../utils/complete.js");
11
+ const pairwise = require("../utils/pairwise.js");
12
+ const compare = require("../utils/compare.js");
13
+ const RULE_NAME = "sort-array-includes";
14
+ const sortArrayIncludes = createEslintRule.createEslintRule({
15
+ name: RULE_NAME,
16
+ meta: {
17
+ type: "suggestion",
18
+ docs: {
19
+ description: "enforce sorted arrays before include method"
20
+ },
21
+ fixable: "code",
22
+ schema: [
23
+ {
24
+ type: "object",
25
+ properties: {
26
+ type: {
27
+ enum: [
28
+ index.SortType.alphabetical,
29
+ index.SortType.natural,
30
+ index.SortType["line-length"]
31
+ ],
32
+ default: index.SortType.alphabetical,
33
+ type: "string"
34
+ },
35
+ order: {
36
+ enum: [index.SortOrder.asc, index.SortOrder.desc],
37
+ default: index.SortOrder.asc,
38
+ type: "string"
39
+ },
40
+ "ignore-case": {
41
+ type: "boolean",
42
+ default: false
43
+ },
44
+ "spread-last": {
45
+ type: "boolean",
46
+ default: false
47
+ }
48
+ },
49
+ additionalProperties: false
50
+ }
51
+ ],
52
+ messages: {
53
+ unexpectedArrayIncludesOrder: 'Expected "{{right}}" to come before "{{left}}"'
54
+ }
55
+ },
56
+ defaultOptions: [
57
+ {
58
+ type: index.SortType.alphabetical,
59
+ order: index.SortOrder.asc
60
+ }
61
+ ],
62
+ create: (context) => ({
63
+ MemberExpression: (node) => {
64
+ if ((node.object.type === "ArrayExpression" || node.object.type === "NewExpression") && node.property.type === "Identifier" && node.property.name === "includes") {
65
+ let elements = node.object.type === "ArrayExpression" ? node.object.elements : node.object.arguments;
66
+ if (elements.length > 1) {
67
+ let options = complete.complete(context.options.at(0), {
68
+ type: index.SortType.alphabetical,
69
+ order: index.SortOrder.asc,
70
+ "ignore-case": false,
71
+ "spread-last": false
72
+ });
73
+ let nodes = elements.reduce(
74
+ (accumulator, element) => {
75
+ if (element !== null) {
76
+ accumulator.at(0).push({
77
+ name: element.type === "Literal" ? `${element.value}` : context.sourceCode.text.slice(...element.range),
78
+ size: rangeToDiff.rangeToDiff(element.range),
79
+ type: element.type,
80
+ node: element
81
+ });
82
+ }
83
+ return accumulator;
84
+ },
85
+ [[], []]
86
+ ).flat();
87
+ pairwise.pairwise(nodes, (left, right) => {
88
+ let compareValue;
89
+ if (options["spread-last"] && left.node.type === "Literal" && right.node.type === "SpreadElement") {
90
+ compareValue = false;
91
+ } else if (options["spread-last"] && left.node.type === "SpreadElement" && right.node.type === "Literal") {
92
+ compareValue = true;
93
+ } else {
94
+ compareValue = isPositive.isPositive(compare.compare(left, right, options));
95
+ }
96
+ if (compareValue) {
97
+ context.report({
98
+ messageId: "unexpectedArrayIncludesOrder",
99
+ data: {
100
+ left: toSingleLine.toSingleLine(left.name),
101
+ right: toSingleLine.toSingleLine(right.name)
102
+ },
103
+ node: right.node,
104
+ fix: (fixer) => {
105
+ let sortedNodes = sortNodes.sortNodes(nodes, options);
106
+ if (options["spread-last"]) {
107
+ for (let i = 0, max = sortedNodes.length; i < max; i++) {
108
+ if (sortedNodes.at(i).node.type === "SpreadElement") {
109
+ sortedNodes.push(sortedNodes.splice(i, 1).at(0));
110
+ }
111
+ }
112
+ }
113
+ return makeFixes.makeFixes(
114
+ fixer,
115
+ nodes,
116
+ sortedNodes,
117
+ context.sourceCode
118
+ );
119
+ }
120
+ });
121
+ }
122
+ });
123
+ }
124
+ }
125
+ }
126
+ })
127
+ });
128
+ exports.RULE_NAME = RULE_NAME;
129
+ exports.default = sortArrayIncludes;
@@ -0,0 +1,129 @@
1
+ import { createEslintRule } from "../utils/create-eslint-rule.mjs";
2
+ import { toSingleLine } from "../utils/to-single-line.mjs";
3
+ import { rangeToDiff } from "../utils/range-to-diff.mjs";
4
+ import { isPositive } from "../utils/is-positive.mjs";
5
+ import { SortType, SortOrder } from "../typings/index.mjs";
6
+ import { sortNodes } from "../utils/sort-nodes.mjs";
7
+ import { makeFixes } from "../utils/make-fixes.mjs";
8
+ import { complete } from "../utils/complete.mjs";
9
+ import { pairwise } from "../utils/pairwise.mjs";
10
+ import { compare } from "../utils/compare.mjs";
11
+ const RULE_NAME = "sort-array-includes";
12
+ const sortArrayIncludes = createEslintRule({
13
+ name: RULE_NAME,
14
+ meta: {
15
+ type: "suggestion",
16
+ docs: {
17
+ description: "enforce sorted arrays before include method"
18
+ },
19
+ fixable: "code",
20
+ schema: [
21
+ {
22
+ type: "object",
23
+ properties: {
24
+ type: {
25
+ enum: [
26
+ SortType.alphabetical,
27
+ SortType.natural,
28
+ SortType["line-length"]
29
+ ],
30
+ default: SortType.alphabetical,
31
+ type: "string"
32
+ },
33
+ order: {
34
+ enum: [SortOrder.asc, SortOrder.desc],
35
+ default: SortOrder.asc,
36
+ type: "string"
37
+ },
38
+ "ignore-case": {
39
+ type: "boolean",
40
+ default: false
41
+ },
42
+ "spread-last": {
43
+ type: "boolean",
44
+ default: false
45
+ }
46
+ },
47
+ additionalProperties: false
48
+ }
49
+ ],
50
+ messages: {
51
+ unexpectedArrayIncludesOrder: 'Expected "{{right}}" to come before "{{left}}"'
52
+ }
53
+ },
54
+ defaultOptions: [
55
+ {
56
+ type: SortType.alphabetical,
57
+ order: SortOrder.asc
58
+ }
59
+ ],
60
+ create: (context) => ({
61
+ MemberExpression: (node) => {
62
+ if ((node.object.type === "ArrayExpression" || node.object.type === "NewExpression") && node.property.type === "Identifier" && node.property.name === "includes") {
63
+ let elements = node.object.type === "ArrayExpression" ? node.object.elements : node.object.arguments;
64
+ if (elements.length > 1) {
65
+ let options = complete(context.options.at(0), {
66
+ type: SortType.alphabetical,
67
+ order: SortOrder.asc,
68
+ "ignore-case": false,
69
+ "spread-last": false
70
+ });
71
+ let nodes = elements.reduce(
72
+ (accumulator, element) => {
73
+ if (element !== null) {
74
+ accumulator.at(0).push({
75
+ name: element.type === "Literal" ? `${element.value}` : context.sourceCode.text.slice(...element.range),
76
+ size: rangeToDiff(element.range),
77
+ type: element.type,
78
+ node: element
79
+ });
80
+ }
81
+ return accumulator;
82
+ },
83
+ [[], []]
84
+ ).flat();
85
+ pairwise(nodes, (left, right) => {
86
+ let compareValue;
87
+ if (options["spread-last"] && left.node.type === "Literal" && right.node.type === "SpreadElement") {
88
+ compareValue = false;
89
+ } else if (options["spread-last"] && left.node.type === "SpreadElement" && right.node.type === "Literal") {
90
+ compareValue = true;
91
+ } else {
92
+ compareValue = isPositive(compare(left, right, options));
93
+ }
94
+ if (compareValue) {
95
+ context.report({
96
+ messageId: "unexpectedArrayIncludesOrder",
97
+ data: {
98
+ left: toSingleLine(left.name),
99
+ right: toSingleLine(right.name)
100
+ },
101
+ node: right.node,
102
+ fix: (fixer) => {
103
+ let sortedNodes = sortNodes(nodes, options);
104
+ if (options["spread-last"]) {
105
+ for (let i = 0, max = sortedNodes.length; i < max; i++) {
106
+ if (sortedNodes.at(i).node.type === "SpreadElement") {
107
+ sortedNodes.push(sortedNodes.splice(i, 1).at(0));
108
+ }
109
+ }
110
+ }
111
+ return makeFixes(
112
+ fixer,
113
+ nodes,
114
+ sortedNodes,
115
+ context.sourceCode
116
+ );
117
+ }
118
+ });
119
+ }
120
+ });
121
+ }
122
+ }
123
+ }
124
+ })
125
+ });
126
+ export {
127
+ RULE_NAME,
128
+ sortArrayIncludes as default
129
+ };
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const path = require("node:path");
4
+ const createEslintRule = require("../utils/create-eslint-rule.js");
5
+ const getGroupNumber = require("../utils/get-group-number.js");
6
+ const rangeToDiff = require("../utils/range-to-diff.js");
7
+ const isPositive = require("../utils/is-positive.js");
8
+ const index = require("../typings/index.js");
9
+ const useGroups = require("../utils/use-groups.js");
10
+ const makeFixes = require("../utils/make-fixes.js");
11
+ const sortNodes = require("../utils/sort-nodes.js");
12
+ const pairwise = require("../utils/pairwise.js");
13
+ const complete = require("../utils/complete.js");
14
+ const compare = require("../utils/compare.js");
15
+ const RULE_NAME = "sort-astro-attributes";
16
+ const sortAstroAttributes = createEslintRule.createEslintRule({
17
+ name: RULE_NAME,
18
+ meta: {
19
+ type: "suggestion",
20
+ docs: {
21
+ description: "enforce sorted Astro attributes"
22
+ },
23
+ fixable: "code",
24
+ schema: [
25
+ {
26
+ type: "object",
27
+ properties: {
28
+ "custom-groups": {
29
+ type: "object"
30
+ },
31
+ type: {
32
+ enum: [
33
+ index.SortType.alphabetical,
34
+ index.SortType.natural,
35
+ index.SortType["line-length"]
36
+ ],
37
+ default: index.SortType.alphabetical,
38
+ type: "string"
39
+ },
40
+ order: {
41
+ enum: [index.SortOrder.asc, index.SortOrder.desc],
42
+ default: index.SortOrder.asc,
43
+ type: "string"
44
+ },
45
+ "ignore-case": {
46
+ type: "boolean",
47
+ default: false
48
+ },
49
+ groups: {
50
+ type: "array"
51
+ }
52
+ },
53
+ additionalProperties: false
54
+ }
55
+ ],
56
+ messages: {
57
+ unexpectedAstroAttributesOrder: 'Expected "{{right}}" to come before "{{left}}"'
58
+ }
59
+ },
60
+ defaultOptions: [
61
+ {
62
+ type: index.SortType.alphabetical,
63
+ order: index.SortOrder.asc
64
+ }
65
+ ],
66
+ // @ts-ignore
67
+ create: (context) => {
68
+ if (path.extname(context.filename) !== ".astro") {
69
+ return {};
70
+ }
71
+ return {
72
+ JSXElement: (node) => {
73
+ let { attributes } = node.openingElement;
74
+ if (attributes.length > 1) {
75
+ let options = complete.complete(context.options.at(0), {
76
+ type: index.SortType.alphabetical,
77
+ order: index.SortOrder.asc,
78
+ "ignore-case": false,
79
+ "custom-groups": {},
80
+ groups: []
81
+ });
82
+ let parts = attributes.reduce(
83
+ (accumulator, attribute) => {
84
+ if (attribute.type === "JSXSpreadAttribute") {
85
+ accumulator.push([]);
86
+ return accumulator;
87
+ }
88
+ let name = typeof attribute.name.name === "string" ? attribute.name.name : context.sourceCode.text.slice(...attribute.name.range);
89
+ let { getGroup, defineGroup, setCustomGroups } = useGroups.useGroups(
90
+ options.groups
91
+ );
92
+ setCustomGroups(options["custom-groups"], name);
93
+ if (attribute.type === "AstroShorthandAttribute") {
94
+ defineGroup("astro-shorthand");
95
+ defineGroup("shorthand");
96
+ }
97
+ if (attribute.value === null) {
98
+ defineGroup("shorthand");
99
+ }
100
+ if (attribute.loc.start.line !== attribute.loc.end.line) {
101
+ defineGroup("multiline");
102
+ }
103
+ accumulator.at(-1).push({
104
+ size: rangeToDiff.rangeToDiff(attribute.range),
105
+ node: attribute,
106
+ group: getGroup(),
107
+ name
108
+ });
109
+ return accumulator;
110
+ },
111
+ [[]]
112
+ );
113
+ for (let nodes of parts) {
114
+ pairwise.pairwise(nodes, (left, right) => {
115
+ let leftNum = getGroupNumber.getGroupNumber(options.groups, left);
116
+ let rightNum = getGroupNumber.getGroupNumber(options.groups, right);
117
+ if (leftNum > rightNum || leftNum === rightNum && isPositive.isPositive(compare.compare(left, right, options))) {
118
+ context.report({
119
+ messageId: "unexpectedAstroAttributesOrder",
120
+ data: {
121
+ left: left.name,
122
+ right: right.name
123
+ },
124
+ node: right.node,
125
+ fix: (fixer) => {
126
+ let grouped = {};
127
+ for (let currentNode of nodes) {
128
+ let groupNum = getGroupNumber.getGroupNumber(options.groups, currentNode);
129
+ if (!(groupNum in grouped)) {
130
+ grouped[groupNum] = [currentNode];
131
+ } else {
132
+ grouped[groupNum] = sortNodes.sortNodes(
133
+ [...grouped[groupNum], currentNode],
134
+ options
135
+ );
136
+ }
137
+ }
138
+ let sortedNodes = [];
139
+ for (let group of Object.keys(grouped).sort(
140
+ (a, b) => Number(a) - Number(b)
141
+ )) {
142
+ sortedNodes.push(...sortNodes.sortNodes(grouped[group], options));
143
+ }
144
+ return makeFixes.makeFixes(
145
+ fixer,
146
+ nodes,
147
+ sortedNodes,
148
+ context.sourceCode
149
+ );
150
+ }
151
+ });
152
+ }
153
+ });
154
+ }
155
+ }
156
+ }
157
+ };
158
+ }
159
+ });
160
+ exports.RULE_NAME = RULE_NAME;
161
+ exports.default = sortAstroAttributes;
@@ -0,0 +1,161 @@
1
+ import path from "node:path";
2
+ import { createEslintRule } from "../utils/create-eslint-rule.mjs";
3
+ import { getGroupNumber } from "../utils/get-group-number.mjs";
4
+ import { rangeToDiff } from "../utils/range-to-diff.mjs";
5
+ import { isPositive } from "../utils/is-positive.mjs";
6
+ import { SortType, SortOrder } from "../typings/index.mjs";
7
+ import { useGroups } from "../utils/use-groups.mjs";
8
+ import { makeFixes } from "../utils/make-fixes.mjs";
9
+ import { sortNodes } from "../utils/sort-nodes.mjs";
10
+ import { pairwise } from "../utils/pairwise.mjs";
11
+ import { complete } from "../utils/complete.mjs";
12
+ import { compare } from "../utils/compare.mjs";
13
+ const RULE_NAME = "sort-astro-attributes";
14
+ const sortAstroAttributes = createEslintRule({
15
+ name: RULE_NAME,
16
+ meta: {
17
+ type: "suggestion",
18
+ docs: {
19
+ description: "enforce sorted Astro attributes"
20
+ },
21
+ fixable: "code",
22
+ schema: [
23
+ {
24
+ type: "object",
25
+ properties: {
26
+ "custom-groups": {
27
+ type: "object"
28
+ },
29
+ type: {
30
+ enum: [
31
+ SortType.alphabetical,
32
+ SortType.natural,
33
+ SortType["line-length"]
34
+ ],
35
+ default: SortType.alphabetical,
36
+ type: "string"
37
+ },
38
+ order: {
39
+ enum: [SortOrder.asc, SortOrder.desc],
40
+ default: SortOrder.asc,
41
+ type: "string"
42
+ },
43
+ "ignore-case": {
44
+ type: "boolean",
45
+ default: false
46
+ },
47
+ groups: {
48
+ type: "array"
49
+ }
50
+ },
51
+ additionalProperties: false
52
+ }
53
+ ],
54
+ messages: {
55
+ unexpectedAstroAttributesOrder: 'Expected "{{right}}" to come before "{{left}}"'
56
+ }
57
+ },
58
+ defaultOptions: [
59
+ {
60
+ type: SortType.alphabetical,
61
+ order: SortOrder.asc
62
+ }
63
+ ],
64
+ // @ts-ignore
65
+ create: (context) => {
66
+ if (path.extname(context.filename) !== ".astro") {
67
+ return {};
68
+ }
69
+ return {
70
+ JSXElement: (node) => {
71
+ let { attributes } = node.openingElement;
72
+ if (attributes.length > 1) {
73
+ let options = complete(context.options.at(0), {
74
+ type: SortType.alphabetical,
75
+ order: SortOrder.asc,
76
+ "ignore-case": false,
77
+ "custom-groups": {},
78
+ groups: []
79
+ });
80
+ let parts = attributes.reduce(
81
+ (accumulator, attribute) => {
82
+ if (attribute.type === "JSXSpreadAttribute") {
83
+ accumulator.push([]);
84
+ return accumulator;
85
+ }
86
+ let name = typeof attribute.name.name === "string" ? attribute.name.name : context.sourceCode.text.slice(...attribute.name.range);
87
+ let { getGroup, defineGroup, setCustomGroups } = useGroups(
88
+ options.groups
89
+ );
90
+ setCustomGroups(options["custom-groups"], name);
91
+ if (attribute.type === "AstroShorthandAttribute") {
92
+ defineGroup("astro-shorthand");
93
+ defineGroup("shorthand");
94
+ }
95
+ if (attribute.value === null) {
96
+ defineGroup("shorthand");
97
+ }
98
+ if (attribute.loc.start.line !== attribute.loc.end.line) {
99
+ defineGroup("multiline");
100
+ }
101
+ accumulator.at(-1).push({
102
+ size: rangeToDiff(attribute.range),
103
+ node: attribute,
104
+ group: getGroup(),
105
+ name
106
+ });
107
+ return accumulator;
108
+ },
109
+ [[]]
110
+ );
111
+ for (let nodes of parts) {
112
+ pairwise(nodes, (left, right) => {
113
+ let leftNum = getGroupNumber(options.groups, left);
114
+ let rightNum = getGroupNumber(options.groups, right);
115
+ if (leftNum > rightNum || leftNum === rightNum && isPositive(compare(left, right, options))) {
116
+ context.report({
117
+ messageId: "unexpectedAstroAttributesOrder",
118
+ data: {
119
+ left: left.name,
120
+ right: right.name
121
+ },
122
+ node: right.node,
123
+ fix: (fixer) => {
124
+ let grouped = {};
125
+ for (let currentNode of nodes) {
126
+ let groupNum = getGroupNumber(options.groups, currentNode);
127
+ if (!(groupNum in grouped)) {
128
+ grouped[groupNum] = [currentNode];
129
+ } else {
130
+ grouped[groupNum] = sortNodes(
131
+ [...grouped[groupNum], currentNode],
132
+ options
133
+ );
134
+ }
135
+ }
136
+ let sortedNodes = [];
137
+ for (let group of Object.keys(grouped).sort(
138
+ (a, b) => Number(a) - Number(b)
139
+ )) {
140
+ sortedNodes.push(...sortNodes(grouped[group], options));
141
+ }
142
+ return makeFixes(
143
+ fixer,
144
+ nodes,
145
+ sortedNodes,
146
+ context.sourceCode
147
+ );
148
+ }
149
+ });
150
+ }
151
+ });
152
+ }
153
+ }
154
+ }
155
+ };
156
+ }
157
+ });
158
+ export {
159
+ RULE_NAME,
160
+ sortAstroAttributes as default
161
+ };