eslint-plugin-perfectionist 2.7.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 -10
  3. package/dist/configs/recommended-line-length.js +9 -1
  4. package/dist/configs/recommended-line-length.mjs +5 -10
  5. package/dist/configs/recommended-natural.js +9 -1
  6. package/dist/configs/recommended-natural.mjs +5 -10
  7. package/dist/index.js +135 -3
  8. package/dist/index.mjs +76 -2197
  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,253 @@
1
+ import { minimatch } from "minimatch";
2
+ import { OptionalityOrder, SortType, SortOrder } from "../typings/index.mjs";
3
+ import { createEslintRule } from "../utils/create-eslint-rule.mjs";
4
+ import { isMemberOptional } from "../utils/is-member-optional.mjs";
5
+ import { getLinesBetween } from "../utils/get-lines-between.mjs";
6
+ import { getGroupNumber } from "../utils/get-group-number.mjs";
7
+ import { toSingleLine } from "../utils/to-single-line.mjs";
8
+ import { rangeToDiff } from "../utils/range-to-diff.mjs";
9
+ import { isPositive } from "../utils/is-positive.mjs";
10
+ import { useGroups } from "../utils/use-groups.mjs";
11
+ import { sortNodes } from "../utils/sort-nodes.mjs";
12
+ import { makeFixes } from "../utils/make-fixes.mjs";
13
+ import { complete } from "../utils/complete.mjs";
14
+ import { pairwise } from "../utils/pairwise.mjs";
15
+ import { compare } from "../utils/compare.mjs";
16
+ const RULE_NAME = "sort-interfaces";
17
+ const sortInterfaces = createEslintRule({
18
+ name: RULE_NAME,
19
+ meta: {
20
+ type: "suggestion",
21
+ docs: {
22
+ description: "enforce sorted interface properties"
23
+ },
24
+ fixable: "code",
25
+ schema: [
26
+ {
27
+ type: "object",
28
+ properties: {
29
+ "custom-groups": {
30
+ type: "object"
31
+ },
32
+ "optionality-order": {
33
+ enum: [
34
+ OptionalityOrder.ignore,
35
+ OptionalityOrder["optional-first"],
36
+ OptionalityOrder["required-first"]
37
+ ],
38
+ default: OptionalityOrder.ignore,
39
+ type: "string"
40
+ },
41
+ type: {
42
+ enum: [
43
+ SortType.alphabetical,
44
+ SortType.natural,
45
+ SortType["line-length"]
46
+ ],
47
+ default: SortType.alphabetical,
48
+ type: "string"
49
+ },
50
+ order: {
51
+ enum: [SortOrder.asc, SortOrder.desc],
52
+ default: SortOrder.asc,
53
+ type: "string"
54
+ },
55
+ "ignore-case": {
56
+ type: "boolean",
57
+ default: false
58
+ },
59
+ "ignore-pattern": {
60
+ items: {
61
+ type: "string"
62
+ },
63
+ type: "array"
64
+ },
65
+ groups: {
66
+ type: "array",
67
+ default: []
68
+ },
69
+ "partition-by-new-line": {
70
+ type: "boolean",
71
+ default: false
72
+ }
73
+ },
74
+ additionalProperties: false
75
+ }
76
+ ],
77
+ messages: {
78
+ unexpectedInterfacePropertiesOrder: 'Expected "{{right}}" to come before "{{left}}"'
79
+ }
80
+ },
81
+ defaultOptions: [
82
+ {
83
+ type: SortType.alphabetical,
84
+ order: SortOrder.asc
85
+ }
86
+ ],
87
+ create: (context) => ({
88
+ TSInterfaceDeclaration: (node) => {
89
+ if (node.body.body.length > 1) {
90
+ let options = complete(context.options.at(0), {
91
+ "optionality-order": OptionalityOrder.ignore,
92
+ "partition-by-new-line": false,
93
+ type: SortType.alphabetical,
94
+ "ignore-case": false,
95
+ order: SortOrder.asc,
96
+ "ignore-pattern": [],
97
+ "custom-groups": {},
98
+ groups: []
99
+ });
100
+ if (!options["ignore-pattern"].some(
101
+ (pattern) => minimatch(node.id.name, pattern, {
102
+ nocomment: true
103
+ })
104
+ )) {
105
+ let formattedMembers = node.body.body.reduce(
106
+ (accumulator, element) => {
107
+ var _a, _b, _c, _d;
108
+ if (element.type === "TSCallSignatureDeclaration") {
109
+ accumulator.push([]);
110
+ return accumulator;
111
+ }
112
+ let lastElement = (_a = accumulator.at(-1)) == null ? void 0 : _a.at(-1);
113
+ let name;
114
+ let { getGroup, defineGroup, setCustomGroups } = useGroups(
115
+ options.groups
116
+ );
117
+ if (element.type === "TSPropertySignature") {
118
+ if (element.key.type === "Identifier") {
119
+ ({ name } = element.key);
120
+ } else if (element.key.type === "Literal") {
121
+ name = `${element.key.value}`;
122
+ } else {
123
+ let end = ((_b = element.typeAnnotation) == null ? void 0 : _b.range.at(0)) ?? element.range.at(1) - (element.optional ? "?".length : 0);
124
+ name = context.sourceCode.text.slice(element.range.at(0), end);
125
+ }
126
+ } else if (element.type === "TSIndexSignature") {
127
+ let endIndex = ((_c = element.typeAnnotation) == null ? void 0 : _c.range.at(0)) ?? element.range.at(1);
128
+ name = context.sourceCode.text.slice(
129
+ element.range.at(0),
130
+ endIndex
131
+ );
132
+ } else {
133
+ let endIndex = ((_d = element.returnType) == null ? void 0 : _d.range.at(0)) ?? element.range.at(1);
134
+ name = context.sourceCode.text.slice(
135
+ element.range.at(0),
136
+ endIndex
137
+ );
138
+ }
139
+ let elementSortingNode = {
140
+ size: rangeToDiff(element.range),
141
+ node: element,
142
+ name
143
+ };
144
+ if (options["partition-by-new-line"] && lastElement && getLinesBetween(
145
+ context.sourceCode,
146
+ lastElement,
147
+ elementSortingNode
148
+ )) {
149
+ accumulator.push([]);
150
+ }
151
+ setCustomGroups(options["custom-groups"], name);
152
+ if (element.loc.start.line !== element.loc.end.line) {
153
+ defineGroup("multiline");
154
+ }
155
+ accumulator.at(-1).push({
156
+ ...elementSortingNode,
157
+ group: getGroup()
158
+ });
159
+ return accumulator;
160
+ },
161
+ [[]]
162
+ );
163
+ let toSorted = (nodes) => {
164
+ let grouped = {};
165
+ for (let currentNode of nodes) {
166
+ let groupNum = getGroupNumber(options.groups, currentNode);
167
+ if (!(groupNum in grouped)) {
168
+ grouped[groupNum] = [currentNode];
169
+ } else {
170
+ grouped[groupNum] = sortNodes(
171
+ [...grouped[groupNum], currentNode],
172
+ options
173
+ );
174
+ }
175
+ }
176
+ let sortedNodes = [];
177
+ for (let group of Object.keys(grouped).sort(
178
+ (a, b) => Number(a) - Number(b)
179
+ )) {
180
+ sortedNodes.push(...sortNodes(grouped[group], options));
181
+ }
182
+ return sortedNodes;
183
+ };
184
+ let checkGroupSort = (left, right) => {
185
+ let leftNum = getGroupNumber(options.groups, left);
186
+ let rightNum = getGroupNumber(options.groups, right);
187
+ return leftNum > rightNum || leftNum === rightNum && isPositive(compare(left, right, options));
188
+ };
189
+ let optionalityOrder = options["optionality-order"];
190
+ let checkOrder = (members, left, right, iteration) => {
191
+ if (optionalityOrder === OptionalityOrder.ignore) {
192
+ return checkGroupSort(left, right);
193
+ }
194
+ let switchIndex = members.findIndex(
195
+ (_, i) => i && isMemberOptional(members[i - 1].node) !== isMemberOptional(members[i].node)
196
+ );
197
+ if (iteration < switchIndex && iteration + 1 !== switchIndex) {
198
+ return checkGroupSort(left, right);
199
+ }
200
+ if (isMemberOptional(left.node) !== isMemberOptional(right.node)) {
201
+ return isMemberOptional(left.node) !== (optionalityOrder === OptionalityOrder["optional-first"]);
202
+ }
203
+ return checkGroupSort(left, right);
204
+ };
205
+ for (let nodes of formattedMembers) {
206
+ pairwise(nodes, (left, right, iteration) => {
207
+ if (checkOrder(nodes, left, right, iteration)) {
208
+ context.report({
209
+ messageId: "unexpectedInterfacePropertiesOrder",
210
+ data: {
211
+ left: toSingleLine(left.name),
212
+ right: toSingleLine(right.name)
213
+ },
214
+ node: right.node,
215
+ fix: (fixer) => {
216
+ let sortedNodes;
217
+ if (optionalityOrder !== OptionalityOrder.ignore) {
218
+ let optionalNodes = nodes.filter(
219
+ (member) => isMemberOptional(member.node)
220
+ );
221
+ let requiredNodes = nodes.filter(
222
+ (member) => !isMemberOptional(member.node)
223
+ );
224
+ sortedNodes = optionalityOrder === OptionalityOrder["optional-first"] ? [
225
+ ...toSorted(optionalNodes),
226
+ ...toSorted(requiredNodes)
227
+ ] : [
228
+ ...toSorted(requiredNodes),
229
+ ...toSorted(optionalNodes)
230
+ ];
231
+ } else {
232
+ sortedNodes = toSorted(nodes);
233
+ }
234
+ return makeFixes(
235
+ fixer,
236
+ nodes,
237
+ sortedNodes,
238
+ context.sourceCode
239
+ );
240
+ }
241
+ });
242
+ }
243
+ });
244
+ }
245
+ }
246
+ }
247
+ }
248
+ })
249
+ });
250
+ export {
251
+ RULE_NAME,
252
+ sortInterfaces as default
253
+ };
@@ -0,0 +1,92 @@
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-intersection-types";
14
+ const sortIntersectionTypes = createEslintRule.createEslintRule({
15
+ name: RULE_NAME,
16
+ meta: {
17
+ type: "suggestion",
18
+ docs: {
19
+ description: "enforce sorted intersection types"
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
+ },
45
+ additionalProperties: false
46
+ }
47
+ ],
48
+ messages: {
49
+ unexpectedIntersectionTypesOrder: 'Expected "{{right}}" to come before "{{left}}"'
50
+ }
51
+ },
52
+ defaultOptions: [
53
+ {
54
+ type: index.SortType.alphabetical,
55
+ order: index.SortOrder.asc
56
+ }
57
+ ],
58
+ create: (context) => ({
59
+ TSIntersectionType: (node) => {
60
+ let options = complete.complete(context.options.at(0), {
61
+ type: index.SortType.alphabetical,
62
+ "ignore-case": false,
63
+ order: index.SortOrder.asc
64
+ });
65
+ let nodes = node.types.map((type) => ({
66
+ group: type.type === "TSNullKeyword" || type.type === "TSUndefinedKeyword" ? "nullable" : "unknown",
67
+ name: context.sourceCode.text.slice(...type.range),
68
+ size: rangeToDiff.rangeToDiff(type.range),
69
+ node: type
70
+ }));
71
+ pairwise.pairwise(nodes, (left, right) => {
72
+ let compareValue = isPositive.isPositive(compare.compare(left, right, options));
73
+ if (compareValue) {
74
+ context.report({
75
+ messageId: "unexpectedIntersectionTypesOrder",
76
+ data: {
77
+ left: toSingleLine.toSingleLine(left.name),
78
+ right: toSingleLine.toSingleLine(right.name)
79
+ },
80
+ node: right.node,
81
+ fix: (fixer) => {
82
+ let sortedNodes = sortNodes.sortNodes(nodes, options);
83
+ return makeFixes.makeFixes(fixer, nodes, sortedNodes, context.sourceCode);
84
+ }
85
+ });
86
+ }
87
+ });
88
+ }
89
+ })
90
+ });
91
+ exports.RULE_NAME = RULE_NAME;
92
+ exports.default = sortIntersectionTypes;
@@ -0,0 +1,92 @@
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-intersection-types";
12
+ const sortIntersectionTypes = createEslintRule({
13
+ name: RULE_NAME,
14
+ meta: {
15
+ type: "suggestion",
16
+ docs: {
17
+ description: "enforce sorted intersection types"
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
+ },
43
+ additionalProperties: false
44
+ }
45
+ ],
46
+ messages: {
47
+ unexpectedIntersectionTypesOrder: 'Expected "{{right}}" to come before "{{left}}"'
48
+ }
49
+ },
50
+ defaultOptions: [
51
+ {
52
+ type: SortType.alphabetical,
53
+ order: SortOrder.asc
54
+ }
55
+ ],
56
+ create: (context) => ({
57
+ TSIntersectionType: (node) => {
58
+ let options = complete(context.options.at(0), {
59
+ type: SortType.alphabetical,
60
+ "ignore-case": false,
61
+ order: SortOrder.asc
62
+ });
63
+ let nodes = node.types.map((type) => ({
64
+ group: type.type === "TSNullKeyword" || type.type === "TSUndefinedKeyword" ? "nullable" : "unknown",
65
+ name: context.sourceCode.text.slice(...type.range),
66
+ size: rangeToDiff(type.range),
67
+ node: type
68
+ }));
69
+ pairwise(nodes, (left, right) => {
70
+ let compareValue = isPositive(compare(left, right, options));
71
+ if (compareValue) {
72
+ context.report({
73
+ messageId: "unexpectedIntersectionTypesOrder",
74
+ data: {
75
+ left: toSingleLine(left.name),
76
+ right: toSingleLine(right.name)
77
+ },
78
+ node: right.node,
79
+ fix: (fixer) => {
80
+ let sortedNodes = sortNodes(nodes, options);
81
+ return makeFixes(fixer, nodes, sortedNodes, context.sourceCode);
82
+ }
83
+ });
84
+ }
85
+ });
86
+ }
87
+ })
88
+ });
89
+ export {
90
+ RULE_NAME,
91
+ sortIntersectionTypes as default
92
+ };
@@ -0,0 +1,156 @@
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-jsx-props";
16
+ const sortJsxProps = createEslintRule.createEslintRule({
17
+ name: RULE_NAME,
18
+ meta: {
19
+ type: "suggestion",
20
+ docs: {
21
+ description: "enforce sorted JSX props"
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
+ groups: {
46
+ type: "array"
47
+ },
48
+ "ignore-case": {
49
+ type: "boolean",
50
+ default: false
51
+ }
52
+ },
53
+ additionalProperties: false
54
+ }
55
+ ],
56
+ messages: {
57
+ unexpectedJSXPropsOrder: 'Expected "{{right}}" to come before "{{left}}"'
58
+ }
59
+ },
60
+ defaultOptions: [
61
+ {
62
+ type: index.SortType.alphabetical,
63
+ order: index.SortOrder.asc
64
+ }
65
+ ],
66
+ create: (context) => {
67
+ if ([".svelte", ".astro", ".vue"].includes(path.extname(context.filename))) {
68
+ return {};
69
+ }
70
+ return {
71
+ JSXElement: (node) => {
72
+ if (node.openingElement.attributes.length > 1) {
73
+ let options = complete.complete(context.options.at(0), {
74
+ type: index.SortType.alphabetical,
75
+ "ignore-case": false,
76
+ order: index.SortOrder.asc,
77
+ "custom-groups": {},
78
+ groups: []
79
+ });
80
+ let parts = node.openingElement.attributes.reduce(
81
+ (accumulator, attribute) => {
82
+ if (attribute.type === "JSXSpreadAttribute") {
83
+ accumulator.push([]);
84
+ return accumulator;
85
+ }
86
+ let name = attribute.name.type === "JSXNamespacedName" ? `${attribute.name.namespace.name}:${attribute.name.name.name}` : attribute.name.name;
87
+ let { getGroup, defineGroup, setCustomGroups } = useGroups.useGroups(
88
+ options.groups
89
+ );
90
+ setCustomGroups(options["custom-groups"], name);
91
+ if (attribute.value === null) {
92
+ defineGroup("shorthand");
93
+ }
94
+ if (attribute.loc.start.line !== attribute.loc.end.line) {
95
+ defineGroup("multiline");
96
+ }
97
+ let jsxNode = {
98
+ size: rangeToDiff.rangeToDiff(attribute.range),
99
+ group: getGroup(),
100
+ node: attribute,
101
+ name
102
+ };
103
+ accumulator.at(-1).push(jsxNode);
104
+ return accumulator;
105
+ },
106
+ [[]]
107
+ );
108
+ for (let nodes of parts) {
109
+ pairwise.pairwise(nodes, (left, right) => {
110
+ let leftNum = getGroupNumber.getGroupNumber(options.groups, left);
111
+ let rightNum = getGroupNumber.getGroupNumber(options.groups, right);
112
+ if (leftNum > rightNum || leftNum === rightNum && isPositive.isPositive(compare.compare(left, right, options))) {
113
+ context.report({
114
+ messageId: "unexpectedJSXPropsOrder",
115
+ data: {
116
+ left: left.name,
117
+ right: right.name
118
+ },
119
+ node: right.node,
120
+ fix: (fixer) => {
121
+ let grouped = {};
122
+ for (let currentNode of nodes) {
123
+ let groupNum = getGroupNumber.getGroupNumber(options.groups, currentNode);
124
+ if (!(groupNum in grouped)) {
125
+ grouped[groupNum] = [currentNode];
126
+ } else {
127
+ grouped[groupNum] = sortNodes.sortNodes(
128
+ [...grouped[groupNum], currentNode],
129
+ options
130
+ );
131
+ }
132
+ }
133
+ let sortedNodes = [];
134
+ for (let group of Object.keys(grouped).sort(
135
+ (a, b) => Number(a) - Number(b)
136
+ )) {
137
+ sortedNodes.push(...sortNodes.sortNodes(grouped[group], options));
138
+ }
139
+ return makeFixes.makeFixes(
140
+ fixer,
141
+ nodes,
142
+ sortedNodes,
143
+ context.sourceCode
144
+ );
145
+ }
146
+ });
147
+ }
148
+ });
149
+ }
150
+ }
151
+ }
152
+ };
153
+ }
154
+ });
155
+ exports.RULE_NAME = RULE_NAME;
156
+ exports.default = sortJsxProps;