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,104 @@
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 rangeToDiff = require("../utils/range-to-diff.js");
5
+ const isPositive = require("../utils/is-positive.js");
6
+ const index = require("../typings/index.js");
7
+ const sortNodes = require("../utils/sort-nodes.js");
8
+ const makeFixes = require("../utils/make-fixes.js");
9
+ const complete = require("../utils/complete.js");
10
+ const pairwise = require("../utils/pairwise.js");
11
+ const compare = require("../utils/compare.js");
12
+ const RULE_NAME = "sort-exports";
13
+ const sortExports = createEslintRule.createEslintRule({
14
+ name: RULE_NAME,
15
+ meta: {
16
+ type: "suggestion",
17
+ docs: {
18
+ description: "enforce sorted exports"
19
+ },
20
+ fixable: "code",
21
+ schema: [
22
+ {
23
+ type: "object",
24
+ properties: {
25
+ type: {
26
+ enum: [
27
+ index.SortType.alphabetical,
28
+ index.SortType.natural,
29
+ index.SortType["line-length"]
30
+ ],
31
+ default: index.SortType.alphabetical,
32
+ type: "string"
33
+ },
34
+ order: {
35
+ enum: [index.SortOrder.asc, index.SortOrder.desc],
36
+ default: index.SortOrder.asc,
37
+ type: "string"
38
+ },
39
+ "ignore-case": {
40
+ type: "boolean",
41
+ default: false
42
+ }
43
+ },
44
+ additionalProperties: false
45
+ }
46
+ ],
47
+ messages: {
48
+ unexpectedExportsOrder: 'Expected "{{right}}" to come before "{{left}}"'
49
+ }
50
+ },
51
+ defaultOptions: [
52
+ {
53
+ type: index.SortType.alphabetical,
54
+ order: index.SortOrder.asc
55
+ }
56
+ ],
57
+ create: (context) => {
58
+ let options = complete.complete(context.options.at(0), {
59
+ type: index.SortType.alphabetical,
60
+ order: index.SortOrder.asc,
61
+ "ignore-case": false
62
+ });
63
+ let parts = [[]];
64
+ let registerNode = (node) => {
65
+ parts.at(-1).push({
66
+ size: rangeToDiff.rangeToDiff(node.range),
67
+ name: node.source.value,
68
+ node
69
+ });
70
+ };
71
+ return {
72
+ ExportAllDeclaration: registerNode,
73
+ ExportNamedDeclaration: (node) => {
74
+ if (node.source !== null) {
75
+ registerNode(node);
76
+ }
77
+ },
78
+ "Program:exit": () => {
79
+ for (let nodes of parts) {
80
+ pairwise.pairwise(nodes, (left, right) => {
81
+ if (isPositive.isPositive(compare.compare(left, right, options))) {
82
+ context.report({
83
+ messageId: "unexpectedExportsOrder",
84
+ data: {
85
+ left: left.name,
86
+ right: right.name
87
+ },
88
+ node: right.node,
89
+ fix: (fixer) => makeFixes.makeFixes(
90
+ fixer,
91
+ nodes,
92
+ sortNodes.sortNodes(nodes, options),
93
+ context.sourceCode
94
+ )
95
+ });
96
+ }
97
+ });
98
+ }
99
+ }
100
+ };
101
+ }
102
+ });
103
+ exports.RULE_NAME = RULE_NAME;
104
+ exports.default = sortExports;
@@ -0,0 +1,104 @@
1
+ import { createEslintRule } from "../utils/create-eslint-rule.mjs";
2
+ import { rangeToDiff } from "../utils/range-to-diff.mjs";
3
+ import { isPositive } from "../utils/is-positive.mjs";
4
+ import { SortType, SortOrder } from "../typings/index.mjs";
5
+ import { sortNodes } from "../utils/sort-nodes.mjs";
6
+ import { makeFixes } from "../utils/make-fixes.mjs";
7
+ import { complete } from "../utils/complete.mjs";
8
+ import { pairwise } from "../utils/pairwise.mjs";
9
+ import { compare } from "../utils/compare.mjs";
10
+ const RULE_NAME = "sort-exports";
11
+ const sortExports = createEslintRule({
12
+ name: RULE_NAME,
13
+ meta: {
14
+ type: "suggestion",
15
+ docs: {
16
+ description: "enforce sorted exports"
17
+ },
18
+ fixable: "code",
19
+ schema: [
20
+ {
21
+ type: "object",
22
+ properties: {
23
+ type: {
24
+ enum: [
25
+ SortType.alphabetical,
26
+ SortType.natural,
27
+ SortType["line-length"]
28
+ ],
29
+ default: SortType.alphabetical,
30
+ type: "string"
31
+ },
32
+ order: {
33
+ enum: [SortOrder.asc, SortOrder.desc],
34
+ default: SortOrder.asc,
35
+ type: "string"
36
+ },
37
+ "ignore-case": {
38
+ type: "boolean",
39
+ default: false
40
+ }
41
+ },
42
+ additionalProperties: false
43
+ }
44
+ ],
45
+ messages: {
46
+ unexpectedExportsOrder: 'Expected "{{right}}" to come before "{{left}}"'
47
+ }
48
+ },
49
+ defaultOptions: [
50
+ {
51
+ type: SortType.alphabetical,
52
+ order: SortOrder.asc
53
+ }
54
+ ],
55
+ create: (context) => {
56
+ let options = complete(context.options.at(0), {
57
+ type: SortType.alphabetical,
58
+ order: SortOrder.asc,
59
+ "ignore-case": false
60
+ });
61
+ let parts = [[]];
62
+ let registerNode = (node) => {
63
+ parts.at(-1).push({
64
+ size: rangeToDiff(node.range),
65
+ name: node.source.value,
66
+ node
67
+ });
68
+ };
69
+ return {
70
+ ExportAllDeclaration: registerNode,
71
+ ExportNamedDeclaration: (node) => {
72
+ if (node.source !== null) {
73
+ registerNode(node);
74
+ }
75
+ },
76
+ "Program:exit": () => {
77
+ for (let nodes of parts) {
78
+ pairwise(nodes, (left, right) => {
79
+ if (isPositive(compare(left, right, options))) {
80
+ context.report({
81
+ messageId: "unexpectedExportsOrder",
82
+ data: {
83
+ left: left.name,
84
+ right: right.name
85
+ },
86
+ node: right.node,
87
+ fix: (fixer) => makeFixes(
88
+ fixer,
89
+ nodes,
90
+ sortNodes(nodes, options),
91
+ context.sourceCode
92
+ )
93
+ });
94
+ }
95
+ });
96
+ }
97
+ }
98
+ };
99
+ }
100
+ });
101
+ export {
102
+ RULE_NAME,
103
+ sortExports as default
104
+ };
@@ -0,0 +1,439 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const node_module = require("node:module");
4
+ const minimatch = require("minimatch");
5
+ const getCommentBefore = require("../utils/get-comment-before.js");
6
+ const createEslintRule = require("../utils/create-eslint-rule.js");
7
+ const getLinesBetween = require("../utils/get-lines-between.js");
8
+ const getGroupNumber = require("../utils/get-group-number.js");
9
+ const getNodeRange = require("../utils/get-node-range.js");
10
+ const rangeToDiff = require("../utils/range-to-diff.js");
11
+ const isPositive = require("../utils/is-positive.js");
12
+ const index = require("../typings/index.js");
13
+ const useGroups = require("../utils/use-groups.js");
14
+ const sortNodes = require("../utils/sort-nodes.js");
15
+ const complete = require("../utils/complete.js");
16
+ const pairwise = require("../utils/pairwise.js");
17
+ const compare = require("../utils/compare.js");
18
+ const RULE_NAME = "sort-imports";
19
+ const sortImports = createEslintRule.createEslintRule({
20
+ name: RULE_NAME,
21
+ meta: {
22
+ type: "suggestion",
23
+ docs: {
24
+ description: "enforce sorted imports"
25
+ },
26
+ fixable: "code",
27
+ schema: [
28
+ {
29
+ id: "sort-imports",
30
+ type: "object",
31
+ properties: {
32
+ "custom-groups": {
33
+ type: "object",
34
+ properties: {
35
+ type: {
36
+ type: "object"
37
+ },
38
+ value: {
39
+ type: "object"
40
+ }
41
+ },
42
+ additionalProperties: false
43
+ },
44
+ type: {
45
+ enum: [
46
+ index.SortType.alphabetical,
47
+ index.SortType.natural,
48
+ index.SortType["line-length"]
49
+ ],
50
+ default: index.SortType.alphabetical,
51
+ type: "string"
52
+ },
53
+ order: {
54
+ enum: [index.SortOrder.asc, index.SortOrder.desc],
55
+ default: index.SortOrder.asc,
56
+ type: "string"
57
+ },
58
+ "ignore-case": {
59
+ type: "boolean",
60
+ default: false
61
+ },
62
+ groups: {
63
+ type: "array",
64
+ default: []
65
+ },
66
+ "internal-pattern": {
67
+ items: {
68
+ type: "string"
69
+ },
70
+ type: "array"
71
+ },
72
+ "newlines-between": {
73
+ enum: [
74
+ "ignore",
75
+ "always",
76
+ "never"
77
+ /* never */
78
+ ],
79
+ default: "always",
80
+ type: "string"
81
+ },
82
+ "max-line-length": {
83
+ type: "integer",
84
+ minimum: 0,
85
+ exclusiveMinimum: true
86
+ }
87
+ },
88
+ allOf: [
89
+ { $ref: "#/definitions/max-line-length-requires-line-length-type" }
90
+ ],
91
+ additionalProperties: false,
92
+ dependencies: {
93
+ "max-line-length": ["type"]
94
+ },
95
+ definitions: {
96
+ "is-line-length": {
97
+ properties: {
98
+ type: { enum: [index.SortType["line-length"]], type: "string" }
99
+ },
100
+ required: ["type"],
101
+ type: "object"
102
+ },
103
+ "max-line-length-requires-line-length-type": {
104
+ anyOf: [
105
+ {
106
+ not: { required: ["max-line-length"], type: "object" },
107
+ type: "object"
108
+ },
109
+ { $ref: "#/definitions/is-line-length" }
110
+ ]
111
+ }
112
+ }
113
+ }
114
+ ],
115
+ messages: {
116
+ unexpectedImportsOrder: 'Expected "{{right}}" to come before "{{left}}"',
117
+ missedSpacingBetweenImports: 'Missed spacing between "{{left}}" and "{{right}}" imports',
118
+ extraSpacingBetweenImports: 'Extra spacing between "{{left}}" and "{{right}}" imports'
119
+ }
120
+ },
121
+ defaultOptions: [
122
+ {
123
+ type: index.SortType.alphabetical,
124
+ order: index.SortOrder.asc
125
+ }
126
+ ],
127
+ create: (context) => {
128
+ let options = complete.complete(context.options.at(0), {
129
+ "newlines-between": "always",
130
+ "custom-groups": { type: {}, value: {} },
131
+ "internal-pattern": ["~/**"],
132
+ type: index.SortType.alphabetical,
133
+ order: index.SortOrder.asc,
134
+ "ignore-case": false,
135
+ groups: []
136
+ });
137
+ let hasUnknownGroup = false;
138
+ for (let group of options.groups) {
139
+ if (Array.isArray(group)) {
140
+ for (let subGroup of group) {
141
+ if (subGroup === "unknown") {
142
+ hasUnknownGroup = true;
143
+ }
144
+ }
145
+ } else {
146
+ if (group === "unknown") {
147
+ hasUnknownGroup = true;
148
+ }
149
+ }
150
+ }
151
+ if (!hasUnknownGroup) {
152
+ options.groups = [...options.groups, "unknown"];
153
+ }
154
+ let nodes = [];
155
+ let isSideEffectImport = (node) => node.type === "ImportDeclaration" && node.specifiers.length === 0;
156
+ let computeGroup = (node) => {
157
+ let isStyle = (value) => [".less", ".scss", ".sass", ".styl", ".pcss", ".css", ".sss"].some(
158
+ (extension) => value.endsWith(extension)
159
+ );
160
+ let isIndex = (value) => [
161
+ "./index.d.js",
162
+ "./index.d.ts",
163
+ "./index.js",
164
+ "./index.ts",
165
+ "./index",
166
+ "./",
167
+ "."
168
+ ].includes(value);
169
+ let isParent = (value) => value.indexOf("..") === 0;
170
+ let isSibling = (value) => value.indexOf("./") === 0;
171
+ let { getGroup, defineGroup, setCustomGroups } = useGroups.useGroups(options.groups);
172
+ let isInternal = (nodeElement) => options["internal-pattern"].length && options["internal-pattern"].some(
173
+ (pattern) => minimatch.minimatch(nodeElement.source.value, pattern, {
174
+ nocomment: true
175
+ })
176
+ );
177
+ let isCoreModule = (value) => {
178
+ let bunModules = [
179
+ "bun",
180
+ "bun:ffi",
181
+ "bun:jsc",
182
+ "bun:sqlite",
183
+ "bun:test",
184
+ "bun:wrap",
185
+ "detect-libc",
186
+ "undici",
187
+ "ws"
188
+ ];
189
+ return node_module.builtinModules.includes(
190
+ value.startsWith("node:") ? value.split("node:")[1] : value
191
+ ) || bunModules.includes(value);
192
+ };
193
+ let isExternal = (value) => !(value.startsWith(".") || value.startsWith("/"));
194
+ if (node.importKind === "type") {
195
+ if (node.type === "ImportDeclaration") {
196
+ setCustomGroups(options["custom-groups"].type, node.source.value);
197
+ if (isIndex(node.source.value)) {
198
+ defineGroup("index-type");
199
+ }
200
+ if (isSibling(node.source.value)) {
201
+ defineGroup("sibling-type");
202
+ }
203
+ if (isParent(node.source.value)) {
204
+ defineGroup("parent-type");
205
+ }
206
+ if (isInternal(node)) {
207
+ defineGroup("internal-type");
208
+ }
209
+ if (isCoreModule(node.source.value)) {
210
+ defineGroup("builtin-type");
211
+ }
212
+ if (isExternal(node.source.value)) {
213
+ defineGroup("external-type");
214
+ }
215
+ }
216
+ defineGroup("type");
217
+ }
218
+ if (node.type === "ImportDeclaration") {
219
+ setCustomGroups(options["custom-groups"].value, node.source.value);
220
+ if (isSideEffectImport(node) && isStyle(node.source.value)) {
221
+ defineGroup("side-effect-style");
222
+ }
223
+ if (isSideEffectImport(node)) {
224
+ defineGroup("side-effect");
225
+ }
226
+ if (isStyle(node.source.value)) {
227
+ defineGroup("style");
228
+ }
229
+ if (isIndex(node.source.value)) {
230
+ defineGroup("index");
231
+ }
232
+ if (isSibling(node.source.value)) {
233
+ defineGroup("sibling");
234
+ }
235
+ if (isParent(node.source.value)) {
236
+ defineGroup("parent");
237
+ }
238
+ if (isInternal(node)) {
239
+ defineGroup("internal");
240
+ }
241
+ if (isCoreModule(node.source.value)) {
242
+ defineGroup("builtin");
243
+ }
244
+ if (isExternal(node.source.value)) {
245
+ defineGroup("external");
246
+ }
247
+ }
248
+ return getGroup();
249
+ };
250
+ let hasMultipleImportDeclarations = (node) => node.specifiers.length > 1;
251
+ let registerNode = (node) => {
252
+ let name;
253
+ if (node.type === "ImportDeclaration") {
254
+ name = node.source.value;
255
+ } else {
256
+ if (node.moduleReference.type === "TSExternalModuleReference" && node.moduleReference.expression.type === "Literal") {
257
+ name = `${node.moduleReference.expression.value}`;
258
+ } else {
259
+ name = context.sourceCode.text.slice(...node.moduleReference.range);
260
+ }
261
+ }
262
+ nodes.push({
263
+ size: rangeToDiff.rangeToDiff(node.range),
264
+ group: computeGroup(node),
265
+ name,
266
+ node,
267
+ ...options.type === index.SortType["line-length"] && options["max-line-length"] && {
268
+ hasMultipleImportDeclarations: hasMultipleImportDeclarations(
269
+ node
270
+ )
271
+ }
272
+ });
273
+ };
274
+ return {
275
+ TSImportEqualsDeclaration: registerNode,
276
+ ImportDeclaration: registerNode,
277
+ "Program:exit": () => {
278
+ var _a;
279
+ let hasContentBetweenNodes = (left, right) => !!context.sourceCode.getTokensBetween(
280
+ left.node,
281
+ getCommentBefore.getCommentBefore(right.node, context.sourceCode) || right.node,
282
+ {
283
+ includeComments: true
284
+ }
285
+ ).length;
286
+ let fix = (fixer, nodesToFix) => {
287
+ let fixes = [];
288
+ let grouped = {};
289
+ for (let node of nodesToFix) {
290
+ let groupNum = getGroupNumber.getGroupNumber(options.groups, node);
291
+ if (!(groupNum in grouped)) {
292
+ grouped[groupNum] = [node];
293
+ } else {
294
+ grouped[groupNum] = sortNodes.sortNodes(
295
+ [...grouped[groupNum], node],
296
+ options
297
+ );
298
+ }
299
+ }
300
+ let formatted = Object.keys(grouped).sort((a, b) => Number(a) - Number(b)).reduce(
301
+ (accumulator, group) => [
302
+ ...accumulator,
303
+ ...grouped[group]
304
+ ],
305
+ []
306
+ );
307
+ for (let i = 0, max = formatted.length; i < max; i++) {
308
+ let node = formatted.at(i);
309
+ fixes.push(
310
+ fixer.replaceTextRange(
311
+ getNodeRange.getNodeRange(nodesToFix.at(i).node, context.sourceCode),
312
+ context.sourceCode.text.slice(
313
+ ...getNodeRange.getNodeRange(node.node, context.sourceCode)
314
+ )
315
+ )
316
+ );
317
+ if (options["newlines-between"] !== "ignore") {
318
+ let nextNode = formatted.at(i + 1);
319
+ if (nextNode) {
320
+ let linesBetweenImports = getLinesBetween.getLinesBetween(
321
+ context.sourceCode,
322
+ nodesToFix.at(i),
323
+ nodesToFix.at(i + 1)
324
+ );
325
+ if (options["newlines-between"] === "always" && getGroupNumber.getGroupNumber(options.groups, node) === getGroupNumber.getGroupNumber(options.groups, nextNode) && linesBetweenImports !== 0 || options["newlines-between"] === "never" && linesBetweenImports > 0) {
326
+ fixes.push(
327
+ fixer.removeRange([
328
+ getNodeRange.getNodeRange(
329
+ nodesToFix.at(i).node,
330
+ context.sourceCode
331
+ ).at(1),
332
+ getNodeRange.getNodeRange(
333
+ nodesToFix.at(i + 1).node,
334
+ context.sourceCode
335
+ ).at(0) - 1
336
+ ])
337
+ );
338
+ }
339
+ if (options["newlines-between"] === "always" && getGroupNumber.getGroupNumber(options.groups, node) !== getGroupNumber.getGroupNumber(options.groups, nextNode) && linesBetweenImports > 1) {
340
+ fixes.push(
341
+ fixer.replaceTextRange(
342
+ [
343
+ getNodeRange.getNodeRange(
344
+ nodesToFix.at(i).node,
345
+ context.sourceCode
346
+ ).at(1),
347
+ getNodeRange.getNodeRange(
348
+ nodesToFix.at(i + 1).node,
349
+ context.sourceCode
350
+ ).at(0) - 1
351
+ ],
352
+ "\n"
353
+ )
354
+ );
355
+ }
356
+ if (options["newlines-between"] === "always" && getGroupNumber.getGroupNumber(options.groups, node) !== getGroupNumber.getGroupNumber(options.groups, nextNode) && linesBetweenImports === 0) {
357
+ fixes.push(
358
+ fixer.insertTextAfterRange(
359
+ getNodeRange.getNodeRange(nodesToFix.at(i).node, context.sourceCode),
360
+ "\n"
361
+ )
362
+ );
363
+ }
364
+ }
365
+ }
366
+ }
367
+ return fixes;
368
+ };
369
+ let splittedNodes = [[]];
370
+ for (let node of nodes) {
371
+ let lastNode = (_a = splittedNodes.at(-1)) == null ? void 0 : _a.at(-1);
372
+ if (lastNode && hasContentBetweenNodes(lastNode, node)) {
373
+ splittedNodes.push([node]);
374
+ } else {
375
+ splittedNodes.at(-1).push(node);
376
+ }
377
+ }
378
+ for (let nodeList of splittedNodes) {
379
+ pairwise.pairwise(nodeList, (left, right) => {
380
+ let leftNum = getGroupNumber.getGroupNumber(options.groups, left);
381
+ let rightNum = getGroupNumber.getGroupNumber(options.groups, right);
382
+ let numberOfEmptyLinesBetween = getLinesBetween.getLinesBetween(
383
+ context.sourceCode,
384
+ left,
385
+ right
386
+ );
387
+ if (!(isSideEffectImport(left.node) && isSideEffectImport(right.node)) && !hasContentBetweenNodes(left, right) && (leftNum > rightNum || leftNum === rightNum && isPositive.isPositive(compare.compare(left, right, options)))) {
388
+ context.report({
389
+ messageId: "unexpectedImportsOrder",
390
+ data: {
391
+ left: left.name,
392
+ right: right.name
393
+ },
394
+ node: right.node,
395
+ fix: (fixer) => fix(fixer, nodeList)
396
+ });
397
+ }
398
+ if (options["newlines-between"] === "never" && numberOfEmptyLinesBetween > 0) {
399
+ context.report({
400
+ messageId: "extraSpacingBetweenImports",
401
+ data: {
402
+ left: left.name,
403
+ right: right.name
404
+ },
405
+ node: right.node,
406
+ fix: (fixer) => fix(fixer, nodeList)
407
+ });
408
+ }
409
+ if (options["newlines-between"] === "always") {
410
+ if (leftNum < rightNum && numberOfEmptyLinesBetween === 0) {
411
+ context.report({
412
+ messageId: "missedSpacingBetweenImports",
413
+ data: {
414
+ left: left.name,
415
+ right: right.name
416
+ },
417
+ node: right.node,
418
+ fix: (fixer) => fix(fixer, nodeList)
419
+ });
420
+ } else if (numberOfEmptyLinesBetween > 1 || leftNum === rightNum && numberOfEmptyLinesBetween > 0) {
421
+ context.report({
422
+ messageId: "extraSpacingBetweenImports",
423
+ data: {
424
+ left: left.name,
425
+ right: right.name
426
+ },
427
+ node: right.node,
428
+ fix: (fixer) => fix(fixer, nodeList)
429
+ });
430
+ }
431
+ }
432
+ });
433
+ }
434
+ }
435
+ };
436
+ }
437
+ });
438
+ exports.RULE_NAME = RULE_NAME;
439
+ exports.default = sortImports;