eslint-plugin-perfectionist 4.13.0 → 4.14.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 (32) hide show
  1. package/dist/package.json.js +1 -1
  2. package/dist/rules/sort-classes.js +2 -2
  3. package/dist/rules/sort-exports.js +2 -0
  4. package/dist/rules/sort-imports/compute-common-selectors.js +15 -5
  5. package/dist/rules/sort-imports/is-side-effect-only-group.js +5 -1
  6. package/dist/rules/sort-imports/read-closest-ts-config-by-path.js +11 -13
  7. package/dist/rules/sort-imports.js +57 -50
  8. package/dist/rules/sort-modules.js +2 -2
  9. package/dist/rules/sort-switch-case.js +7 -0
  10. package/dist/utils/common-json-schemas.js +6 -1
  11. package/dist/utils/get-comment-above-that-should-exist.js +34 -0
  12. package/dist/utils/{get-group-number.js → get-group-index.js} +2 -2
  13. package/dist/utils/{get-newlines-errors.js → get-newlines-between-errors.js} +5 -5
  14. package/dist/utils/get-newlines-between-option.js +3 -6
  15. package/dist/utils/is-comment-above-option.js +5 -0
  16. package/dist/utils/make-comment-above-fixes.js +109 -0
  17. package/dist/utils/make-fixes.js +28 -11
  18. package/dist/utils/{make-newlines-fixes.js → make-newlines-between-fixes.js} +2 -2
  19. package/dist/utils/make-single-node-comment-after-fixes.js +16 -2
  20. package/dist/utils/pairwise.js +2 -1
  21. package/dist/utils/report-all-errors.js +37 -13
  22. package/dist/utils/report-errors.js +17 -11
  23. package/dist/utils/should-partition.js +9 -2
  24. package/dist/utils/sort-nodes-by-groups.js +2 -2
  25. package/dist/utils/validate-generated-groups-configuration.js +2 -4
  26. package/dist/utils/validate-no-duplicated-groups.js +5 -1
  27. package/dist/utils/validate-objects-inside-groups.js +18 -0
  28. package/package.json +3 -3
  29. package/dist/utils/get-comment-after.js +0 -18
  30. package/dist/utils/has-partition-comment.js +0 -11
  31. package/dist/utils/to-single-line.js +0 -4
  32. package/dist/utils/validate-newlines-between-inside-groups.js +0 -18
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const name = 'eslint-plugin-perfectionist'
4
- const version = '4.13.0'
4
+ const version = '4.14.0'
5
5
  exports.name = name
6
6
  exports.version = version
@@ -18,7 +18,7 @@ const createEslintRule = require('../utils/create-eslint-rule.js')
18
18
  const getDecoratorName = require('../utils/get-decorator-name.js')
19
19
  const reportAllErrors = require('../utils/report-all-errors.js')
20
20
  const shouldPartition = require('../utils/should-partition.js')
21
- const getGroupNumber = require('../utils/get-group-number.js')
21
+ const getGroupIndex = require('../utils/get-group-index.js')
22
22
  const computeGroup = require('../utils/compute-group.js')
23
23
  const rangeToDiff = require('../utils/range-to-diff.js')
24
24
  const getSettings = require('../utils/get-settings.js')
@@ -474,7 +474,7 @@ const sortClasses = createEslintRule.createEslintRule({
474
474
  let nodesSortedByGroups = formattedNodes.flatMap(nodes2 =>
475
475
  sortNodesByGroups.sortNodesByGroups({
476
476
  isNodeIgnored: sortingNode =>
477
- getGroupNumber.getGroupNumber(options.groups, sortingNode) ===
477
+ getGroupIndex.getGroupIndex(options.groups, sortingNode) ===
478
478
  options.groups.length,
479
479
  getOptionsByGroupNumber:
480
480
  getCustomGroupsCompareOptions.buildGetCustomGroupOverriddenOptionsFunction(
@@ -142,6 +142,7 @@ const sortExports = createEslintRule.createEslintRule({
142
142
  missedSpacingBetweenMembers: 'missedSpacingBetweenExports',
143
143
  extraSpacingBetweenMembers: 'extraSpacingBetweenExports',
144
144
  unexpectedGroupOrder: 'unexpectedExportsGroupOrder',
145
+ missedCommentAbove: 'missedCommentAboveExport',
145
146
  unexpectedOrder: 'unexpectedExportsOrder',
146
147
  },
147
148
  sortNodesExcludingEslintDisabled,
@@ -185,6 +186,7 @@ const sortExports = createEslintRule.createEslintRule({
185
186
  type: 'array',
186
187
  },
187
188
  messages: {
189
+ missedCommentAboveExport: reportErrors.MISSED_COMMENT_ABOVE_ERROR,
188
190
  missedSpacingBetweenExports: reportErrors.MISSED_SPACING_ERROR,
189
191
  extraSpacingBetweenExports: reportErrors.EXTRA_SPACING_ERROR,
190
192
  unexpectedExportsGroupOrder: reportErrors.GROUP_ORDER_ERROR,
@@ -65,12 +65,22 @@ let builtinPrefixOnlyModules = /* @__PURE__ */ new Set([
65
65
  'node:sea',
66
66
  ])
67
67
  let isCoreModule = (value, environment) => {
68
- let valueToCheck = value.startsWith('node:') ? value.split('node:')[1] : value
69
- return (
70
- (!!valueToCheck && nodeBuiltinModules.has(valueToCheck)) ||
68
+ let clean = string_ => string_.replace(/^(?:node:){1,2}/u, '')
69
+ let [basePath] = value.split('/')
70
+ let cleanValue = clean(value)
71
+ let cleanBase = clean(basePath)
72
+ if (nodeBuiltinModules.has(cleanValue) || nodeBuiltinModules.has(cleanBase)) {
73
+ return true
74
+ }
75
+ if (
71
76
  builtinPrefixOnlyModules.has(value) ||
72
- (environment === 'bun' ? bunModules.has(value) : false)
73
- )
77
+ builtinPrefixOnlyModules.has(`node:${cleanValue}`) ||
78
+ builtinPrefixOnlyModules.has(basePath) ||
79
+ builtinPrefixOnlyModules.has(`node:${cleanBase}`)
80
+ ) {
81
+ return true
82
+ }
83
+ return environment === 'bun' && bunModules.has(value)
74
84
  }
75
85
  let isParent = value => value.startsWith('..')
76
86
  let isSibling = value => value.startsWith('./')
@@ -1,8 +1,12 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const isNewlinesBetweenOption = require('../../utils/is-newlines-between-option.js')
4
+ const isCommentAboveOption = require('../../utils/is-comment-above-option.js')
4
5
  let isSideEffectOnlyGroup = group => {
5
- if (isNewlinesBetweenOption.isNewlinesBetweenOption(group)) {
6
+ if (
7
+ isNewlinesBetweenOption.isNewlinesBetweenOption(group) ||
8
+ isCommentAboveOption.isCommentAboveOption(group)
9
+ ) {
6
10
  return false
7
11
  }
8
12
  if (typeof group === 'string') {
@@ -29,15 +29,20 @@ const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path)
29
29
  const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs)
30
30
  let directoryCacheByPath = /* @__PURE__ */ new Map()
31
31
  let contentCacheByPath = /* @__PURE__ */ new Map()
32
- let readClosestTsConfigByPath = input => {
32
+ let readClosestTsConfigByPath = ({
33
+ tsconfigFilename,
34
+ tsconfigRootDir,
35
+ contextCwd,
36
+ filePath,
37
+ }) => {
33
38
  let typescriptImport = getTypescriptImport.getTypescriptImport()
34
39
  if (!typescriptImport) {
35
40
  return null
36
41
  }
37
- let directory = path__namespace.dirname(input.filePath)
42
+ let directory = path__namespace.dirname(filePath)
38
43
  let checkedDirectories = [directory]
39
44
  do {
40
- let tsconfigPath = path__namespace.join(directory, 'tsconfig.json')
45
+ let tsconfigPath = path__namespace.join(directory, tsconfigFilename)
41
46
  let cachedDirectory = directoryCacheByPath.get(directory)
42
47
  if (!cachedDirectory && fs__namespace.existsSync(tsconfigPath)) {
43
48
  cachedDirectory = tsconfigPath
@@ -46,20 +51,13 @@ let readClosestTsConfigByPath = input => {
46
51
  for (let checkedDirectory of checkedDirectories) {
47
52
  directoryCacheByPath.set(checkedDirectory, cachedDirectory)
48
53
  }
49
- return getCompilerOptions(
50
- typescriptImport,
51
- input.contextCwd,
52
- cachedDirectory,
53
- )
54
+ return getCompilerOptions(typescriptImport, contextCwd, cachedDirectory)
54
55
  }
55
56
  directory = path__namespace.dirname(directory)
56
57
  checkedDirectories.push(directory)
57
- } while (
58
- directory.length > 1 &&
59
- directory.length >= input.tsconfigRootDir.length
60
- )
58
+ } while (directory.length > 1 && directory.length >= tsconfigRootDir.length)
61
59
  throw new Error(
62
- `Couldn't find any tsconfig.json relative to '${input.filePath}' within '${input.tsconfigRootDir}'.`,
60
+ `Couldn't find any ${tsconfigFilename} relative to '${filePath}' within '${tsconfigRootDir}'.`,
63
61
  )
64
62
  }
65
63
  let getCompilerOptions = (typescriptImport, contextCwd, filePath) => {
@@ -26,38 +26,39 @@ const getSettings = require('../utils/get-settings.js')
26
26
  const isSortable = require('../utils/is-sortable.js')
27
27
  const complete = require('../utils/complete.js')
28
28
  let cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
29
- let defaultGroups = [
30
- 'type-import',
31
- ['value-builtin', 'value-external'],
32
- 'type-internal',
33
- 'value-internal',
34
- ['type-parent', 'type-sibling', 'type-index'],
35
- ['value-parent', 'value-sibling', 'value-index'],
36
- 'ts-equals-import',
37
- 'unknown',
38
- ]
29
+ let defaultOptions = {
30
+ groups: [
31
+ 'type-import',
32
+ ['value-builtin', 'value-external'],
33
+ 'type-internal',
34
+ 'value-internal',
35
+ ['type-parent', 'type-sibling', 'type-index'],
36
+ ['value-parent', 'value-sibling', 'value-index'],
37
+ 'ts-equals-import',
38
+ 'unknown',
39
+ ],
40
+ internalPattern: ['^~/.+', '^@/.+'],
41
+ fallbackSort: { type: 'unsorted' },
42
+ partitionByComment: false,
43
+ partitionByNewLine: false,
44
+ newlinesBetween: 'always',
45
+ specialCharacters: 'keep',
46
+ sortSideEffects: false,
47
+ type: 'alphabetical',
48
+ environment: 'node',
49
+ customGroups: [],
50
+ ignoreCase: true,
51
+ locales: 'en-US',
52
+ alphabet: '',
53
+ order: 'asc',
54
+ }
39
55
  const sortImports = createEslintRule.createEslintRule({
40
56
  create: context => {
57
+ var _a, _b
41
58
  let settings = getSettings.getSettings(context.settings)
42
59
  let userOptions = context.options.at(0)
43
60
  let options = getOptionsWithCleanGroups.getOptionsWithCleanGroups(
44
- complete.complete(userOptions, settings, {
45
- internalPattern: ['^~/.+', '^@/.+'],
46
- fallbackSort: { type: 'unsorted' },
47
- partitionByComment: false,
48
- partitionByNewLine: false,
49
- newlinesBetween: 'always',
50
- specialCharacters: 'keep',
51
- sortSideEffects: false,
52
- groups: defaultGroups,
53
- type: 'alphabetical',
54
- environment: 'node',
55
- customGroups: [],
56
- ignoreCase: true,
57
- locales: 'en-US',
58
- alphabet: '',
59
- order: 'asc',
60
- }),
61
+ complete.complete(userOptions, settings, defaultOptions),
61
62
  )
62
63
  validateGeneratedGroupsConfiguration.validateGeneratedGroupsConfiguration({
63
64
  options: {
@@ -77,9 +78,15 @@ const sortImports = createEslintRule.createEslintRule({
77
78
  options,
78
79
  )
79
80
  validateSideEffectsConfiguration.validateSideEffectsConfiguration(options)
80
- let tsConfigOutput = options.tsconfigRootDir
81
+ let tsconfigRootDirectory =
82
+ ((_a = options.tsconfig) == null ? void 0 : _a.rootDir) ??
83
+ options.tsconfigRootDir
84
+ let tsConfigOutput = tsconfigRootDirectory
81
85
  ? readClosestTsConfigByPath.readClosestTsConfigByPath({
82
- tsconfigRootDir: options.tsconfigRootDir,
86
+ tsconfigFilename:
87
+ ((_b = options.tsconfig) == null ? void 0 : _b.filename) ??
88
+ 'tsconfig.json',
89
+ tsconfigRootDir: tsconfigRootDirectory,
83
90
  filePath: context.physicalFilename,
84
91
  contextCwd: context.cwd,
85
92
  })
@@ -306,6 +313,7 @@ const sortImports = createEslintRule.createEslintRule({
306
313
  missedSpacingBetweenMembers: 'missedSpacingBetweenImports',
307
314
  extraSpacingBetweenMembers: 'extraSpacingBetweenImports',
308
315
  unexpectedGroupOrder: 'unexpectedImportsGroupOrder',
316
+ missedCommentAbove: 'missedCommentAboveImport',
309
317
  unexpectedOrder: 'unexpectedImportsOrder',
310
318
  },
311
319
  options: {
@@ -322,15 +330,15 @@ const sortImports = createEslintRule.createEslintRule({
322
330
  }
323
331
  },
324
332
  VariableDeclaration: node => {
325
- var _a
333
+ var _a2
326
334
  if (
327
335
  node.declarations[0].init &&
328
336
  node.declarations[0].init.type === 'CallExpression' &&
329
337
  node.declarations[0].init.callee.type === 'Identifier' &&
330
338
  node.declarations[0].init.callee.name === 'require' &&
331
- ((_a = node.declarations[0].init.arguments[0]) == null
339
+ ((_a2 = node.declarations[0].init.arguments[0]) == null
332
340
  ? void 0
333
- : _a.type) === 'Literal'
341
+ : _a2.type) === 'Literal'
334
342
  ) {
335
343
  registerNode(node)
336
344
  }
@@ -366,6 +374,21 @@ const sortImports = createEslintRule.createEslintRule({
366
374
  }),
367
375
  ],
368
376
  },
377
+ tsconfig: {
378
+ properties: {
379
+ rootDir: {
380
+ description: 'Specifies the tsConfig root directory.',
381
+ type: 'string',
382
+ },
383
+ filename: {
384
+ description: 'Specifies the tsConfig filename.',
385
+ type: 'string',
386
+ },
387
+ },
388
+ additionalProperties: false,
389
+ required: ['rootDir'],
390
+ type: 'object',
391
+ },
369
392
  maxLineLength: {
370
393
  description: 'Specifies the maximum line length.',
371
394
  exclusiveMinimum: true,
@@ -400,6 +423,7 @@ const sortImports = createEslintRule.createEslintRule({
400
423
  },
401
424
  messages: {
402
425
  unexpectedImportsDependencyOrder: reportErrors.DEPENDENCY_ORDER_ERROR,
426
+ missedCommentAboveImport: reportErrors.MISSED_COMMENT_ABOVE_ERROR,
403
427
  missedSpacingBetweenImports: reportErrors.MISSED_SPACING_ERROR,
404
428
  extraSpacingBetweenImports: reportErrors.EXTRA_SPACING_ERROR,
405
429
  unexpectedImportsGroupOrder: reportErrors.GROUP_ORDER_ERROR,
@@ -413,24 +437,7 @@ const sortImports = createEslintRule.createEslintRule({
413
437
  type: 'suggestion',
414
438
  fixable: 'code',
415
439
  },
416
- defaultOptions: [
417
- {
418
- customGroups: { value: {}, type: {} },
419
- internalPattern: ['^~/.+', '^@/.+'],
420
- partitionByComment: false,
421
- partitionByNewLine: false,
422
- specialCharacters: 'keep',
423
- newlinesBetween: 'always',
424
- sortSideEffects: false,
425
- groups: defaultGroups,
426
- type: 'alphabetical',
427
- environment: 'node',
428
- ignoreCase: true,
429
- locales: 'en-US',
430
- alphabet: '',
431
- order: 'asc',
432
- },
433
- ],
440
+ defaultOptions: [defaultOptions],
434
441
  name: 'sort-imports',
435
442
  })
436
443
  let hasContentBetweenNodes = (sourceCode, left, right) =>
@@ -18,8 +18,8 @@ const createEslintRule = require('../utils/create-eslint-rule.js')
18
18
  const getDecoratorName = require('../utils/get-decorator-name.js')
19
19
  const reportAllErrors = require('../utils/report-all-errors.js')
20
20
  const shouldPartition = require('../utils/should-partition.js')
21
- const getGroupNumber = require('../utils/get-group-number.js')
22
21
  const getEnumMembers = require('../utils/get-enum-members.js')
22
+ const getGroupIndex = require('../utils/get-group-index.js')
23
23
  const computeGroup = require('../utils/compute-group.js')
24
24
  const rangeToDiff = require('../utils/range-to-diff.js')
25
25
  const getSettings = require('../utils/get-settings.js')
@@ -284,7 +284,7 @@ let analyzeModule = ({
284
284
  let nodesSortedByGroups = formattedNodes.flatMap(nodes2 =>
285
285
  sortNodesByGroups.sortNodesByGroups({
286
286
  isNodeIgnored: sortingNode =>
287
- getGroupNumber.getGroupNumber(options.groups, sortingNode) ===
287
+ getGroupIndex.getGroupIndex(options.groups, sortingNode) ===
288
288
  options.groups.length,
289
289
  getOptionsByGroupNumber:
290
290
  getCustomGroupsCompareOptions.buildGetCustomGroupOverriddenOptionsFunction(
@@ -77,6 +77,9 @@ const sortSwitchCase = createEslintRule.createEslintRule({
77
77
  sortedCaseNameSortingNodes,
78
78
  )
79
79
  pairwise.pairwise(caseNodesSortingNodeGroup, (left, right) => {
80
+ if (!left) {
81
+ return
82
+ }
80
83
  let leftIndex = nodeIndexMap.get(left)
81
84
  let rightIndex = nodeIndexMap.get(right)
82
85
  if (leftIndex < rightIndex) {
@@ -198,6 +201,9 @@ const sortSwitchCase = createEslintRule.createEslintRule({
198
201
  let sortingNodeGroupsForBlockSortFlat =
199
202
  sortingNodeGroupsForBlockSort.flat()
200
203
  pairwise.pairwise(sortingNodeGroupsForBlockSortFlat, (left, right) => {
204
+ if (!left) {
205
+ return
206
+ }
201
207
  let indexOfLeft = sortedSortingNodeGroupsForBlockSort.indexOf(left)
202
208
  let indexOfRight = sortedSortingNodeGroupsForBlockSort.indexOf(right)
203
209
  if (indexOfLeft < indexOfRight) {
@@ -210,6 +216,7 @@ const sortSwitchCase = createEslintRule.createEslintRule({
210
216
  : makeFixes.makeFixes({
211
217
  sortedNodes: sortedSortingNodeGroupsForBlockSort,
212
218
  nodes: sortingNodeGroupsForBlockSortFlat,
219
+ hasCommentAboveMissing: false,
213
220
  sourceCode,
214
221
  fixer,
215
222
  }),
@@ -68,6 +68,10 @@ let newlinesBetweenJsonSchema = {
68
68
  enum: ['ignore', 'always', 'never'],
69
69
  type: 'string',
70
70
  }
71
+ let commentAboveJsonSchema = {
72
+ description: 'Specifies a comment to enforce above the group.',
73
+ type: 'string',
74
+ }
71
75
  let groupsJsonSchema = {
72
76
  items: {
73
77
  oneOf: [
@@ -83,9 +87,10 @@ let groupsJsonSchema = {
83
87
  {
84
88
  properties: {
85
89
  newlinesBetween: newlinesBetweenJsonSchema,
90
+ commentAbove: commentAboveJsonSchema,
86
91
  },
87
- required: ['newlinesBetween'],
88
92
  additionalProperties: false,
93
+ minProperties: 1,
89
94
  type: 'object',
90
95
  },
91
96
  ],
@@ -0,0 +1,34 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ const isCommentAboveOption = require('./is-comment-above-option.js')
4
+ const getCommentsBefore = require('./get-comments-before.js')
5
+ let getCommentAboveThatShouldExist = ({
6
+ rightGroupIndex,
7
+ leftGroupIndex,
8
+ sortingNode,
9
+ sourceCode,
10
+ options,
11
+ }) => {
12
+ if (leftGroupIndex !== null && leftGroupIndex >= rightGroupIndex) {
13
+ return null
14
+ }
15
+ let groupAboveRight = options.groups[rightGroupIndex - 1]
16
+ if (!isCommentAboveOption.isCommentAboveOption(groupAboveRight)) {
17
+ return null
18
+ }
19
+ let matchingCommentsAbove = getCommentsBefore
20
+ .getCommentsBefore({
21
+ node: sortingNode.node,
22
+ sourceCode,
23
+ })
24
+ .find(comment =>
25
+ commentMatches(comment.value, groupAboveRight.commentAbove),
26
+ )
27
+ return {
28
+ comment: groupAboveRight.commentAbove,
29
+ exists: !!matchingCommentsAbove,
30
+ }
31
+ }
32
+ let commentMatches = (comment, expected) =>
33
+ comment.toLowerCase().includes(expected.toLowerCase().trim())
34
+ exports.getCommentAboveThatShouldExist = getCommentAboveThatShouldExist
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- let getGroupNumber = (groups, node) => {
3
+ let getGroupIndex = (groups, node) => {
4
4
  for (let max = groups.length, i = 0; i < max; i++) {
5
5
  let currentGroup = groups[i]
6
6
  if (
@@ -14,4 +14,4 @@ let getGroupNumber = (groups, node) => {
14
14
  }
15
15
  return groups.length
16
16
  }
17
- exports.getGroupNumber = getGroupNumber
17
+ exports.getGroupIndex = getGroupIndex
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const getNewlinesBetweenOption = require('./get-newlines-between-option.js')
4
4
  const getLinesBetween = require('./get-lines-between.js')
5
- let getNewlinesErrors = ({
5
+ let getNewlinesBetweenErrors = ({
6
6
  newlinesBetweenValueGetter,
7
7
  missedSpacingError,
8
8
  extraSpacingError,
9
+ rightGroupIndex,
10
+ leftGroupIndex,
9
11
  sourceCode,
10
- rightNum,
11
- leftNum,
12
12
  options,
13
13
  right,
14
14
  left,
@@ -26,7 +26,7 @@ let getNewlinesErrors = ({
26
26
  right,
27
27
  left,
28
28
  })) ?? newlinesBetween
29
- if (leftNum > rightNum) {
29
+ if (leftGroupIndex > rightGroupIndex) {
30
30
  return []
31
31
  }
32
32
  let numberOfEmptyLinesBetween = getLinesBetween.getLinesBetween(
@@ -48,4 +48,4 @@ let getNewlinesErrors = ({
48
48
  }
49
49
  return []
50
50
  }
51
- exports.getNewlinesErrors = getNewlinesErrors
51
+ exports.getNewlinesBetweenErrors = getNewlinesBetweenErrors
@@ -1,13 +1,10 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const isNewlinesBetweenOption = require('./is-newlines-between-option.js')
4
- const getGroupNumber = require('./get-group-number.js')
4
+ const getGroupIndex = require('./get-group-index.js')
5
5
  let getNewlinesBetweenOption = ({ nextSortingNode, sortingNode, options }) => {
6
- let nodeGroupNumber = getGroupNumber.getGroupNumber(
7
- options.groups,
8
- sortingNode,
9
- )
10
- let nextNodeGroupNumber = getGroupNumber.getGroupNumber(
6
+ let nodeGroupNumber = getGroupIndex.getGroupIndex(options.groups, sortingNode)
7
+ let nextNodeGroupNumber = getGroupIndex.getGroupIndex(
11
8
  options.groups,
12
9
  nextSortingNode,
13
10
  )
@@ -0,0 +1,5 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ let isCommentAboveOption = groupOption =>
4
+ typeof groupOption === 'object' && 'commentAbove' in groupOption
5
+ exports.isCommentAboveOption = isCommentAboveOption
@@ -0,0 +1,109 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ const getCommentAboveThatShouldExist = require('./get-comment-above-that-should-exist.js')
4
+ const isCommentAboveOption = require('./is-comment-above-option.js')
5
+ const getCommentsBefore = require('./get-comments-before.js')
6
+ const getGroupIndex = require('./get-group-index.js')
7
+ let makeCommentAboveFixes = ({ sortedNodes, sourceCode, options, fixer }) => {
8
+ let allAutoAddedComments = new Set(
9
+ options.groups
10
+ .filter(group => isCommentAboveOption.isCommentAboveOption(group))
11
+ .map(({ commentAbove }) => commentAbove),
12
+ )
13
+ let fixes = []
14
+ let firstNodeFixes = makeCommentAboveFix({
15
+ nextSortedSortingNode: sortedNodes[0],
16
+ sortedSortingNode: null,
17
+ allAutoAddedComments,
18
+ sourceCode,
19
+ options,
20
+ fixer,
21
+ })
22
+ fixes.push(...firstNodeFixes)
23
+ for (let i = 0; i < sortedNodes.length - 1; i++) {
24
+ let sortedSortingNode = sortedNodes.at(i)
25
+ let nextSortedSortingNode = sortedNodes.at(i + 1)
26
+ let nodeFixes = makeCommentAboveFix({
27
+ nextSortedSortingNode,
28
+ allAutoAddedComments,
29
+ sortedSortingNode,
30
+ sourceCode,
31
+ options,
32
+ fixer,
33
+ })
34
+ fixes.push(...nodeFixes)
35
+ }
36
+ return fixes
37
+ }
38
+ let makeCommentAboveFix = ({
39
+ nextSortedSortingNode,
40
+ allAutoAddedComments,
41
+ sortedSortingNode,
42
+ sourceCode,
43
+ options,
44
+ fixer,
45
+ }) => {
46
+ let leftGroupIndex = sortedSortingNode
47
+ ? getGroupIndex.getGroupIndex(options.groups, sortedSortingNode)
48
+ : -1
49
+ let rightGroupIndex = getGroupIndex.getGroupIndex(
50
+ options.groups,
51
+ nextSortedSortingNode,
52
+ )
53
+ let commentAboveThatShouldExist =
54
+ getCommentAboveThatShouldExist.getCommentAboveThatShouldExist({
55
+ options: {
56
+ ...options,
57
+ groups: options.groups,
58
+ },
59
+ sortingNode: nextSortedSortingNode,
60
+ rightGroupIndex,
61
+ leftGroupIndex,
62
+ sourceCode,
63
+ })
64
+ let commentsBefore = getCommentsBefore.getCommentsBefore({
65
+ node: nextSortedSortingNode.node,
66
+ sourceCode,
67
+ })
68
+ let autoAddedCommentsAboveToRemove = commentsBefore
69
+ .filter(
70
+ comment =>
71
+ !(commentAboveThatShouldExist == null
72
+ ? void 0
73
+ : commentAboveThatShouldExist.comment) ||
74
+ comment.value.slice(1) !== commentAboveThatShouldExist.comment,
75
+ )
76
+ .filter(
77
+ comment =>
78
+ comment.type === 'Line' &&
79
+ allAutoAddedComments.has(comment.value.slice(1)),
80
+ )
81
+ let fixes = []
82
+ for (let autoAddedCommentAboveToRemove of autoAddedCommentsAboveToRemove) {
83
+ let nextToken = sourceCode.getTokenAfter(autoAddedCommentAboveToRemove)
84
+ fixes.push(
85
+ fixer.removeRange([
86
+ autoAddedCommentAboveToRemove.range[0],
87
+ nextToken.range[0],
88
+ ]),
89
+ )
90
+ }
91
+ if (commentAboveThatShouldExist && !commentAboveThatShouldExist.exists) {
92
+ let nodeToPutCommentBefore
93
+ let isFirstToken = !sourceCode.getTokenBefore(nextSortedSortingNode.node)
94
+ if (isFirstToken || !commentsBefore[0]) {
95
+ nodeToPutCommentBefore = nextSortedSortingNode.node
96
+ } else {
97
+ ;[nodeToPutCommentBefore] = commentsBefore
98
+ }
99
+ fixes.push(
100
+ fixer.insertTextBeforeRange(
101
+ nodeToPutCommentBefore.range,
102
+ `// ${commentAboveThatShouldExist.comment}
103
+ `,
104
+ ),
105
+ )
106
+ }
107
+ return fixes
108
+ }
109
+ exports.makeCommentAboveFixes = makeCommentAboveFixes
@@ -1,11 +1,13 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ const makeNewlinesBetweenFixes = require('./make-newlines-between-fixes.js')
3
4
  const makeCommentAfterFixes = require('./make-comment-after-fixes.js')
4
- const makeNewlinesFixes = require('./make-newlines-fixes.js')
5
+ const makeCommentAboveFixes = require('./make-comment-above-fixes.js')
5
6
  const makeOrderFixes = require('./make-order-fixes.js')
6
7
  let makeFixes = ({
7
8
  ignoreFirstNodeHighestBlockComment,
8
9
  newlinesBetweenValueGetter,
10
+ hasCommentAboveMissing,
9
11
  sortedNodes,
10
12
  sourceCode,
11
13
  options,
@@ -26,25 +28,40 @@ let makeFixes = ({
26
28
  nodes,
27
29
  fixer,
28
30
  })
29
- if (
30
- commentAfterFixes.length > 0 ||
31
- !(options == null ? void 0 : options.groups) ||
32
- !options.newlinesBetween
33
- ) {
31
+ if (commentAfterFixes.length > 0) {
34
32
  return [...orderFixes, ...commentAfterFixes]
35
33
  }
36
- let newlinesFixes = makeNewlinesFixes.makeNewlinesFixes({
34
+ if ((options == null ? void 0 : options.groups) && options.newlinesBetween) {
35
+ let newlinesFixes = makeNewlinesBetweenFixes.makeNewlinesBetweenFixes({
36
+ options: {
37
+ ...options,
38
+ newlinesBetween: options.newlinesBetween,
39
+ groups: options.groups,
40
+ },
41
+ newlinesBetweenValueGetter,
42
+ sortedNodes,
43
+ sourceCode,
44
+ fixer,
45
+ nodes,
46
+ })
47
+ if (newlinesFixes.length > 0) {
48
+ return [...orderFixes, ...newlinesFixes]
49
+ }
50
+ }
51
+ if (orderFixes.length > 0) {
52
+ return orderFixes
53
+ }
54
+ if (!hasCommentAboveMissing || !(options == null ? void 0 : options.groups)) {
55
+ return []
56
+ }
57
+ return makeCommentAboveFixes.makeCommentAboveFixes({
37
58
  options: {
38
59
  ...options,
39
- newlinesBetween: options.newlinesBetween,
40
60
  groups: options.groups,
41
61
  },
42
- newlinesBetweenValueGetter,
43
62
  sortedNodes,
44
63
  sourceCode,
45
64
  fixer,
46
- nodes,
47
65
  })
48
- return [...orderFixes, ...newlinesFixes]
49
66
  }
50
67
  exports.makeFixes = makeFixes
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const getNewlinesBetweenOption = require('./get-newlines-between-option.js')
4
4
  const getLinesBetween = require('./get-lines-between.js')
5
5
  const getNodeRange = require('./get-node-range.js')
6
- let makeNewlinesFixes = ({
6
+ let makeNewlinesBetweenFixes = ({
7
7
  newlinesBetweenValueGetter,
8
8
  sortedNodes,
9
9
  sourceCode,
@@ -87,4 +87,4 @@ let addNewlineBeforeFirstNewline = value => {
87
87
  return `${value.slice(0, firstNewlineIndex)}
88
88
  ${value.slice(firstNewlineIndex)}`
89
89
  }
90
- exports.makeNewlinesFixes = makeNewlinesFixes
90
+ exports.makeNewlinesBetweenFixes = makeNewlinesBetweenFixes
@@ -1,13 +1,12 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const getCommentAfter = require('./get-comment-after.js')
4
3
  let makeSingleNodeCommentAfterFixes = ({
5
4
  sortedNode,
6
5
  sourceCode,
7
6
  fixer,
8
7
  node,
9
8
  }) => {
10
- let commentAfter = getCommentAfter.getCommentAfter(sortedNode, sourceCode)
9
+ let commentAfter = getCommentAfter(sortedNode, sourceCode)
11
10
  let areNodesOnSameLine = node.loc.start.line === sortedNode.loc.end.line
12
11
  if (!commentAfter || areNodesOnSameLine) {
13
12
  return []
@@ -28,4 +27,19 @@ let makeSingleNodeCommentAfterFixes = ({
28
27
  )
29
28
  return fixes
30
29
  }
30
+ let getCommentAfter = (node, source) => {
31
+ let token = source.getTokenAfter(node, {
32
+ filter: ({ value, type }) =>
33
+ type !== 'Punctuator' || ![',', ';', ':'].includes(value),
34
+ includeComments: true,
35
+ })
36
+ if (
37
+ ((token == null ? void 0 : token.type) === 'Block' ||
38
+ (token == null ? void 0 : token.type) === 'Line') &&
39
+ node.loc.end.line === token.loc.end.line
40
+ ) {
41
+ return token
42
+ }
43
+ return null
44
+ }
31
45
  exports.makeSingleNodeCommentAfterFixes = makeSingleNodeCommentAfterFixes
@@ -5,10 +5,11 @@ let pairwise = (nodes, callback) => {
5
5
  if (!isSortable.isSortable(nodes)) {
6
6
  return
7
7
  }
8
+ callback(null, nodes.at(0))
8
9
  for (let i = 1; i < nodes.length; i++) {
9
10
  let left = nodes.at(i - 1)
10
11
  let right = nodes.at(i)
11
- callback(left, right, i - 1)
12
+ callback(left, right)
12
13
  }
13
14
  }
14
15
  exports.pairwise = pairwise
@@ -1,10 +1,11 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const computeNodesInCircularDependencies = require('./compute-nodes-in-circular-dependencies.js')
4
+ const getCommentAboveThatShouldExist = require('./get-comment-above-that-should-exist.js')
4
5
  const isNodeDependentOnOtherNode = require('./is-node-dependent-on-other-node.js')
6
+ const getNewlinesBetweenErrors = require('./get-newlines-between-errors.js')
5
7
  const createNodeIndexMap = require('./create-node-index-map.js')
6
- const getNewlinesErrors = require('./get-newlines-errors.js')
7
- const getGroupNumber = require('./get-group-number.js')
8
+ const getGroupIndex = require('./get-group-index.js')
8
9
  const reportErrors = require('./report-errors.js')
9
10
  const pairwise = require('./pairwise.js')
10
11
  let reportAllErrors = ({
@@ -28,9 +29,13 @@ let reportAllErrors = ({
28
29
  )
29
30
  : /* @__PURE__ */ new Set()
30
31
  pairwise.pairwise(nodes, (left, right) => {
31
- let leftNumber = getGroupNumber.getGroupNumber(options.groups, left)
32
- let rightNumber = getGroupNumber.getGroupNumber(options.groups, right)
33
- let leftIndex = nodeIndexMap.get(left)
32
+ let leftInfo = left
33
+ ? {
34
+ groupIndex: getGroupIndex.getGroupIndex(options.groups, left),
35
+ index: nodeIndexMap.get(left),
36
+ }
37
+ : null
38
+ let rightGroupIndex = getGroupIndex.getGroupIndex(options.groups, right)
34
39
  let rightIndex = nodeIndexMap.get(right)
35
40
  let indexOfRightExcludingEslintDisabled =
36
41
  sortedNodesExcludingEslintDisabled.indexOf(right)
@@ -44,16 +49,17 @@ let reportAllErrors = ({
44
49
  })
45
50
  }
46
51
  if (
47
- firstUnorderedNodeDependentOnRight ||
48
- leftIndex > rightIndex ||
49
- (left.isEslintDisabled &&
50
- leftIndex >= indexOfRightExcludingEslintDisabled)
52
+ leftInfo &&
53
+ (firstUnorderedNodeDependentOnRight ||
54
+ leftInfo.index > rightIndex ||
55
+ ((left == null ? void 0 : left.isEslintDisabled) &&
56
+ leftInfo.index >= indexOfRightExcludingEslintDisabled))
51
57
  ) {
52
58
  if (firstUnorderedNodeDependentOnRight) {
53
59
  messageIds.push(availableMessageIds.unexpectedDependencyOrder)
54
60
  } else {
55
61
  messageIds.push(
56
- leftNumber === rightNumber ||
62
+ leftInfo.groupIndex === rightGroupIndex ||
57
63
  !availableMessageIds.unexpectedGroupOrder
58
64
  ? availableMessageIds.unexpectedOrder
59
65
  : availableMessageIds.unexpectedGroupOrder,
@@ -61,33 +67,51 @@ let reportAllErrors = ({
61
67
  }
62
68
  }
63
69
  if (
70
+ left &&
64
71
  options.newlinesBetween &&
65
72
  availableMessageIds.missedSpacingBetweenMembers &&
66
73
  availableMessageIds.extraSpacingBetweenMembers
67
74
  ) {
68
75
  messageIds = [
69
76
  ...messageIds,
70
- ...getNewlinesErrors.getNewlinesErrors({
77
+ ...getNewlinesBetweenErrors.getNewlinesBetweenErrors({
71
78
  options: {
72
79
  ...options,
73
80
  newlinesBetween: options.newlinesBetween,
74
81
  },
75
82
  missedSpacingError: availableMessageIds.missedSpacingBetweenMembers,
76
83
  extraSpacingError: availableMessageIds.extraSpacingBetweenMembers,
84
+ leftGroupIndex: leftInfo.groupIndex,
77
85
  newlinesBetweenValueGetter,
78
- rightNum: rightNumber,
79
- leftNum: leftNumber,
86
+ rightGroupIndex,
80
87
  sourceCode,
81
88
  right,
82
89
  left,
83
90
  }),
84
91
  ]
85
92
  }
93
+ let commentAboveMissing
94
+ if (availableMessageIds.missedCommentAbove) {
95
+ let commentAboveThatShouldExist =
96
+ getCommentAboveThatShouldExist.getCommentAboveThatShouldExist({
97
+ leftGroupIndex:
98
+ (leftInfo == null ? void 0 : leftInfo.groupIndex) ?? null,
99
+ sortingNode: right,
100
+ rightGroupIndex,
101
+ sourceCode,
102
+ options,
103
+ })
104
+ if (commentAboveThatShouldExist && !commentAboveThatShouldExist.exists) {
105
+ commentAboveMissing = commentAboveThatShouldExist.comment
106
+ messageIds = [...messageIds, availableMessageIds.missedCommentAbove]
107
+ }
108
+ }
86
109
  reportErrors.reportErrors({
87
110
  sortedNodes: sortedNodesExcludingEslintDisabled,
88
111
  ignoreFirstNodeHighestBlockComment,
89
112
  firstUnorderedNodeDependentOnRight,
90
113
  newlinesBetweenValueGetter,
114
+ commentAboveMissing,
91
115
  messageIds,
92
116
  sourceCode,
93
117
  options,
@@ -1,21 +1,23 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const toSingleLine = require('./to-single-line.js')
4
3
  const makeFixes = require('./make-fixes.js')
5
4
  const NODE_DEPENDENT_ON_RIGHT = 'nodeDependentOnRight'
6
5
  const RIGHT = 'right'
7
6
  const RIGHT_GROUP = 'rightGroup'
8
7
  const LEFT = 'left'
9
8
  const LEFT_GROUP = 'leftGroup'
9
+ const MISSED_COMMENT_ABOVE = 'missedCommentAbove'
10
10
  const ORDER_ERROR = `Expected "{{${RIGHT}}}" to come before "{{${LEFT}}}".`
11
11
  const DEPENDENCY_ORDER_ERROR = `Expected dependency "{{${RIGHT}}}" to come before "{{${NODE_DEPENDENT_ON_RIGHT}}}".`
12
12
  const GROUP_ORDER_ERROR = `Expected "{{${RIGHT}}}" ({{${RIGHT_GROUP}}}) to come before "{{${LEFT}}}" ({{${LEFT_GROUP}}}).`
13
13
  const EXTRA_SPACING_ERROR = `Extra spacing between "{{${LEFT}}}" and "{{${RIGHT}}}" objects.`
14
14
  const MISSED_SPACING_ERROR = `Missed spacing between "{{${LEFT}}}" and "{{${RIGHT}}}".`
15
+ const MISSED_COMMENT_ABOVE_ERROR = `Missed comment "{{${MISSED_COMMENT_ABOVE}}}" above "{{${RIGHT}}}".`
15
16
  let reportErrors = ({
16
17
  firstUnorderedNodeDependentOnRight,
17
18
  ignoreFirstNodeHighestBlockComment,
18
19
  newlinesBetweenValueGetter,
20
+ commentAboveMissing,
19
21
  sortedNodes,
20
22
  messageIds,
21
23
  sourceCode,
@@ -27,8 +29,20 @@ let reportErrors = ({
27
29
  }) => {
28
30
  for (let messageId of messageIds) {
29
31
  context.report({
32
+ data: {
33
+ [NODE_DEPENDENT_ON_RIGHT]:
34
+ firstUnorderedNodeDependentOnRight == null
35
+ ? void 0
36
+ : firstUnorderedNodeDependentOnRight.name,
37
+ [MISSED_COMMENT_ABOVE]: commentAboveMissing,
38
+ [LEFT]: toSingleLine((left == null ? void 0 : left.name) ?? ''),
39
+ [RIGHT]: toSingleLine(right.name),
40
+ [RIGHT_GROUP]: right.group,
41
+ [LEFT_GROUP]: left == null ? void 0 : left.group,
42
+ },
30
43
  fix: fixer =>
31
44
  makeFixes.makeFixes({
45
+ hasCommentAboveMissing: !!commentAboveMissing,
32
46
  ignoreFirstNodeHighestBlockComment,
33
47
  newlinesBetweenValueGetter,
34
48
  sortedNodes,
@@ -37,25 +51,17 @@ let reportErrors = ({
37
51
  fixer,
38
52
  nodes,
39
53
  }),
40
- data: {
41
- [NODE_DEPENDENT_ON_RIGHT]:
42
- firstUnorderedNodeDependentOnRight == null
43
- ? void 0
44
- : firstUnorderedNodeDependentOnRight.name,
45
- [RIGHT]: toSingleLine.toSingleLine(right.name),
46
- [LEFT]: toSingleLine.toSingleLine(left.name),
47
- [RIGHT_GROUP]: right.group,
48
- [LEFT_GROUP]: left.group,
49
- },
50
54
  node: right.node,
51
55
  messageId,
52
56
  })
53
57
  }
54
58
  }
59
+ let toSingleLine = string => string.replaceAll(/\s{2,}/gu, ' ').trim()
55
60
  exports.DEPENDENCY_ORDER_ERROR = DEPENDENCY_ORDER_ERROR
56
61
  exports.EXTRA_SPACING_ERROR = EXTRA_SPACING_ERROR
57
62
  exports.GROUP_ORDER_ERROR = GROUP_ORDER_ERROR
58
63
  exports.LEFT = LEFT
64
+ exports.MISSED_COMMENT_ABOVE_ERROR = MISSED_COMMENT_ABOVE_ERROR
59
65
  exports.MISSED_SPACING_ERROR = MISSED_SPACING_ERROR
60
66
  exports.ORDER_ERROR = ORDER_ERROR
61
67
  exports.RIGHT = RIGHT
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const hasPartitionComment = require('./has-partition-comment.js')
3
+ const isPartitionComment = require('./is-partition-comment.js')
4
4
  const getCommentsBefore = require('./get-comments-before.js')
5
5
  const getLinesBetween = require('./get-lines-between.js')
6
6
  let shouldPartition = ({
@@ -12,7 +12,7 @@ let shouldPartition = ({
12
12
  }) => {
13
13
  let shouldPartitionByComment =
14
14
  options.partitionByComment &&
15
- hasPartitionComment.hasPartitionComment({
15
+ hasPartitionComment({
16
16
  comments: getCommentsBefore.getCommentsBefore({
17
17
  tokenValueToIgnoreBefore,
18
18
  node: sortingNode.node,
@@ -29,4 +29,11 @@ let shouldPartition = ({
29
29
  getLinesBetween.getLinesBetween(sourceCode, lastSortingNode, sortingNode)
30
30
  )
31
31
  }
32
+ let hasPartitionComment = ({ partitionByComment, comments }) =>
33
+ comments.some(comment =>
34
+ isPartitionComment.isPartitionComment({
35
+ partitionByComment,
36
+ comment,
37
+ }),
38
+ )
32
39
  exports.shouldPartition = shouldPartition
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const getGroupNumber = require('./get-group-number.js')
3
+ const getGroupIndex = require('./get-group-index.js')
4
4
  const sortNodes = require('./sort-nodes.js')
5
5
  let sortNodesByGroups = ({
6
6
  ignoreEslintDisabledNodes,
@@ -20,7 +20,7 @@ let sortNodesByGroups = ({
20
20
  ignoredNodeIndices.push(index)
21
21
  continue
22
22
  }
23
- let groupNumber = getGroupNumber.getGroupNumber(groups, sortingNode)
23
+ let groupNumber = getGroupIndex.getGroupIndex(groups, sortingNode)
24
24
  nodesByNonIgnoredGroupNumber[groupNumber] ??
25
25
  (nodesByNonIgnoredGroupNumber[groupNumber] = [])
26
26
  nodesByNonIgnoredGroupNumber[groupNumber].push(sortingNode)
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const validateNewlinesBetweenInsideGroups = require('./validate-newlines-between-inside-groups.js')
3
+ const validateObjectsInsideGroups = require('./validate-objects-inside-groups.js')
4
4
  const validateNoDuplicatedGroups = require('./validate-no-duplicated-groups.js')
5
5
  let validateGeneratedGroupsConfiguration = ({
6
6
  selectors,
@@ -24,9 +24,7 @@ let validateGeneratedGroupsConfiguration = ({
24
24
  throw new Error(`Invalid group(s): ${invalidGroups.join(', ')}`)
25
25
  }
26
26
  validateNoDuplicatedGroups.validateNoDuplicatedGroups(options)
27
- validateNewlinesBetweenInsideGroups.validateNewlinesBetweenInsideGroups(
28
- options,
29
- )
27
+ validateObjectsInsideGroups.validateObjectsInsideGroups(options)
30
28
  }
31
29
  let isPredefinedGroup = (allSelectors, allModifiers, input) => {
32
30
  if (input === 'unknown') {
@@ -1,12 +1,16 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
3
  const isNewlinesBetweenOption = require('./is-newlines-between-option.js')
4
+ const isCommentAboveOption = require('./is-comment-above-option.js')
4
5
  let validateNoDuplicatedGroups = ({ groups }) => {
5
6
  let flattenGroups = groups.flat()
6
7
  let seenGroups = /* @__PURE__ */ new Set()
7
8
  let duplicatedGroups = /* @__PURE__ */ new Set()
8
9
  for (let group of flattenGroups) {
9
- if (isNewlinesBetweenOption.isNewlinesBetweenOption(group)) {
10
+ if (
11
+ isNewlinesBetweenOption.isNewlinesBetweenOption(group) ||
12
+ isCommentAboveOption.isCommentAboveOption(group)
13
+ ) {
10
14
  continue
11
15
  }
12
16
  if (seenGroups.has(group)) {
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ let validateObjectsInsideGroups = ({ groups }) => {
4
+ let isPreviousElementObject = false
5
+ for (let group of groups) {
6
+ if (typeof group === 'string' || Array.isArray(group)) {
7
+ isPreviousElementObject = false
8
+ continue
9
+ }
10
+ if (isPreviousElementObject) {
11
+ throw new Error(
12
+ 'Consecutive objects (`newlinesBetween` or `commentAbove` are not allowed: merge them into a single object',
13
+ )
14
+ }
15
+ isPreviousElementObject = true
16
+ }
17
+ }
18
+ exports.validateObjectsInsideGroups = validateObjectsInsideGroups
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-perfectionist",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.",
5
5
  "keywords": [
6
6
  "eslint",
@@ -27,8 +27,8 @@
27
27
  "./dist"
28
28
  ],
29
29
  "dependencies": {
30
- "@typescript-eslint/types": "^8.32.1",
31
- "@typescript-eslint/utils": "^8.32.1",
30
+ "@typescript-eslint/types": "^8.33.1",
31
+ "@typescript-eslint/utils": "^8.33.1",
32
32
  "natural-orderby": "^5.0.0"
33
33
  },
34
34
  "peerDependencies": {
@@ -1,18 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- let getCommentAfter = (node, source) => {
4
- let token = source.getTokenAfter(node, {
5
- filter: ({ value, type }) =>
6
- type !== 'Punctuator' || ![',', ';', ':'].includes(value),
7
- includeComments: true,
8
- })
9
- if (
10
- ((token == null ? void 0 : token.type) === 'Block' ||
11
- (token == null ? void 0 : token.type) === 'Line') &&
12
- node.loc.end.line === token.loc.end.line
13
- ) {
14
- return token
15
- }
16
- return null
17
- }
18
- exports.getCommentAfter = getCommentAfter
@@ -1,11 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const isPartitionComment = require('./is-partition-comment.js')
4
- let hasPartitionComment = ({ partitionByComment, comments }) =>
5
- comments.some(comment =>
6
- isPartitionComment.isPartitionComment({
7
- partitionByComment,
8
- comment,
9
- }),
10
- )
11
- exports.hasPartitionComment = hasPartitionComment
@@ -1,4 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- let toSingleLine = string => string.replaceAll(/\s{2,}/gu, ' ').trim()
4
- exports.toSingleLine = toSingleLine
@@ -1,18 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
- const isNewlinesBetweenOption = require('./is-newlines-between-option.js')
4
- let validateNewlinesBetweenInsideGroups = ({ groups }) => {
5
- let isPreviousElementNewlinesBetween = false
6
- for (let groupElement of groups) {
7
- if (!isNewlinesBetweenOption.isNewlinesBetweenOption(groupElement)) {
8
- isPreviousElementNewlinesBetween = false
9
- continue
10
- }
11
- if (isPreviousElementNewlinesBetween) {
12
- throw new Error("Consecutive 'newlinesBetween' objects are not allowed")
13
- }
14
- isPreviousElementNewlinesBetween = true
15
- }
16
- }
17
- exports.validateNewlinesBetweenInsideGroups =
18
- validateNewlinesBetweenInsideGroups