eslint-plugin-perfectionist 3.8.0 → 3.9.1

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 (59) hide show
  1. package/dist/index.d.ts +74 -32
  2. package/dist/index.js +7 -4
  3. package/dist/index.mjs +7 -4
  4. package/dist/rules/sort-array-includes.js +8 -0
  5. package/dist/rules/sort-array-includes.mjs +8 -0
  6. package/dist/rules/sort-astro-attributes.js +10 -0
  7. package/dist/rules/sort-astro-attributes.mjs +10 -0
  8. package/dist/rules/sort-classes-utils.js +58 -0
  9. package/dist/rules/sort-classes-utils.mjs +52 -0
  10. package/dist/rules/sort-classes.js +31 -50
  11. package/dist/rules/sort-classes.mjs +29 -44
  12. package/dist/rules/sort-classes.types.js +4 -0
  13. package/dist/rules/sort-classes.types.mjs +4 -0
  14. package/dist/rules/sort-enums.js +9 -0
  15. package/dist/rules/sort-enums.mjs +9 -0
  16. package/dist/rules/sort-exports.js +8 -0
  17. package/dist/rules/sort-exports.mjs +8 -0
  18. package/dist/rules/sort-imports.js +222 -254
  19. package/dist/rules/sort-imports.mjs +208 -238
  20. package/dist/rules/sort-interfaces.js +19 -2
  21. package/dist/rules/sort-interfaces.mjs +19 -2
  22. package/dist/rules/sort-intersection-types.js +8 -0
  23. package/dist/rules/sort-intersection-types.mjs +8 -0
  24. package/dist/rules/sort-jsx-props.js +8 -0
  25. package/dist/rules/sort-jsx-props.mjs +8 -0
  26. package/dist/rules/sort-maps.js +8 -0
  27. package/dist/rules/sort-maps.mjs +8 -0
  28. package/dist/rules/sort-named-exports.js +8 -0
  29. package/dist/rules/sort-named-exports.mjs +8 -0
  30. package/dist/rules/sort-named-imports.js +8 -0
  31. package/dist/rules/sort-named-imports.mjs +8 -0
  32. package/dist/rules/sort-object-types.js +20 -3
  33. package/dist/rules/sort-object-types.mjs +20 -3
  34. package/dist/rules/sort-objects.js +8 -0
  35. package/dist/rules/sort-objects.mjs +8 -0
  36. package/dist/rules/sort-sets.js +1 -0
  37. package/dist/rules/sort-sets.mjs +1 -0
  38. package/dist/rules/sort-svelte-attributes.js +10 -0
  39. package/dist/rules/sort-svelte-attributes.mjs +10 -0
  40. package/dist/rules/sort-switch-case.js +13 -3
  41. package/dist/rules/sort-switch-case.mjs +13 -3
  42. package/dist/rules/sort-union-types.js +8 -0
  43. package/dist/rules/sort-union-types.mjs +8 -0
  44. package/dist/rules/sort-variable-declarations.js +8 -0
  45. package/dist/rules/sort-variable-declarations.mjs +8 -0
  46. package/dist/rules/sort-vue-attributes.js +10 -0
  47. package/dist/rules/sort-vue-attributes.mjs +10 -0
  48. package/dist/utils/compare.js +17 -3
  49. package/dist/utils/compare.mjs +17 -3
  50. package/dist/utils/get-options-with-clean-groups.js +13 -0
  51. package/dist/utils/get-options-with-clean-groups.mjs +11 -0
  52. package/dist/utils/get-settings.js +9 -10
  53. package/dist/utils/get-settings.mjs +9 -10
  54. package/dist/utils/sort-nodes-by-groups.js +33 -7
  55. package/dist/utils/sort-nodes-by-groups.mjs +33 -7
  56. package/dist/utils/validate-groups-configuration.js +11 -0
  57. package/dist/utils/validate-groups-configuration.mjs +11 -1
  58. package/package.json +3 -3
  59. package/readme.md +1 -1
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ declare type AccessorPropertySelector = 'accessor-property'
12
12
 
13
13
  declare type AdvancedSingleCustomGroup<T extends Selector> = {
14
14
  decoratorNamePattern?: string
15
+ elementValuePattern?: string
15
16
  elementNamePattern?: string
16
17
  } & BaseSingleCustomGroup<T>
17
18
 
@@ -114,6 +115,7 @@ declare const _default: {
114
115
  Partial<{
115
116
  type: 'alphabetical' | 'line-length' | 'natural'
116
117
  partitionByComment: string[] | boolean | string
118
+ specialCharacters: 'remove' | 'trim' | 'keep'
117
119
  matcher: 'minimatch' | 'regex'
118
120
  partitionByNewLine: boolean
119
121
  order: 'desc' | 'asc'
@@ -130,6 +132,7 @@ declare const _default: {
130
132
  Partial<{
131
133
  type: 'alphabetical' | 'line-length' | 'natural'
132
134
  partitionByComment: string[] | boolean | string
135
+ specialCharacters: 'remove' | 'trim' | 'keep'
133
136
  matcher: 'minimatch' | 'regex'
134
137
  groups: (
135
138
  | (
@@ -180,6 +183,7 @@ declare const _default: {
180
183
  [x: string]: string | string[]
181
184
  }
182
185
  type: 'alphabetical' | 'line-length' | 'natural'
186
+ specialCharacters: 'remove' | 'trim' | 'keep'
183
187
  groups: (string | string[])[]
184
188
  matcher: 'minimatch' | 'regex'
185
189
  order: 'desc' | 'asc'
@@ -197,6 +201,7 @@ declare const _default: {
197
201
  [x: string]: string | string[]
198
202
  }
199
203
  type: 'alphabetical' | 'line-length' | 'natural'
204
+ specialCharacters: 'remove' | 'trim' | 'keep'
200
205
  groups: (string | string[])[]
201
206
  matcher: 'minimatch' | 'regex'
202
207
  order: 'desc' | 'asc'
@@ -214,6 +219,7 @@ declare const _default: {
214
219
  [x: string]: string | string[]
215
220
  }
216
221
  type: 'alphabetical' | 'line-length' | 'natural'
222
+ specialCharacters: 'remove' | 'trim' | 'keep'
217
223
  groups: (string | string[])[]
218
224
  matcher: 'minimatch' | 'regex'
219
225
  order: 'desc' | 'asc'
@@ -236,6 +242,7 @@ declare const _default: {
236
242
  groupKind: 'values-first' | 'types-first' | 'mixed'
237
243
  type: 'alphabetical' | 'line-length' | 'natural'
238
244
  partitionByComment: string[] | boolean | string
245
+ specialCharacters: 'remove' | 'trim' | 'keep'
239
246
  matcher: 'minimatch' | 'regex'
240
247
  partitionByNewLine: boolean
241
248
  order: 'desc' | 'asc'
@@ -253,6 +260,7 @@ declare const _default: {
253
260
  groupKind: 'values-first' | 'types-first' | 'mixed'
254
261
  type: 'alphabetical' | 'line-length' | 'natural'
255
262
  partitionByComment: string[] | boolean | string
263
+ specialCharacters: 'remove' | 'trim' | 'keep'
256
264
  matcher: 'minimatch' | 'regex'
257
265
  partitionByNewLine: boolean
258
266
  order: 'desc' | 'asc'
@@ -272,6 +280,7 @@ declare const _default: {
272
280
  }
273
281
  type: 'alphabetical' | 'line-length' | 'natural'
274
282
  partitionByComment: string[] | boolean | string
283
+ specialCharacters: 'remove' | 'trim' | 'keep'
275
284
  groups: (string | string[])[]
276
285
  matcher: 'minimatch' | 'regex'
277
286
  partitionByNewLine: boolean
@@ -288,6 +297,7 @@ declare const _default: {
288
297
  Partial<{
289
298
  type: 'alphabetical' | 'line-length' | 'natural'
290
299
  partitionByComment: string[] | boolean | string
300
+ specialCharacters: 'remove' | 'trim' | 'keep'
291
301
  matcher: 'minimatch' | 'regex'
292
302
  groups: (
293
303
  | (
@@ -334,6 +344,7 @@ declare const _default: {
334
344
  [
335
345
  Partial<{
336
346
  type: 'alphabetical' | 'line-length' | 'natural'
347
+ specialCharacters: 'remove' | 'trim' | 'keep'
337
348
  order: 'desc' | 'asc'
338
349
  ignoreCase: boolean
339
350
  }>,
@@ -352,6 +363,7 @@ declare const _default: {
352
363
  }
353
364
  type: 'alphabetical' | 'line-length' | 'natural'
354
365
  partitionByComment: string[] | boolean | string
366
+ specialCharacters: 'remove' | 'trim' | 'keep'
355
367
  groups: (string | string[])[]
356
368
  matcher: 'minimatch' | 'regex'
357
369
  partitionByNewLine: boolean
@@ -371,6 +383,7 @@ declare const _default: {
371
383
  [x: string]: string | string[]
372
384
  }
373
385
  type: 'alphabetical' | 'line-length' | 'natural'
386
+ specialCharacters: 'remove' | 'trim' | 'keep'
374
387
  groups: (string | string[])[]
375
388
  matcher: 'minimatch' | 'regex'
376
389
  ignorePattern: string[]
@@ -390,36 +403,8 @@ declare const _default: {
390
403
  RuleListener
391
404
  >
392
405
  'sort-imports': RuleModule<
393
- | 'missedSpacingBetweenImports'
394
- | 'unexpectedImportsGroupOrder'
395
- | 'extraSpacingBetweenImports'
396
- | 'unexpectedImportsOrder',
397
- [
398
- Partial<{
399
- customGroups: {
400
- value?:
401
- | {
402
- [x: string]: string | string[]
403
- }
404
- | undefined
405
- type?:
406
- | {
407
- [x: string]: string | string[]
408
- }
409
- | undefined
410
- }
411
- type: 'alphabetical' | 'line-length' | 'natural'
412
- newlinesBetween: 'ignore' | 'always' | 'never'
413
- groups: (string | string[])[]
414
- matcher: 'minimatch' | 'regex'
415
- environment: 'node' | 'bun'
416
- internalPattern: string[]
417
- sortSideEffects: boolean
418
- maxLineLength?: number
419
- order: 'desc' | 'asc'
420
- ignoreCase: boolean
421
- }>,
422
- ],
406
+ MESSAGE_ID,
407
+ Options_2<string[]>,
423
408
  unknown,
424
409
  RuleListener
425
410
  >
@@ -430,6 +415,7 @@ declare const _default: {
430
415
  groupKind: 'values-first' | 'types-first' | 'mixed'
431
416
  type: 'alphabetical' | 'line-length' | 'natural'
432
417
  partitionByComment: string[] | boolean | string
418
+ specialCharacters: 'remove' | 'trim' | 'keep'
433
419
  matcher: 'minimatch' | 'regex'
434
420
  partitionByNewLine: boolean
435
421
  order: 'desc' | 'asc'
@@ -450,6 +436,7 @@ declare const _default: {
450
436
  }
451
437
  type: 'alphabetical' | 'line-length' | 'natural'
452
438
  partitionByComment: string[] | boolean | string
439
+ specialCharacters: 'remove' | 'trim' | 'keep'
453
440
  matcher: 'minimatch' | 'regex'
454
441
  groups: (string[] | string)[]
455
442
  partitionByNewLine: boolean
@@ -465,7 +452,7 @@ declare const _default: {
465
452
  >
466
453
  'sort-enums': RuleModule<
467
454
  'unexpectedEnumsDependencyOrder' | 'unexpectedEnumsOrder',
468
- Options_2,
455
+ Options_3,
469
456
  unknown,
470
457
  RuleListener
471
458
  >
@@ -481,6 +468,7 @@ declare const _default: {
481
468
  Partial<{
482
469
  type: 'alphabetical' | 'line-length' | 'natural'
483
470
  partitionByComment: string[] | boolean | string
471
+ specialCharacters: 'remove' | 'trim' | 'keep'
484
472
  matcher: 'minimatch' | 'regex'
485
473
  partitionByNewLine: boolean
486
474
  order: 'desc' | 'asc'
@@ -527,11 +515,38 @@ declare type Group =
527
515
  | 'unknown'
528
516
  | string
529
517
 
518
+ declare type Group_2<T extends string[]> =
519
+ | 'side-effect-style'
520
+ | 'external-type'
521
+ | 'internal-type'
522
+ | 'builtin-type'
523
+ | 'sibling-type'
524
+ | 'parent-type'
525
+ | 'side-effect'
526
+ | 'index-type'
527
+ | 'internal'
528
+ | 'external'
529
+ | T[number]
530
+ | 'sibling'
531
+ | 'unknown'
532
+ | 'builtin'
533
+ | 'parent'
534
+ | 'object'
535
+ | 'index'
536
+ | 'style'
537
+ | 'type'
538
+
530
539
  declare type IndexSignatureGroup =
531
540
  `${StaticModifierPrefix}${ReadonlyModifierPrefix}${IndexSignatureSelector}`
532
541
 
533
542
  declare type IndexSignatureSelector = 'index-signature'
534
543
 
544
+ declare type MESSAGE_ID =
545
+ | 'missedSpacingBetweenImports'
546
+ | 'unexpectedImportsGroupOrder'
547
+ | 'extraSpacingBetweenImports'
548
+ | 'unexpectedImportsOrder'
549
+
535
550
  declare type MethodGroup =
536
551
  `${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${DecoratedModifierPrefix}${OptionalModifierPrefix}${MethodSelector}`
537
552
 
@@ -549,6 +564,7 @@ declare type Options = [
549
564
  groupKind: 'literals-first' | 'spreads-first' | 'mixed'
550
565
  type: 'alphabetical' | 'line-length' | 'natural'
551
566
  partitionByComment: string[] | boolean | string
567
+ specialCharacters: 'remove' | 'trim' | 'keep'
552
568
  matcher: 'minimatch' | 'regex'
553
569
  partitionByNewLine: boolean
554
570
  order: 'desc' | 'asc'
@@ -556,10 +572,35 @@ declare type Options = [
556
572
  }>,
557
573
  ]
558
574
 
559
- declare type Options_2 = [
575
+ declare type Options_2<T extends string[]> = [
576
+ Partial<{
577
+ customGroups: {
578
+ value?: {
579
+ [key in T[number]]: string[] | string
580
+ }
581
+ type?: {
582
+ [key in T[number]]: string[] | string
583
+ }
584
+ }
585
+ type: 'alphabetical' | 'line-length' | 'natural'
586
+ newlinesBetween: 'ignore' | 'always' | 'never'
587
+ specialCharacters: 'remove' | 'trim' | 'keep'
588
+ groups: (Group_2<T>[] | Group_2<T>)[]
589
+ matcher: 'minimatch' | 'regex'
590
+ environment: 'node' | 'bun'
591
+ internalPattern: string[]
592
+ sortSideEffects: boolean
593
+ maxLineLength?: number
594
+ order: 'desc' | 'asc'
595
+ ignoreCase: boolean
596
+ }>,
597
+ ]
598
+
599
+ declare type Options_3 = [
560
600
  Partial<{
561
601
  type: 'alphabetical' | 'line-length' | 'natural'
562
602
  partitionByComment: string[] | boolean | string
603
+ specialCharacters: 'remove' | 'trim' | 'keep'
563
604
  matcher: 'minimatch' | 'regex'
564
605
  partitionByNewLine: boolean
565
606
  forceNumericSort: boolean
@@ -627,6 +668,7 @@ declare type SortClassesOptions = [
627
668
  | CustomGroup[]
628
669
  type: 'alphabetical' | 'line-length' | 'natural'
629
670
  partitionByComment: string[] | boolean | string
671
+ specialCharacters: 'remove' | 'trim' | 'keep'
630
672
  matcher: 'minimatch' | 'regex'
631
673
  groups: (Group[] | Group)[]
632
674
  order: 'desc' | 'asc'
package/dist/index.js CHANGED
@@ -47,10 +47,13 @@ let plugin = {
47
47
  }
48
48
  let getRules = options =>
49
49
  Object.fromEntries(
50
- Object.keys(plugin.rules).map(rule => [
51
- `${name}/${rule}`,
52
- ['error', options],
53
- ]),
50
+ Object.entries(plugin.rules).reduce(
51
+ (accumulator, [ruleName, ruleValue]) =>
52
+ ruleValue.meta.deprecated
53
+ ? accumulator
54
+ : [...accumulator, [`${name}/${ruleName}`, ['error', options]]],
55
+ [],
56
+ ),
54
57
  )
55
58
  let createConfig = options => ({
56
59
  plugins: {
package/dist/index.mjs CHANGED
@@ -46,10 +46,13 @@ let plugin = {
46
46
  }
47
47
  let getRules = options =>
48
48
  Object.fromEntries(
49
- Object.keys(plugin.rules).map(rule => [
50
- `${name}/${rule}`,
51
- ['error', options],
52
- ]),
49
+ Object.entries(plugin.rules).reduce(
50
+ (accumulator, [ruleName, ruleValue]) =>
51
+ ruleValue.meta.deprecated
52
+ ? accumulator
53
+ : [...accumulator, [`${name}/${ruleName}`, ['error', options]]],
54
+ [],
55
+ ),
53
56
  )
54
57
  let createConfig = options => ({
55
58
  plugins: {
@@ -41,6 +41,12 @@ let jsonSchema = {
41
41
  description: 'Controls whether sorting should be case-sensitive or not.',
42
42
  type: 'boolean',
43
43
  },
44
+ specialCharacters: {
45
+ description:
46
+ 'Controls how special characters should be handled before sorting.',
47
+ type: 'string',
48
+ enum: ['remove', 'trim', 'keep'],
49
+ },
44
50
  groupKind: {
45
51
  description: 'Specifies top-level groups.',
46
52
  enum: ['mixed', 'literals-first', 'spreads-first'],
@@ -91,6 +97,7 @@ const sortArrayIncludes = createEslintRule.createEslintRule({
91
97
  type: 'alphabetical',
92
98
  order: 'asc',
93
99
  ignoreCase: true,
100
+ specialCharacters: 'keep',
94
101
  matcher: 'minimatch',
95
102
  groupKind: 'literals-first',
96
103
  partitionByComment: false,
@@ -121,6 +128,7 @@ let sortArray = (context, messageId, elements) => {
121
128
  groupKind: 'literals-first',
122
129
  type: 'alphabetical',
123
130
  ignoreCase: true,
131
+ specialCharacters: 'keep',
124
132
  matcher: 'minimatch',
125
133
  order: 'asc',
126
134
  partitionByComment: false,
@@ -36,6 +36,12 @@ let jsonSchema = {
36
36
  description: 'Controls whether sorting should be case-sensitive or not.',
37
37
  type: 'boolean',
38
38
  },
39
+ specialCharacters: {
40
+ description:
41
+ 'Controls how special characters should be handled before sorting.',
42
+ type: 'string',
43
+ enum: ['remove', 'trim', 'keep'],
44
+ },
39
45
  groupKind: {
40
46
  description: 'Specifies top-level groups.',
41
47
  enum: ['mixed', 'literals-first', 'spreads-first'],
@@ -86,6 +92,7 @@ const sortArrayIncludes = createEslintRule({
86
92
  type: 'alphabetical',
87
93
  order: 'asc',
88
94
  ignoreCase: true,
95
+ specialCharacters: 'keep',
89
96
  matcher: 'minimatch',
90
97
  groupKind: 'literals-first',
91
98
  partitionByComment: false,
@@ -116,6 +123,7 @@ let sortArray = (context, messageId, elements) => {
116
123
  groupKind: 'literals-first',
117
124
  type: 'alphabetical',
118
125
  ignoreCase: true,
126
+ specialCharacters: 'keep',
119
127
  matcher: 'minimatch',
120
128
  order: 'asc',
121
129
  partitionByComment: false,
@@ -19,6 +19,8 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
19
19
  description: 'Enforce sorted Astro attributes.',
20
20
  },
21
21
  fixable: 'code',
22
+ deprecated: true,
23
+ replacedBy: ['astro/sort-attributes'],
22
24
  schema: [
23
25
  {
24
26
  type: 'object',
@@ -44,6 +46,12 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
44
46
  'Controls whether sorting should be case-sensitive or not.',
45
47
  type: 'boolean',
46
48
  },
49
+ specialCharacters: {
50
+ description:
51
+ 'Controls how special characters should be handled before sorting.',
52
+ type: 'string',
53
+ enum: ['remove', 'trim', 'keep'],
54
+ },
47
55
  groups: {
48
56
  description: 'Specifies the order of the groups.',
49
57
  type: 'array',
@@ -94,6 +102,7 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
94
102
  type: 'alphabetical',
95
103
  order: 'asc',
96
104
  ignoreCase: true,
105
+ specialCharacters: 'keep',
97
106
  matcher: 'minimatch',
98
107
  groups: [],
99
108
  customGroups: {},
@@ -112,6 +121,7 @@ const sortAstroAttributes = createEslintRule.createEslintRule({
112
121
  let options = complete.complete(context.options.at(0), settings, {
113
122
  type: 'alphabetical',
114
123
  ignoreCase: true,
124
+ specialCharacters: 'keep',
115
125
  matcher: 'minimatch',
116
126
  customGroups: {},
117
127
  order: 'asc',
@@ -18,6 +18,8 @@ const sortAstroAttributes = createEslintRule({
18
18
  description: 'Enforce sorted Astro attributes.',
19
19
  },
20
20
  fixable: 'code',
21
+ deprecated: true,
22
+ replacedBy: ['astro/sort-attributes'],
21
23
  schema: [
22
24
  {
23
25
  type: 'object',
@@ -43,6 +45,12 @@ const sortAstroAttributes = createEslintRule({
43
45
  'Controls whether sorting should be case-sensitive or not.',
44
46
  type: 'boolean',
45
47
  },
48
+ specialCharacters: {
49
+ description:
50
+ 'Controls how special characters should be handled before sorting.',
51
+ type: 'string',
52
+ enum: ['remove', 'trim', 'keep'],
53
+ },
46
54
  groups: {
47
55
  description: 'Specifies the order of the groups.',
48
56
  type: 'array',
@@ -93,6 +101,7 @@ const sortAstroAttributes = createEslintRule({
93
101
  type: 'alphabetical',
94
102
  order: 'asc',
95
103
  ignoreCase: true,
104
+ specialCharacters: 'keep',
96
105
  matcher: 'minimatch',
97
106
  groups: [],
98
107
  customGroups: {},
@@ -111,6 +120,7 @@ const sortAstroAttributes = createEslintRule({
111
120
  let options = complete(context.options.at(0), settings, {
112
121
  type: 'alphabetical',
113
122
  ignoreCase: true,
123
+ specialCharacters: 'keep',
114
124
  matcher: 'minimatch',
115
125
  customGroups: {},
116
126
  order: 'asc',
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
3
+ const validateGroupsConfiguration$1 = require('../utils/validate-groups-configuration.js')
4
+ const sortClasses_types = require('./sort-classes.types.js')
3
5
  const matches = require('../utils/matches.js')
4
6
  const cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
5
7
  const generateOfficialGroups = (modifiers, selectors) => {
@@ -128,6 +130,19 @@ const customGroupMatches = props => {
128
130
  return false
129
131
  }
130
132
  }
133
+ if (
134
+ 'elementValuePattern' in props.customGroup &&
135
+ props.customGroup.elementValuePattern
136
+ ) {
137
+ let matchesElementValuePattern = matches.matches(
138
+ props.elementValue ?? '',
139
+ props.customGroup.elementValuePattern,
140
+ props.matcher,
141
+ )
142
+ if (!matchesElementValuePattern) {
143
+ return false
144
+ }
145
+ }
131
146
  if (
132
147
  'decoratorNamePattern' in props.customGroup &&
133
148
  props.customGroup.decoratorNamePattern
@@ -157,10 +172,53 @@ const getCompareOptions = (options, groupNumber) => {
157
172
  customGroup && 'order' in customGroup && customGroup.order
158
173
  ? customGroup.order
159
174
  : options.order,
175
+ specialCharacters: options.specialCharacters,
160
176
  ignoreCase: options.ignoreCase,
161
177
  }
162
178
  }
179
+ let validateGroupsConfiguration = (groups, customGroups) => {
180
+ let availableCustomGroupNames = Array.isArray(customGroups)
181
+ ? customGroups.map(customGroup => customGroup.groupName)
182
+ : Object.keys(customGroups)
183
+ let invalidGroups = groups
184
+ .flat()
185
+ .filter(
186
+ group =>
187
+ !isPredefinedGroup(group) && !availableCustomGroupNames.includes(group),
188
+ )
189
+ if (invalidGroups.length) {
190
+ throw new Error('Invalid group(s): ' + invalidGroups.join(', '))
191
+ }
192
+ validateGroupsConfiguration$1.validateNoDuplicatedGroups(groups)
193
+ }
194
+ const isPredefinedGroup = input => {
195
+ if (input === 'unknown') {
196
+ return true
197
+ }
198
+ let singleWordSelector = input.split('-').at(-1)
199
+ if (!singleWordSelector) {
200
+ return false
201
+ }
202
+ let twoWordsSelector = input.split('-').slice(-2).join('-')
203
+ let isTwoWordSelectorValid =
204
+ sortClasses_types.allSelectors.includes(twoWordsSelector)
205
+ if (
206
+ !sortClasses_types.allSelectors.includes(singleWordSelector) &&
207
+ !isTwoWordSelectorValid
208
+ ) {
209
+ return false
210
+ }
211
+ let modifiers = input.split('-').slice(0, isTwoWordSelectorValid ? -2 : -1)
212
+ return (
213
+ new Set(modifiers).size === modifiers.length &&
214
+ modifiers.every(modifier =>
215
+ sortClasses_types.allModifiers.includes(modifier),
216
+ )
217
+ )
218
+ }
163
219
  exports.customGroupMatches = customGroupMatches
164
220
  exports.generateOfficialGroups = generateOfficialGroups
221
+ exports.getCombinations = getCombinations
165
222
  exports.getCompareOptions = getCompareOptions
166
223
  exports.getOverloadSignatureGroups = getOverloadSignatureGroups
224
+ exports.validateGroupsConfiguration = validateGroupsConfiguration
@@ -1,3 +1,5 @@
1
+ import { validateNoDuplicatedGroups } from '../utils/validate-groups-configuration.mjs'
2
+ import { allSelectors, allModifiers } from './sort-classes.types.mjs'
1
3
  import { matches } from '../utils/matches.mjs'
2
4
  const cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
3
5
  const generateOfficialGroups = (modifiers, selectors) => {
@@ -126,6 +128,19 @@ const customGroupMatches = props => {
126
128
  return false
127
129
  }
128
130
  }
131
+ if (
132
+ 'elementValuePattern' in props.customGroup &&
133
+ props.customGroup.elementValuePattern
134
+ ) {
135
+ let matchesElementValuePattern = matches(
136
+ props.elementValue ?? '',
137
+ props.customGroup.elementValuePattern,
138
+ props.matcher,
139
+ )
140
+ if (!matchesElementValuePattern) {
141
+ return false
142
+ }
143
+ }
129
144
  if (
130
145
  'decoratorNamePattern' in props.customGroup &&
131
146
  props.customGroup.decoratorNamePattern
@@ -155,12 +170,49 @@ const getCompareOptions = (options, groupNumber) => {
155
170
  customGroup && 'order' in customGroup && customGroup.order
156
171
  ? customGroup.order
157
172
  : options.order,
173
+ specialCharacters: options.specialCharacters,
158
174
  ignoreCase: options.ignoreCase,
159
175
  }
160
176
  }
177
+ let validateGroupsConfiguration = (groups, customGroups) => {
178
+ let availableCustomGroupNames = Array.isArray(customGroups)
179
+ ? customGroups.map(customGroup => customGroup.groupName)
180
+ : Object.keys(customGroups)
181
+ let invalidGroups = groups
182
+ .flat()
183
+ .filter(
184
+ group =>
185
+ !isPredefinedGroup(group) && !availableCustomGroupNames.includes(group),
186
+ )
187
+ if (invalidGroups.length) {
188
+ throw new Error('Invalid group(s): ' + invalidGroups.join(', '))
189
+ }
190
+ validateNoDuplicatedGroups(groups)
191
+ }
192
+ const isPredefinedGroup = input => {
193
+ if (input === 'unknown') {
194
+ return true
195
+ }
196
+ let singleWordSelector = input.split('-').at(-1)
197
+ if (!singleWordSelector) {
198
+ return false
199
+ }
200
+ let twoWordsSelector = input.split('-').slice(-2).join('-')
201
+ let isTwoWordSelectorValid = allSelectors.includes(twoWordsSelector)
202
+ if (!allSelectors.includes(singleWordSelector) && !isTwoWordSelectorValid) {
203
+ return false
204
+ }
205
+ let modifiers = input.split('-').slice(0, isTwoWordSelectorValid ? -2 : -1)
206
+ return (
207
+ new Set(modifiers).size === modifiers.length &&
208
+ modifiers.every(modifier => allModifiers.includes(modifier))
209
+ )
210
+ }
161
211
  export {
162
212
  customGroupMatches,
163
213
  generateOfficialGroups,
214
+ getCombinations,
164
215
  getCompareOptions,
165
216
  getOverloadSignatureGroups,
217
+ validateGroupsConfiguration,
166
218
  }