-
Notifications
You must be signed in to change notification settings - Fork 53
release v5.0.0 #569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
release v5.0.0 #569
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughConvert repository to ESM (package/type changes, Node >=20), replace deprecated object-based customGroups/groupKind APIs with array-based customGroups + groups, add partition/newline options and per-group overrides, refactor utils/types, expose defaultOptions in rule metadata, and add two new rules: sort-import-attributes and sort-export-attributes (with tests/docs). Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant ESLint as ESLint
participant Rule as sort-import/export-attributes
participant Groups as GroupsMatcher
participant Partitioner as Partitioner
participant Sorter as SortEngine
participant Reporter as reportAllErrors
ESLint->>Rule: Node (ImportDeclaration / ExportNamedDeclaration)
Rule->>Groups: compute group for each attribute (predefined + array customGroups)
Groups-->>Rule: groupName per attribute
Rule->>Partitioner: partition attributes (partitionByNewLine / partitionByComment)
Partitioner-->>Rule: partitions[]
loop per partition
Rule->>Sorter: apply per-group overrides (newlinesBetween/newlinesInside/fallbackSort)
Sorter-->>Rule: sorted nodes + ordering metadata
Rule->>Reporter: report spacing/group/order errors (includes leftGroup/rightGroup)
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120+ minutes Possibly related PRs
Suggested reviewers
Pre-merge checks❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
vite.config.ts (1)
17-23
: rollupOptions + preserveModules interplay — validate export pathsUsing preserveModules with multiple lib entry points and a custom fileName can affect final paths. Cross-check that the files referenced in package.json exports (especially ./alphabet) match the generated structure.
If you want fully predictable entry locations, consider setting rollupOptions.output.entryFileNames explicitly (e.g., '[name].js') and aligning exports accordingly.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
package.json
(2 hunks)vite.config.ts
(1 hunks)
🧰 Additional context used
🪛 ESLint
vite.config.ts
[error] 27-27: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
🔇 Additional comments (7)
package.json (4)
14-14
: ESM-only transition acknowledgedSwitching "type" to "module" aligns with the ESM-only objective. Ensure all Node-facing configs and scripts (and any code using __dirname/require) are ESM-safe.
129-129
: Engines updated to Node 20+/22+ — goodThis cleanly drops Node 18 in line with the plan to use newer language APIs (e.g., toSorted).
20-23
: Verify the ./alphabet export path consistency (JS vs types)Current mapping mixes paths:
- types: "./dist/alphabet.d.ts"
- default: "./dist/utils/alphabet.js"
Given preserveModules + custom fileName in Vite, confirm that both files exist at publish time. If the build flattens the entry to dist/alphabet.js (common with lib.fileName), align exports for consistency.
Two options (pick the one matching the actual build output):
- If output is flattened:
"./alphabet": { - "types": "./dist/alphabet.d.ts", - "default": "./dist/utils/alphabet.js" + "types": "./dist/alphabet.d.ts", + "default": "./dist/alphabet.js" },
- If output preserves utils/:
"./alphabet": { - "types": "./dist/alphabet.d.ts", + "types": "./dist/utils/alphabet.d.ts", "default": "./dist/utils/alphabet.js" },Also ensure the dts plugin actually emits the corresponding .d.ts at the chosen location.
125-127
: Align ESLint peerDependency with v9+ policyThe
peerDependencies
entry still permits ESLint v8 despite the stated objective to drop v8 support. Please confirm the intended minimum version and update accordingly:• File: package.json (lines 125–127)
• Current snippet:"peerDependencies": { "eslint": ">=8.45.0" }• Suggested change:
- "peerDependencies": { - "eslint": ">=8.45.0" - }, + "peerDependencies": { + "eslint": ">=9.0.0" + },If v8 compatibility is intentionally retained, ensure the PR description, documentation, and changelog accurately reflect that decision.
vite.config.ts (3)
15-16
: ESM-only build format — goodformats: ['es'] is consistent with the ESM-only package.json. This removes CJS output and matches ESLint v9’s ESM direction.
35-35
: copyDtsFiles: true — streamlined d.ts generationLooks good and complements the ESM setup. Just ensure it produces the files expected by package.json exports (e.g., ./alphabet).
27-27
: Ensure Proper Typings fordts
PluginESLint flags
dts(...)
as anany
call because TypeScript cannot resolve the default import’s types. Please verify that your roottsconfig.json
(which extends@azat-io/typescript-config
) enables:•
esModuleInterop: true
orallowSyntheticDefaultImports: true
• A moduleResolution mode supporting ES modules (e.g."NodeNext"
or"Bundler"
)If those aren’t set, add them under
compilerOptions
in your roottsconfig.json
.
Alternatively, you can:
Create a typed alias in
vite.config.ts
before callingdts
:import type { Plugin } from 'vite' import dts, { type Options as DtsOptions } from 'vite-plugin-dts' const dtsPlugin: (options?: DtsOptions) => Plugin = dts // … plugins: [ dtsPlugin({ /* … */ }) ]Or, as a last resort, disable the rule for that line:
// eslint-disable-next-line @typescript-eslint/no-unsafe-call dts({ /* … */ })Locations to verify:
- vite.config.ts:27
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #569 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 101 108 +7
Lines 8565 8875 +310
Branches 1688 1693 +5
==========================================
+ Hits 8565 8875 +310 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
vite.config.ts (1)
29-32
: Same Node 20 compatibility issue: replace import.meta.dirname in dts includeThe include paths will fail on Node 20. Use the same __dirname shim as above.
- path.join(import.meta.dirname, 'index.ts'), - path.join(import.meta.dirname, 'types'), - path.join(import.meta.dirname, 'rules'), - path.join(import.meta.dirname, 'utils'), + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'types'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'),
🧹 Nitpick comments (2)
vite.config.ts (2)
14-14
: name is unused for ES format — consider removingThe lib.name option is only used for IIFE/UMD builds. For ES builds it’s ignored; removing it avoids confusion.
- name: 'eslint-plugin-perfectionist',
27-27
: ESLint: no-unsafe-call on dts(...) — ensure types or locally suppressStatic analysis flags dts(...) as an unsafe call, likely because the import is typed as any in this environment. If your TS setup doesn’t pick up vite-plugin-dts types, either assert the type or suppress for config files.
Options:
- Type assertion:
import type { PluginOption } from 'vite' (dts({ // ... }) as unknown as PluginOption)
- Or disable the rule for this line/file:
// eslint-disable-next-line @typescript-eslint/no-unsafe-call dts({ /* ... */ })Please confirm whether your linter is actually failing CI on this, and I can tailor the fix.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (2)
package.json
(5 hunks)vite.config.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🪛 ESLint
vite.config.ts
[error] 27-27: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
🔇 Additional comments (2)
vite.config.ts (2)
15-15
: ESM-only build looks goodformats: ['es'] aligns with the ESM-only migration and ESLint 9.
35-35
: Good addition: copyDtsFilescopyDtsFiles: true helps keep declaration files in sync alongside preserveModules.
path.resolve(import.meta.dirname, 'index.ts'), | ||
path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'), | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix: import.meta.dirname breaks on Node 20 — use ESM-safe __dirname
import.meta.dirname isn’t available in Node 20; this will throw at build time and contradicts engines: "^20.0.0 || >=22.0.0". Either bump engines to >=22 only or switch to an ESM-safe __dirname shim.
Apply this diff within the current block:
- path.resolve(import.meta.dirname, 'index.ts'),
- path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'),
+ path.resolve(__dirname, 'index.ts'),
+ path.resolve(__dirname, 'utils', 'alphabet.ts'),
And add this near the imports (outside this hunk):
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
🤖 Prompt for AI Agents
In vite.config.ts around lines 10 to 12, import.meta.dirname is used which
breaks on Node 20; replace uses of import.meta.dirname with an ESM-safe
__dirname shim: add an import for fileURLToPath from 'node:url' and define const
__dirname = path.dirname(fileURLToPath(import.meta.url)) near the top imports,
then update the path.resolve calls in this block to use __dirname instead of
import.meta.dirname (do not change engines).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
vite.config.ts (1)
10-12
: import.meta.dirname will break on Node 20 — use an ESM-safe __dirname shimYour engines field allows Node 20, but
import.meta.dirname
is only available in Node 22+. Replace it with an ESM-safe__dirname
shim to keep Node 20 support intact. This was already raised earlier; reiterating with a concrete, minimal fix.Apply this diff within the selected lines:
- path.resolve(import.meta.dirname, 'index.ts'), - path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'), + path.resolve(__dirname, 'index.ts'), + path.resolve(__dirname, 'utils', 'alphabet.ts'),- path.join(import.meta.dirname, 'index.ts'), - path.join(import.meta.dirname, 'types'), - path.join(import.meta.dirname, 'rules'), - path.join(import.meta.dirname, 'utils'), + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'types'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'),Add this near the imports (outside the selected ranges):
import { fileURLToPath } from 'node:url' const __dirname = path.dirname(fileURLToPath(import.meta.url))Also applies to: 29-32
🧹 Nitpick comments (3)
vite.config.ts (3)
27-27
: Silence no-unsafe-call by typing the dts factoryESLint flagged this call as unsafe (any/unknown). Wrap the default export in a typed factory to satisfy the rule without changing behavior.
Apply this diff to the call site:
- dts({ + createDtsPlugin({Add the following (outside the selected range, near the imports):
import type { PluginOption } from 'vite' import type { PluginOptions } from 'vite-plugin-dts' const createDtsPlugin: (options?: PluginOptions) => PluginOption = dts
2-2
: Use vitest/config defineConfig so thetest
block is typed and discoverableImporting
defineConfig
fromvitest/config
ensures thetest
property is properly typed and recognized by Vitest tooling.-import { defineConfig } from 'vite' +import { defineConfig } from 'vitest/config'
19-21
: Nit:exports: 'auto'
is unnecessary for ES-only outputThis Rollup option is relevant for CJS. Since you’re emitting only ES modules, you can safely drop it.
output: { preserveModules: true, - exports: 'auto', },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (2)
package.json
(5 hunks)vite.config.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🪛 ESLint
vite.config.ts
[error] 27-27: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
🔇 Additional comments (1)
vite.config.ts (1)
13-16
: ESM-only build and preserved modules — LGTMThe switch to formats: ['es'] with preserveModules aligns with the ESM-only objective. File naming is consistent and explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
test/rules/sort-decorators.test.ts (1)
1-6998
: Migrate object-based customGroups to the new array API
In test/rules/sort-decorators.test.ts, replace everycustomGroups: { /* groupName: elementNamePattern [, …] */ },with
customGroups: [ { groupName: 'error', elementNamePattern: 'Error$' }, ],and for multiple entries:
- customGroups: { A: 'A', B: 'B' }, + customGroups: [ + { groupName: 'A', elementNamePattern: 'A' }, + { groupName: 'B', elementNamePattern: 'B' }, +],docs/content/rules/sort-decorators.mdx (2)
272-276
: Update groups type to reflect inline newlines objects.Examples use { newlinesBetween: ... } between groups, but the declared type omits these objects.
-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: 'always' | 'never' | number | 'ignore' }>` +</sub>Also applies to: 293-311
519-521
: Fix test source link path.The file lives under test/rules/sort-decorators.test.ts in this PR.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-decorators.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-decorators.test.ts)
🧹 Nitpick comments (7)
rules/sort-decorators/types.ts (3)
40-40
: Redundant union: 'unknown' | string.This widens to plain string; prefer just string for clarity.
-type Group = 'unknown' | string +type Group = string
42-44
: Make schema constant and non-reassignable.Minor: declare as const to avoid accidental reassignment.
-export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { elementNamePattern: regexJsonSchema, }
34-36
: Add concise JSDoc on exported public types.Public-facing types (Options, SingleCustomGroup) lack JSDoc; add brief comments to improve DX and align with PR objective.
Also applies to: 17-33
test/rules/sort-decorators.test.ts (1)
665-753
: ESLint: no-unsafe-call on tagged templates (dedent).Static analysis flags dedent template calls as unsafe (typed any/unknown). Two low-touch fixes:
- Install proper types: add @types/dedent dev dep (or switch to ts-dedent).
- Or disable the rule for this test file.
Options:
- Prefer proper typing
// package.json (devDependencies) "@types/dedent": "^1.0.3"
- File-level disable (top of this test file)
/* eslint-disable @typescript-eslint/no-unsafe-call */
Also applies to: 808-883, 885-995, 997-1044, 1046-1109, 1110-1177, 1179-1254, 1256-1307, 1309-1423, 1425-1465, 1467-1517, 1519-1725, 4861-5030
docs/content/rules/sort-decorators.mdx (1)
247-253
: Clarify partitionByNewLine description.Minor wording to reflect “sort within newline-delimited partitions”.
-When `true`, the rule will not sort the decorators if there is an empty line between them. +When `true`, blank lines create partitions: decorators are sorted within each partition but not moved across blank lines.rules/sort-decorators.ts (2)
145-160
: Broaden parameter-decorator detection to avoid false negatives.The current check requires the decorated node to be an Identifier under a FunctionExpression. This can miss valid TS cases (e.g., TSParameterProperty, default/rest patterns). Relaxing the node-type check improves coverage without impacting class/property/class-decorator handlers.
Apply this minimal diff:
- if ( - 'decorators' in decorator.parent && - decorator.parent.type === 'Identifier' && - decorator.parent.parent.type === 'FunctionExpression' - ) { + if ( + 'decorators' in decorator.parent && + decorator.parent.parent?.type === 'FunctionExpression' + ) {Would you like me to add tests for constructor parameters with parameter properties and default/rest patterns?
237-253
: Nit: avoid repeated .at(-1) calls and correct partition index to be zero-based.
- Minor perf/readability: cache the current bucket.
- Partition IDs are typically zero-based; using length produces 1-based IDs.
Apply this diff:
- let lastSortingNode = accumulator.at(-1)?.at(-1) + let bucket = accumulator[accumulator.length - 1] + let lastSortingNode = bucket.at(-1) if ( shouldPartition({ lastSortingNode, sortingNode, sourceCode, options, }) ) { - accumulator.push([]) + bucket = [] + accumulator.push(bucket) } - accumulator.at(-1)!.push({ + bucket.push({ ...sortingNode, - partitionId: accumulator.length, + partitionId: accumulator.length - 1, })If other utilities rely on 1-based IDs, keep the old value and skip the index tweak.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/content/rules/sort-decorators.mdx
(5 hunks)rules/sort-decorators.ts
(5 hunks)rules/sort-decorators/types.ts
(1 hunks)test/rules/sort-decorators.test.ts
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
rules/sort-decorators/types.ts (3)
types/common-options.ts (7)
CustomGroupsOption
(103-140)DeprecatedCustomGroupsOption
(473-473)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(499-499)types/sorting-node.ts (1)
SortingNode
(18-102)utils/common-json-schemas.ts (1)
regexJsonSchema
(237-246)
rules/sort-decorators.ts (6)
rules/sort-decorators/types.ts (1)
Options
(17-32)utils/common-json-schemas.ts (5)
deprecatedCustomGroupsJsonSchema
(192-208)buildCustomGroupsArrayJsonSchema
(320-369)partitionByNewLineJsonSchema
(286-290)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)
🪛 ESLint
test/rules/sort-decorators.test.ts
[error] 674-674: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 701-701: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 791-791: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 798-798: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 829-829: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 851-851: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 887-887: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 929-929: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 999-999: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1089-1089: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1099-1099: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1157-1157: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1166-1166: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1228-1228: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1240-1240: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1293-1293: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1300-1300: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1349-1349: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1354-1354: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1390-1390: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1416-1416: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1450-1450: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1457-1457: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1497-1497: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1506-1506: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1547-1547: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1553-1553: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1591-1591: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1596-1596: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1608-1608: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1655-1655: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🔇 Additional comments (10)
test/rules/sort-decorators.test.ts (5)
665-753
: Great parametric coverage for elementNamePattern.Covers strings, arrays, and regex objects; helps ensure RegexOption variants all work.
754-806
: Solid tie-breaker test for fallbackSort.Accurately validates line-length ties resolved via alphabetical fallback.
Also applies to: 808-883
885-995
: Unsorted group behavior verified correctly.Ensures intra-group order is preserved while enforcing group ordering.
1110-1177
: Spacing matrix is comprehensive.Nice coverage of global vs inline newlinesBetween and newlinesInside combinations.
Also applies to: 1179-1254, 1256-1307, 1309-1423
1519-1725
: partitionByNewLine semantics validated.Good check that sorting occurs within, not across, blank-line partitions.
rules/sort-decorators.ts (5)
4-7
: Type centralization LGTM.Moving public types into rules/sort-decorators/types reduces duplication and drift across files.
70-131
: Meta/schema and messages look consistent.
- New options (partitionByNewLine/newlinesBetween) are correctly exposed in the schema.
- Messages map aligns with the renamed public IDs.
142-142
: Good guard on mutually exclusive newline options.The explicit validation prevents ambiguous configurations at runtime.
274-280
: Tests cover all new message IDs. Verified thatmissedSpacingBetweenDecorators
,extraSpacingBetweenDecorators
,unexpectedDecoratorsGroupOrder
, andunexpectedDecoratorsOrder
are referenced throughouttest/rules/sort-decorators.test.ts
.
169-176
: AccessorProperty is supported by current parser version
@typescript-eslint/parser v8.39.0 includesAST_NODE_TYPES.AccessorProperty
(introduced in v7.16.0), so this listener will fire as intended. (newreleases.io)
<sub>type: `number | 'ignore'`</sub> | ||
<sub>default: `'ignore'`</sub> | ||
|
||
Specifies how to handle newlines between groups. | ||
|
||
- `'ignore'` — Do not report errors related to newlines. | ||
- `0` — No newlines are allowed. | ||
- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix newlinesBetween type and values.
The rule accepts 'always' | 'never' | number | 'ignore', but docs show only number | 'ignore'.
-<sub>type: `number | 'ignore'`</sub>
+<sub>type: `'always' | 'never' | number | 'ignore'`</sub>
...
-Specifies how to handle newlines between groups.
+Specifies how to handle newlines between groups.
...
-- `'ignore'` — Do not report errors related to newlines.
-- `0` — No newlines are allowed.
-- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups.
+- `'ignore'` — Do not report errors related to newlines.
+- `'always'` — Exactly one blank line between groups.
+- `'never'` — No blank lines between groups.
+- `0` — No blank lines between groups.
+- Any other number — Enforce this exact number of blank lines between groups; forbid blank lines inside groups.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<sub>type: `number | 'ignore'`</sub> | |
<sub>default: `'ignore'`</sub> | |
Specifies how to handle newlines between groups. | |
- `'ignore'` — Do not report errors related to newlines. | |
- `0` — No newlines are allowed. | |
- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. | |
<sub>type: `'always' | 'never' | number | 'ignore'`</sub> | |
<sub>default: `'ignore'`</sub> | |
Specifies how to handle newlines between groups. | |
- `'ignore'` — Do not report errors related to newlines. | |
- `'always'` — Exactly one blank line between groups. | |
- `'never'` — No blank lines between groups. | |
- `0` — No blank lines between groups. | |
- Any other number — Enforce this exact number of blank lines between groups; forbid blank lines inside groups. |
🤖 Prompt for AI Agents
In docs/content/rules/sort-decorators.mdx around lines 255 to 263, the
documented type and allowed values for the newlinesBetween option are wrong:
update the type annotation to include 'always' | 'never' | number | 'ignore'
(instead of only number | 'ignore'), adjust the default if needed, and expand
the bullet list to document the 'always' and 'never' cases (e.g., 'always' —
require a newline between groups; 'never' — forbid newlines between groups),
while keeping the existing descriptions for numeric values and 'ignore'.
interface CustomGroupDefinition { | ||
groupName: string | ||
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | ||
order?: 'asc' | 'desc' | ||
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | ||
newlinesInside?: number | ||
selector?: string | ||
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct CustomGroupDefinition typings (fallbackSort, newlinesInside).
Align with runtime/types: fallbackSort type union; newlinesInside supports 'always' | 'never' | number.
interface CustomGroupDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
- fallbackSort?: { type: string; order?: 'asc' | 'desc' }
- newlinesInside?: number
+ fallbackSort?: {
+ type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
+ order?: 'asc' | 'desc'
+ }
+ newlinesInside?: 'always' | 'never' | number
selector?: string
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
interface CustomGroupDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | |
newlinesInside?: number | |
selector?: string | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
} | |
interface CustomGroupDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { | |
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' | |
order?: 'asc' | 'desc' | |
} | |
newlinesInside?: 'always' | 'never' | number | |
selector?: string | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
} |
🤖 Prompt for AI Agents
In docs/content/rules/sort-decorators.mdx around lines 352 to 360, the
CustomGroupDefinition TypeScript example has incorrect typings for fallbackSort
and newlinesInside; update fallbackSort to be a union matching runtime/types
(i.e. allow the same sort descriptor shape or the broader union used at runtime,
not just { type: string; order?: 'asc'|'desc' }), and change newlinesInside to
accept 'always' | 'never' | number instead of only number; adjust the typedef
text accordingly so the docs match the runtime/types definitions.
interface CustomGroupAnyOfDefinition { | ||
groupName: string | ||
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | ||
order?: 'asc' | 'desc' | ||
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | ||
newlinesInside?: number | ||
anyOf: Array<{ | ||
selector?: string | ||
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | ||
}> | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct CustomGroupAnyOfDefinition typings (fallbackSort, newlinesInside).
Same issue as above.
interface CustomGroupAnyOfDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
- fallbackSort?: { type: string; order?: 'asc' | 'desc' }
- newlinesInside?: number
+ fallbackSort?: {
+ type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
+ order?: 'asc' | 'desc'
+ }
+ newlinesInside?: 'always' | 'never' | number
anyOf: Array<{
selector?: string
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
}>
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
interface CustomGroupAnyOfDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | |
newlinesInside?: number | |
anyOf: Array<{ | |
selector?: string | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
}> | |
} | |
``` | |
interface CustomGroupAnyOfDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { | |
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' | |
order?: 'asc' | 'desc' | |
} | |
newlinesInside?: 'always' | 'never' | number | |
anyOf: Array<{ | |
selector?: string | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
}> | |
} |
🤖 Prompt for AI Agents
In docs/content/rules/sort-decorators.mdx around lines 368 to 379, the
CustomGroupAnyOfDefinition typings for fallbackSort and newlinesInside are
incorrect; update fallbackSort to be optional and to mirror the main sort
options (i.e. fallbackSort?: { type?: 'alphabetical' | 'natural' | 'line-length'
| 'unsorted'; order?: 'asc' | 'desc' }) and update newlinesInside to accept
either a single number or a bounds object (e.g. newlinesInside?: number | {
min?: number; max?: number }) so it matches the other definitions in this file.
rules/sort-decorators/types.ts
Outdated
customGroups: | ||
| CustomGroupsOption<SingleCustomGroup> | ||
| DeprecatedCustomGroupsOption | ||
partitionByComment: PartitionByCommentOption | ||
newlinesBetween: NewlinesBetweenOption | ||
groups: GroupsOptions<Group> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Remove DeprecatedCustomGroupsOption from public Options (docs/runtime mismatch).
Docs say the object-based customGroups API is removed in v5, but the type still allows DeprecatedCustomGroupsOption. This will compile while failing at runtime schema, confusing users.
Apply:
- customGroups:
- | CustomGroupsOption<SingleCustomGroup>
- | DeprecatedCustomGroupsOption
+ customGroups: CustomGroupsOption<SingleCustomGroup>
To find any lingering legacy usages/tests:
🏁 Script executed:
#!/bin/bash
rg -nP "customGroups:\s*\{" -g "test/**.ts" -g "docs/**"
rg -n "DeprecatedCustomGroupsOption"
Length of output: 3493
Remove DeprecatedCustomGroupsOption across all APIs, utilities, and docs
- DeprecatedCustomGroupsOption remains referenced in numerous rule‐type definitions (e.g. sort‐decorators, sort‐objects, sort‐imports, sort‐jsx‐props, sort‐heritage‐clauses, etc.), utility modules under utils/, and examples in docs/content/rules/*.
- Removing it only in rules/sort-decorators/types.ts is incomplete—every occurrence must be expunged or replaced with CustomGroupsOption, and all documentation examples updated to match the v5 API.
- Delete the type alias in types/common-options.ts and any related runtime validation logic that still expects the deprecated shape.
🤖 Prompt for AI Agents
In rules/sort-decorators/types.ts around lines 19 to 24, the type
DeprecatedCustomGroupsOption is still referenced; remove this deprecated type
and replace its usages with CustomGroupsOption across the codebase: update every
rule-type file (sort-decorators, sort-objects, sort-imports, sort-jsx-props,
sort-heritage-clauses, etc.), all utility modules under utils/, and
documentation examples in docs/content/rules/* to use CustomGroupsOption only;
delete the DeprecatedCustomGroupsOption alias from types/common-options.ts and
remove any runtime validation/guards that expect the deprecated shape, ensuring
validation, tests, and examples conform to the v5 API shape and build after
changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (10)
docs/content/rules/sort-array-includes.mdx (1)
250-252
: Document the full union for newlinesBetweenCode/types accept 'always' | 'never' | number | 'ignore', but docs list only number | 'ignore'.
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'always' | 'never' | number | 'ignore'`</sub>test/rules/sort-array-includes.test.ts (3)
1183-1199
: Fix spread element quoted as a string'...foo' must be a spread element, not a string literal. This breaks grouping by selector and expected fixes.
- [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value) @@ - [ - 'a', - '...foo', - 'cFoo', - ].includes(value) + [ + 'a', + ...foo, + 'cFoo', + ].includes(value)
2980-2997
: Fix spread element quoted as a string (natural block)Same issue as above.
- [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value) @@ - [ - 'a', - '...foo', - 'cFoo', - ].includes(value) + [ + 'a', + ...foo, + 'cFoo', + ].includes(value)
4756-4768
: Fix spread element quoted as a string (line-length block)Same issue as above.
- [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value)docs/content/rules/sort-heritage-clauses.mdx (1)
321-333
: Update example to new array-based customGroups API (object form is no longer supported).This contradicts the migration note above. Replace the map with an array of definitions.
{ groups: [ 'withIdInterface', // [!code ++] 'unknown' ], -+ customGroups: { // [!code ++] -+ -+ withIdInterface: '^WithId' // [!code ++] -+ } // [!code ++] + customGroups: [ // [!code ++] + { // [!code ++] + groupName: 'withIdInterface', + elementNamePattern: '^WithId' + } + ] // [!code ++] }docs/content/rules/sort-decorators.mdx (1)
272-276
: Document full groups union shape.Schema allows objects between groups (newlinesBetween/commentAbove). Update the type and inline example.
-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: 'always' | 'never' | number | 'ignore'; commentAbove?: string }>` +</sub>Also rename “See the groups option” anchor to match the section header or keep as-is if correct.
Also applies to: 293-311
rules/sort-object-types.ts (1)
379-399
: Use definite indices instead of .at(...) to satisfy TS and avoid undefined.range.at(0) and range.at(1) are typed as possibly undefined; this can break under strict TS configs. Use indexed access.
- let end: number = - typeElement.typeAnnotation?.range.at(0) ?? - typeElement.range.at(1)! - (typeElement.optional ? '?'.length : 0) - name = sourceCode.text.slice(typeElement.range.at(0), end) + let end: number = + typeElement.typeAnnotation?.range[0] ?? + typeElement.range[1] - (typeElement.optional ? '?'.length : 0) + name = sourceCode.text.slice(typeElement.range[0], end) @@ - let endIndex: number = - typeElement.typeAnnotation?.range.at(0) ?? typeElement.range.at(1)! + let endIndex: number = + typeElement.typeAnnotation?.range[0] ?? typeElement.range[1] @@ - name = formatName( - sourceCode.text.slice(typeElement.range.at(0), typeElement.range.at(1)), - ) + name = formatName( + sourceCode.text.slice(typeElement.range[0], typeElement.range[1]), + )docs/content/rules/sort-intersection-types.mdx (2)
231-244
: Fix mismatched quotes in selector names.Backticks slipped into the quoted selector literals; renderers will show them incorrectly.
Apply:
- - `'conditional`' — Conditional types. - - `'function`' — Function types. - - `'import`' — Imported types. - - `'intersection`' — Intersection types. - - `'keyword`' — Keyword types. - - `'literal`' — Literal types. - - `'named`' — Named types. - - `'object`' — Object types. - - `'operator`' — Operator types. - - `'tuple`' — Tuple types. - - `'union`' — Union types. - - `'nullish`' — Nullish types (`null` or `undefined`). - - `'unknown`' — Types that don’t fit into any group specified in the `groups` option. + - `'conditional'` — Conditional types. + - `'function'` — Function types. + - `'import'` — Imported types. + - `'intersection'` — Intersection types. + - `'keyword'` — Keyword types. + - `'literal'` — Literal types. + - `'named'` — Named types. + - `'object'` — Object types. + - `'operator'` — Operator types. + - `'tuple'` — Tuple types. + - `'union'` — Union types. + - `'nullish'` — Nullish types (`null` or `undefined`). + - `'unknown'` — Types that don’t fit into any group specified in the `groups` option.
490-491
: Update incorrect "Test source" link in docsdocs/content/rules/sort-intersection-types.mdx (lines 490–491): 'Rule source' link is correct; change 'Test source' from
https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-intersection-types.test.ts
to
https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-intersection-types.test.tspackage.json (1)
20-23
: Alphabet types path does not match emitted structure.Exports map
"./alphabet".types
to./dist/alphabet.d.ts
while JS points to./dist/utils/alphabet.js
. With preserveModules and current includes, the d.ts will land underdist/utils/alphabet.d.ts
, not at the root. This breaks TS resolution for consumers.Apply one of:
- Fix exports to point to
./dist/utils/alphabet.d.ts
(simplest), or- Change Vite/dts config to emit
alphabet.d.ts
at root (more complex).Patch (exports fix):
"./alphabet": { - "types": "./dist/alphabet.d.ts", + "types": "./dist/utils/alphabet.d.ts", "default": "./dist/utils/alphabet.js" },
♻️ Duplicate comments (9)
test/rules/sort-sets.test.ts (2)
1761-1763
: Same change here — looks goodMirrors the alphabetical suite updates.
Also applies to: 1769-1775, 1779-1784
3283-3285
: Same change here — looks goodConsistent group-aware assertions across suites.
Also applies to: 3291-3297, 3301-3306
docs/content/rules/sort-decorators.mdx (2)
255-263
: Fix newlinesBetween type and values.Must include 'always' and 'never' to match runtime/schema.
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'always' | 'never' | number | 'ignore'`</sub> <sub>default: `'ignore'`</sub> -Specifies how to handle newlines between groups. +Specifies how to handle newlines between groups. -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'always'` — Exactly one blank line between groups. +- `'never'` — No blank lines between groups. +- `0` — No blank lines between groups. +- Any other number — Enforce this exact number of blank lines between groups; forbid blank lines inside groups.
342-349
: Correct CustomGroupDefinition/AnyOf typings (fallbackSort, newlinesInside).Align with rule/types: fallbackSort union and newlinesInside string | number.
interface CustomGroupDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] } interface CustomGroupAnyOfDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }Also applies to: 351-361, 366-378
test/rules/sort-named-imports.test.ts (2)
1860-1866
: Same change pattern as aboveGroup-order assertions and config look consistent for the natural sort suite.
Also applies to: 1911-1912
3371-3377
: Same change pattern as aboveGroup-order assertions and config look consistent for the line-length suite.
Also applies to: 3422-3423
test/rules/sort-named-exports.test.ts (2)
1486-1492
: Same change pattern as aboveConfig and expectations look consistent for the natural sort suite.
Also applies to: 1537-1538
2856-2862
: Same change pattern as aboveConfig and expectations look consistent for the line-length suite.
Also applies to: 2907-2908
vite.config.ts (1)
10-12
: Replace import.meta.dirname with an ESM-safe __dirname (Node 20 compatibility).import.meta.dirname isn’t available in Node 20. This will break the build given engines: "^20.0.0 || >=22.0.0". Use an ESM-safe __dirname shim.
import path from 'node:path' +import { fileURLToPath } from 'node:url' + +// ESM-safe __dirname +const __dirname = path.dirname(fileURLToPath(import.meta.url)) - path.resolve(import.meta.dirname, 'index.ts'), - path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'), + path.resolve(__dirname, 'index.ts'), + path.resolve(__dirname, 'utils', 'alphabet.ts'), @@ - include: [ - path.join(import.meta.dirname, 'index.ts'), - path.join(import.meta.dirname, 'types'), - path.join(import.meta.dirname, 'rules'), - path.join(import.meta.dirname, 'utils'), - ], + include: [ + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'types'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'), + ],Also applies to: 29-32
🧹 Nitpick comments (33)
test/rules/sort-sets.test.ts (5)
978-984
: Use an actual spread element instead of the string '...foo'This test is meant to demonstrate
anyOf
withselector: 'spread'
, but it currently uses a string literal. Update both code and output to exercise a real spread.- new Set([ - '...foo', - 'cFoo', - 'a', - ]) + new Set([ + ...foo, + 'cFoo', + 'a', + ]) @@ - new Set([ - 'a', - '...foo', - 'cFoo', - ]) + new Set([ + 'a', + ...foo, + 'cFoo', + ])Also applies to: 985-991
2500-2506
: Same spread-vs-string issue in “natural” anyOf testSwitch to real spread usage to cover the
spread
selector.- new Set([ - '...foo', - 'cFoo', - 'a', - ]) + new Set([ + ...foo, + 'cFoo', + 'a', + ]) @@ - new Set([ - 'a', - '...foo', - 'cFoo', - ]) + new Set([ + 'a', + ...foo, + 'cFoo', + ])Also applies to: 2507-2513
4022-4028
: Same spread-vs-string issue in “line-length” anyOf testUpdate to actual spread to validate
anyOf
withselector: 'spread'
.- new Set([ - '...foo', - 'cFoo', - 'a', - ]) + new Set([ + ...foo, + 'cFoo', + 'a', + ]) @@ - new Set([ - 'a', - '...foo', - 'cFoo', - ]) + new Set([ + 'a', + ...foo, + 'cFoo', + ])Also applies to: 4029-4035
1052-1052
: Regex precedence bug: anchor each alternative
'^r|g|b$'
means “starts with r” OR “contains g” OR “ends with b”. You likely want exact match for r/g/b.- allNamesMatchPattern: '^r|g|b$', + allNamesMatchPattern: '^(r|g|b)$',Also applies to: 2574-2574, 4096-4096
4597-4603
: Inconsistent Set construction in “custom” suite
new Set('a', 'b', ...)
constructs from only the first iterable argument; others are ignored. Use an array literal for clarity and consistency with the rule’s target shape.- new Set( - 'a', - 'b', - 'c', - 'd', - ) + new Set([ + 'a', + 'b', + 'c', + 'd', + ])rules/sort-exports.ts (1)
151-163
: Minor: hoistgetOptionsByGroupIndex
to avoid recreating per call.
reportAllErrors
callssortNodesExcludingEslintDisabled
twice; hoisting saves a closure allocation and makes intent clearer.'Program:exit': () => { - function sortNodesExcludingEslintDisabled( + const getOptionsByGroupIndex = + buildGetCustomGroupOverriddenOptionsFunction(options) + + function sortNodesExcludingEslintDisabled( ignoreEslintDisabledNodes: boolean, ): SortExportsSortingNode[] { - return formattedMembers.flatMap(groupedNodes => + return formattedMembers.flatMap(groupedNodes => sortNodesByGroups({ - getOptionsByGroupIndex: - buildGetCustomGroupOverriddenOptionsFunction(options), + getOptionsByGroupIndex, ignoreEslintDisabledNodes, groups: options.groups, nodes: groupedNodes, }), ) }rules/sort-heritage-clauses/types.ts (1)
33-35
: Prefer const for schema mapThis object isn’t reassigned; use const to prevent accidental mutation.
-export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { elementNamePattern: regexJsonSchema, }docs/content/rules/sort-array-includes.mdx (2)
491-492
: Fix “Test source” link pathTests live under test/rules now.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-array-includes.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-array-includes.test.ts)
4-4
: Grammar tweak in shortDescription“includes” (method name) reads better than “include”.
-shortDescription: Enforce sorted arrays before include method +shortDescription: Enforce sorted arrays before includes methodrules/sort-heritage-clauses.ts (3)
46-59
: Defaults align with new options; minor nitSetting newlinesBetween: 'ignore' by default is consistent. Consider adding a comment that per-group overrides are only honored when partitionByNewLine is false (mirrors validator).
138-180
: Set partitionId per partition (currently always 0)partitionId is useful for diagnostics/telemetry; populate it with the current partition index.
- let formattedMembers: SortingNode[][] = [[]] + let formattedMembers: SortingNode[][] = [[]] for (let heritageClause of heritageClauses) { @@ - let sortingNode: SortingNode = { + let sortingNode: SortingNode = { isEslintDisabled: isNodeEslintDisabled( heritageClause, eslintDisabledLines, ), size: rangeToDiff(heritageClause, sourceCode), node: heritageClause, - partitionId: 0, + partitionId: 0, group, name, } @@ - if ( + if ( shouldPartition({ lastSortingNode, sortingNode, sourceCode, options, }) ) { formattedMembers.push([]) } - - formattedMembers.at(-1)!.push(sortingNode) + let currentPartitionIndex = formattedMembers.length - 1 + sortingNode.partitionId = currentPartitionIndex + formattedMembers.at(-1)!.push(sortingNode)
197-211
: Confirm newlinesBetween value resolver is wiredreportAllErrors can emit missed/extra spacing only if it knows the effective newlinesBetween between group pairs. If not already handled inside reportAllErrors, pass a resolver that respects inline group overrides.
Would you like me to propose a small helper to compute the per-pair newlinesBetween from options.groups and options.newlinesBetween?
docs/content/rules/sort-heritage-clauses.mdx (2)
166-182
: Clarify numeric domain for newlinesBetween.Say “non-negative integer” to avoid ambiguity about negatives and decimals.
- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. + - Any non-negative integer — Enforce this number of newlines between each group, and forbid newlines inside groups.
227-254
: Call out breaking change and cross-check examples below.
- Explicitly mark this as a v5.0.0 breaking change.
- Ensure all examples later in the page use the new array form (there’s at least one object-shaped example below).
<Important title="Migrating from the old API"> -Support for the object-based `customGroups` option has been removed. +Support for the object-based `customGroups` option has been removed (breaking change in v5.0.0). @@ -Migrating from the old to the current API is easy: +Migrating from the old to the current API is easy. Ensure all examples below use the new array form:rules/sort-decorators.ts (2)
209-257
: Partitioning logic: partitionId assignment is 1-based; OK but add a brief comment.rangeToDiff + shouldPartition pipeline is sound. A small inline comment clarifies intent for future readers.
- accumulator.at(-1)!.push({ + // Partition ids are 1-based to simplify downstream grouping logic + accumulator.at(-1)!.push({ ...sortingNode, partitionId: accumulator.length, })
145-160
: Parameter-decorator entrypoint: consider a safer type guard.The 'in' check on decorator.parent and Identifier → FunctionExpression chain is fine at runtime but brittle for typings. Prefer a reusable isDecoratedParameter helper to narrow safely.
- Decorator: decorator => { - if (!options.sortOnParameters) return - if ( - 'decorators' in decorator.parent && - decorator.parent.type === 'Identifier' && - decorator.parent.parent.type === 'FunctionExpression' - ) { + Decorator: decorator => { + if (!options.sortOnParameters) return + if (isDecoratedParameter(decorator)) { let { decorators } = decorator.parent if (decorator !== decorators[0]) return sortDecorators(context, options, decorators) } },Type guard (add in this file or a utils/types module):
function isDecoratedParameter( d: TSESTree.Decorator, ): d is TSESTree.Decorator & { parent: TSESTree.Identifier & { decorators: TSESTree.Decorator[]; parent: TSESTree.FunctionExpression } } { let p = d.parent as any return !!p && Array.isArray(p.decorators) && p.type === 'Identifier' && p.parent?.type === 'FunctionExpression' }test/rules/sort-decorators.test.ts (2)
539-546
: Tests intentionally cover deprecated object-form customGroups; align with final decision.If v5 removes object-form, replace these occurrences with array-form to match docs. If kept as deprecated, keep these tests but mark them as compatibility and update docs accordingly.
Also applies to: 606-615, 970-983, 1890-1894, 2067-2071, 2673-2674, 3500-3506, 3634-3640, 4240-4241, 5201-5207, 6249-6255, 6829-6831
1-17
: Duplicate errors helper is clean; consider stronger typing to silence no-unsafe-call in tests.Static analysis flags “no-unsafe-call” at many template-tag lines (dedent). Add an ESLint override for tests or ensure dedent types resolve.
Suggested repo-level ESLint override:
// .eslintrc.cjs (or flat config override) { "overrides": [ { "files": ["**/*.test.ts"], - "rules": {} + "rules": { + "@typescript-eslint/no-unsafe-call": "off" + } } ] }Also applies to: 6989-6997
docs/content/rules/sort-decorators.mdx (4)
247-252
: Clarify partitionByNewLine behavior.It partitions by blank lines and sorts within partitions; current phrasing suggests “do not sort”.
-When `true`, the rule will not sort the decorators if there is an empty line between them. +When `true`, blank lines create partitions; sorting is applied within each partition only (no reordering across partitions).
314-341
: Migration box: soften “removed” wording if runtime still accepts object form.If schema keeps deprecated object, change “Support … has been removed” to “deprecated; still accepted in v5, removal in v6”. Otherwise keep “removed”.
415-427
: Example diff markers are great; minor formatting nit.Ensure code fence language hint matches JS/TS (currently fine) and remove trailing spaces (if any).
518-520
: Fix “Test source” link path.The file lives at test/rules/sort-decorators.test.ts.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-decorators.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-decorators.test.ts)rules/sort-object-types.ts (2)
260-267
: Method “value” is always null; confirm desired behavior for sortBy: "value".Only TSPropertySignature populates value. In groups configured with sortBy: "value", methods and index signatures will be treated as ignored for that group and retain original order. If you intended fallback sorting for those nodes, drop the group-level ignore and rely on fallbackSort.
Possible change (inside isNodeIgnoredForGroup):
- if (groupOptions.sortBy === 'value') { - return !node.value - } - return false + return false
310-313
: Partition ID off-by-one semantics—confirm consumer expectations.partitionId uses formattedMembers.length (1-based). If downstream assumes 0-based group ids, this will misalign. If 1-based is intentional, consider a short comment to codify the contract.
test/rules/sort-named-imports.test.ts (1)
342-348
: LGTM: migrated to explicit groups for type importsThe assertions and config now correctly target the 'type-import' group and expect the new group-order message. Consider adding one extra case that explicitly asserts ordering between 'type-import' and 'value-import' to cover both predefined groups.
Also applies to: 393-394
test/rules/sort-named-exports.test.ts (1)
116-122
: LGTM: explicit 'type-export' grouping and message idTests align with the new groups API and the group-order message. Consider mirroring one case that asserts relative order vs value exports to exercise both predefined groups.
Also applies to: 167-168
docs/content/rules/sort-intersection-types.mdx (6)
11-14
: Deduplicate keywords."typescript linting" appears twice; keep one.
- typescript types - - typescript linting - typescript-eslint
156-156
: Grammar: lowercase “to”.-Refer To +Refer to
87-87
: Wording: “groups” and “newline behavior”.-- 'unsorted' — Do not sort items. [`grouping`](#groups) and [`newlines behavior`](#newlinesbetween) are still enforced. +- 'unsorted' — Do not sort items. [`groups`](#groups) and [`newline behavior`](#newlinesbetween) are still enforced.
359-359
: Clarify target: not “object type members”.Here we’re grouping intersection constituents, not object members.
-Defines custom groups to match specific object type members. +Defines custom groups to match intersection type constituents.
375-375
: Grammar and clarity: “A type constituent…”.-An type member will match a `CustomGroupDefinition` group if it matches all the filters of the custom group's definition. +A type constituent will match a `CustomGroupDefinition` group if it matches all the filters of the custom group's definition.
393-393
: Grammar and clarity: “A type constituent…”.-An type member will match a `CustomGroupAnyOfDefinition` group if it matches all the filters of at least one of the `anyOf` items. +A type constituent will match a `CustomGroupAnyOfDefinition` group if it matches all the filters of at least one of the `anyOf` items.vite.config.ts (1)
27-37
: Fix ESLint no-unsafe-call on dts() by ensuring types are resolved.Lint hints show typescript/no-unsafe-call at Line 27. If TS fails to resolve types for vite-plugin-dts in your setup, explicitly type the plugin or locally suppress the rule for this line.
Option A (typed variable):
- plugins: [ - dts({ + plugins: [ + (dts({ include: [ /* ... */ ], insertTypesEntry: true, copyDtsFiles: true, strictOutput: true, - }), + }) as import('vite').PluginOption),Option B (surgical disable):
- dts({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + dts({
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (36)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(4 hunks)docs/content/rules/sort-interfaces.mdx
(0 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(0 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)package.json
(5 hunks)rules/sort-array-includes.ts
(3 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-decorators.ts
(5 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(5 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-interfaces.ts
(0 hunks)rules/sort-named-exports.ts
(1 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(1 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(1 hunks)rules/sort-object-types/types.ts
(0 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(1 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(1 hunks)test/rules/sort-interfaces.test.ts
(0 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(0 hunks)test/rules/sort-sets.test.ts
(3 hunks)vite.config.ts
(1 hunks)
💤 Files with no reviewable changes (12)
- docs/content/rules/sort-exports.mdx
- rules/sort-interfaces.ts
- rules/sort-object-types/types.ts
- docs/content/rules/sort-named-exports.mdx
- rules/sort-exports/types.ts
- test/rules/sort-object-types.test.ts
- docs/content/rules/sort-interfaces.mdx
- docs/content/rules/sort-object-types.mdx
- test/rules/sort-interfaces.test.ts
- rules/sort-array-includes/types.ts
- test/rules/sort-exports.test.ts
- docs/content/rules/sort-named-imports.mdx
🚧 Files skipped from review as they are similar to previous changes (4)
- rules/sort-named-exports/types.ts
- rules/sort-decorators/types.ts
- docs/content/rules/sort-sets.mdx
- rules/sort-array-includes.ts
🧰 Additional context used
🧬 Code graph analysis (8)
rules/sort-heritage-clauses/types.ts (2)
types/common-options.ts (7)
CustomGroupsOption
(103-140)DeprecatedCustomGroupsOption
(473-473)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(499-499)utils/common-json-schemas.ts (1)
regexJsonSchema
(237-246)
rules/sort-named-imports.ts (4)
rules/sort-named-imports/types.ts (1)
SortNamedImportsSortingNode
(95-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-named-imports/types.ts (1)
types/sorting-node.ts (1)
SortingNode
(18-102)
rules/sort-exports.ts (4)
types/sorting-node.ts (1)
SortingNode
(18-102)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-named-exports.ts (4)
rules/sort-named-exports/types.ts (1)
SortNamedExportsSortingNode
(95-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-heritage-clauses.ts (11)
rules/sort-heritage-clauses/types.ts (1)
Options
(15-25)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(320-369)partitionByNewLineJsonSchema
(286-290)partitionByCommentJsonSchema
(259-280)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(111-163)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-object-types.ts (12)
rules/sort-object-types/types.ts (3)
SortObjectTypesSortingNode
(395-403)Selector
(145-150)Modifier
(158-158)utils/is-node-function-type.ts (1)
isNodeFunctionType
(49-60)rules/sort-object-types/is-member-optional.ts (1)
isMemberOptional
(15-23)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(111-163)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)rules/sort-object-types/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(27-74)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-decorators.ts (6)
rules/sort-decorators/types.ts (1)
Options
(17-32)utils/common-json-schemas.ts (6)
deprecatedCustomGroupsJsonSchema
(192-208)buildCustomGroupsArrayJsonSchema
(320-369)partitionByCommentJsonSchema
(259-280)partitionByNewLineJsonSchema
(286-290)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)
🪛 ESLint
test/rules/sort-heritage-clauses.test.ts
[error] 395-395: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 400-400: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 446-446: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 451-451: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 489-489: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 494-494: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 527-527: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 532-532: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 554-554: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 605-605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 616-616: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 675-675: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 685-685: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 748-748: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 761-761: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 815-815: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 823-823: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 873-873: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 879-879: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 916-916: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 944-944: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 979-979: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 987-987: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1028-1028: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1038-1038: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1080-1080: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1087-1087: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1126-1126: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1132-1132: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1161-1161: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1172-1172: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1210-1210: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1226-1226: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1253-1253: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1272-1272: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1285-1285: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1318-1318: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1355-1355: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1362-1362: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1382-1382: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1402-1402: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1416-1416: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1453-1453: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1460-1460: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1480-1480: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1492-1492: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1514-1514: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-decorators.test.ts
[error] 674-674: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 701-701: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 791-791: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 798-798: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 829-829: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 851-851: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 887-887: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 929-929: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 999-999: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1089-1089: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1099-1099: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1157-1157: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1166-1166: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1228-1228: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1240-1240: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1293-1293: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1300-1300: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1349-1349: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1354-1354: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1390-1390: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1416-1416: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1450-1450: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1457-1457: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1497-1497: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1506-1506: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1547-1547: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1553-1553: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1591-1591: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1596-1596: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1608-1608: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1655-1655: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
vite.config.ts
[error] 27-27: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
🔇 Additional comments (23)
test/rules/sort-sets.test.ts (2)
239-241
: Groups-based config in partitioned test: LGTMAdopting
groups: ['spread']
matches the new API and keeps the test intent clear.
247-253
: Group-aware error assertions: LGTMSwitch to
unexpectedSetsGroupOrder
with{ leftGroup, rightGroup }
is correct and aligns with the rule’s new messages.Also applies to: 256-262
rules/sort-exports.ts (2)
165-179
: No change required — newlinesBetweenValueGetter is optionalreportAllErrors declares newlinesBetweenValueGetter as optional (utils/report-all-errors.ts) and uses it via optional chaining (utils/get-newlines-between-errors.ts); many rules (including rules/sort-exports.ts) omit the getter and only rules/sort-classes.ts supplies a custom one. No runtime change required.
50-52
: Type alias change LGTM — no stalegroupKind
usages found.
DroppinggroupKind
from SortExportsSortingNode aligns with the new groups-based flow.rules/sort-heritage-clauses/types.ts (1)
15-25
: Options shape looks consistent with repo-wide config migrationUnioned customGroups (array and deprecated map), newlines/partition flags, and GroupsOptions wiring LGTM.
test/rules/sort-array-includes.test.ts (1)
1-1
: Verify remaining '...' string literals in testsrg found matches in test/rules/sort-sets.test.ts, test/rules/sort-array-includes.test.ts, and test/rules/sort-maps.test.ts — confirm whether the '...foo' / '...b' entries are intended string literals (expected test data) or accidental "spread-as-string" slips; if accidental, replace with actual spread elements or adjust the expected outputs.
test/rules/sort-heritage-clauses.test.ts (1)
954-996
: Great coverage for inline comments + spacing combosThese assertions exercise both missed/extra spacing and comment preservation well.
docs/content/rules/sort-heritage-clauses.mdx (4)
160-166
: LGTM: partitionByNewLine description is clear and scoped.No issues; behavior is described precisely.
206-224
: LGTM: per-boundary overrides for newlines are well-explained.Example and constraints (dependency on partitionByNewLine = false) read correctly.
358-363
: LGTM: Flat config shows the new options and empty arrays by default.Defaults match the Options section.
388-393
: LGTM: Legacy config mirrors the flat config example.Consistent keys and defaults.
rules/sort-decorators.ts (4)
118-131
: Nice: public message IDs include spacing variants.The new missed/extra spacing message IDs map cleanly to shared error templates; consistent with reportAllErrors.
50-68
: Sane defaults and ESM-friendly options shape.Default options align with newlinesBetween/partitionByNewLine validation and array-based customGroups.
132-143
: Good guardrail: validateNewlinesAndPartitionConfiguration.Early validation prevents contradictory newline config and group-level overrides.
259-271
: Per-group overrides wired correctly.buildGetCustomGroupOverriddenOptionsFunction(options) is passed as getOptionsByGroupIndex; matches utils contract.
test/rules/sort-decorators.test.ts (1)
665-752
: Great coverage for name patterns, overrides, fallback, unsorted, and newline semantics.These scenarios exercise the new API surface well and will catch regressions.
Also applies to: 754-806, 808-883, 885-995, 997-1044, 1046-1108, 1110-1177, 1179-1254, 1256-1307, 1309-1423, 1425-1465, 1467-1517, 1606-1725
rules/sort-object-types.ts (1)
298-305
: Confirm ShouldPartitionParameters.tokenValueToIgnoreBefore optionality — no action required.
The ShouldPartitionParameters interface in utils/should-partition.ts declares tokenValueToIgnoreBefore?: string, so calling shouldPartition without it is valid.Likely an incorrect or invalid review comment.
rules/sort-named-exports.ts (1)
168-195
: LGTM: unified sorting/reporting pipelineThe extracted sortNodesExcludingEslintDisabled and single reportAllErrors pass improve clarity and keep behavior aligned with other rules.
docs/content/rules/sort-intersection-types.mdx (2)
3-3
: Typo fix looks good.Front-matter description is now clean and accurate.
129-131
: Import path verified — keepimport { Alphabet } from 'eslint-plugin-perfectionist/alphabet'
.package.json exports include "./alphabet" → ./dist/utils/alphabet.js with types at ./dist/alphabet.d.ts; Alphabet is the exported symbol.
vite.config.ts (1)
8-16
: Ignore flattening concern — preserveModules already preserves subpaths.vite.config.ts sets rollupOptions.output.preserveModules = true and uses lib.fileName((_format, entryName) =>
${entryName}.js
); with preserveModules Rollup's entry name includes the relative path, so the build will emit dist/utils/alphabet.js matching package.json exports. (rollupjs.org)Drop
name
if you don't produce UMD/IIFE builds (it's only required for those formats). (v3.vitejs.dev)Likely an incorrect or invalid review comment.
package.json (2)
3-3
: Version still 4.15.0 while PR targets v5.0.0.Release scripts tag from package.json. Ensure the version is bumped before running
release:*
or CI will tag and publish 4.x.If you bump here:
- "version": "4.15.0", + "version": "5.0.0",Alternatively, adjust your release tooling to write the new version prior to tagging.
126-127
: If ESLint v8 support will be removed in v5.0.0, update the peer range to v9+.Current state: ./package.json (v4.15.0) has "peerDependencies.eslint": ">=8.45.0"; devDependencies use "eslint": "^9.33.0"; docs/public/llms.txt still says "Compatible with ESLint v8.45.0 or greater"; repository has many "Will be removed in v5.0.0" deprecations but no explicit statement that ESLint v8 will be dropped — confirm the intended policy.
- "peerDependencies": { - "eslint": ">=8.45.0" - }, + "peerDependencies": { + "eslint": ">=9.0.0" + },If v8 support is kept temporarily, document that decision in the changelog and update docs/public/llms.txt to avoid surprises.
### partitionByComment | ||
|
||
<sub>default: `false`</sub> | ||
|
||
Enables the use of comments to separate class decorators into logical groups. | ||
|
||
- `true` — All comments will be treated as delimiters, creating partitions. | ||
- `false` — Comments will not be used as delimiters. | ||
- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. | ||
- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. | ||
- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix terminology and align RegExpPattern shape with types below.
- “class decorators” is incorrect for this rule; use “heritage clauses”.
- In RegExpPattern examples,
flags
should be optional to match the interfaces later (flags?: string
).
### partitionByComment
<sub>default: `false`</sub>
-Enables the use of comments to separate class decorators into logical groups.
+Enables the use of comments to separate heritage clauses into logical groups.
- `true` — All comments will be treated as delimiters, creating partitions.
- `false` — Comments will not be used as delimiters.
-- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters.
+- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters.
-- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters.
+- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters.
-- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters.
+- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
### partitionByComment | |
<sub>default: `false`</sub> | |
Enables the use of comments to separate class decorators into logical groups. | |
- `true` — All comments will be treated as delimiters, creating partitions. | |
- `false` — Comments will not be used as delimiters. | |
- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. | |
- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. | |
- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters. | |
### partitionByComment | |
<sub>default: `false`</sub> | |
Enables the use of comments to separate heritage clauses into logical groups. | |
- `true` — All comments will be treated as delimiters, creating partitions. | |
- `false` — Comments will not be used as delimiters. | |
- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters. | |
- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. | |
- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters. |
🤖 Prompt for AI Agents
In docs/content/rules/sort-heritage-clauses.mdx around lines 148 to 159, replace
the incorrect phrase “class decorators” with “heritage clauses” and update the
RegExpPattern shape descriptions to match the interfaces used later by making
flags optional (use flags?: string wording); ensure each listed RegExpPattern
example reflects the optional flags (both single and array variants) and keep
the same overall option descriptions and examples.
/** Extended sorting node for named import specifiers. */ | ||
export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Bug: wrong AST node type for SortNamedImportsSortingNode
Sorting nodes in the rule hold ImportSpecifier, not ImportClause. This causes an incorrect public type and potential type errors.
Apply this fix:
-/** Extended sorting node for named import specifiers. */
-export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause>
+/** Extended sorting node for named import specifiers. */
+export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportSpecifier>
Run to confirm no remaining references to ImportClause in this context and that the type matches usage:
🏁 Script executed:
#!/bin/bash
rg -nP --type=ts -C2 '\bSortNamedImportsSortingNode\b'
rg -nP --type=ts -C2 'node:\s*specifier' rules/sort-named-imports.ts
rg -nP --type=ts -C2 'ImportClause' rules/sort-named-imports
Length of output: 2013
Fix SortNamedImportsSortingNode: use TSESTree.ImportSpecifier
Sorting nodes are built from ImportSpecifier (the code passes specifier
as node
), so the exported type must be SortingNode<TSESTree.ImportSpecifier>.
-/** Extended sorting node for named import specifiers. */
-export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause>
+/** Extended sorting node for named import specifiers. */
+export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportSpecifier>
Location: rules/sort-named-imports/types.ts:95
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
/** Extended sorting node for named import specifiers. */ | |
export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause> | |
/** Extended sorting node for named import specifiers. */ | |
export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportSpecifier> |
🤖 Prompt for AI Agents
In rules/sort-named-imports/types.ts around lines 94 to 96, the exported type
SortNamedImportsSortingNode is incorrectly using TSESTree.ImportClause but the
sorting nodes are constructed from ImportSpecifier; update the type to
SortingNode<TSESTree.ImportSpecifier> so the exported type matches the actual
node kind passed in the code and any downstream usage.
let nodes = formattedMembers.flat() | ||
reportAllErrors<MessageIds>({ | ||
sortNodesExcludingEslintDisabled, | ||
availableMessageIds, | ||
sourceCode, | ||
options, | ||
context, | ||
nodes, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass newlinesBetweenValueGetter to enable spacing diagnostics.
Without newlinesBetweenValueGetter, reportAllErrors can't compute missed/extra blank-line errors when options.newlinesBetween is set.
Apply this diff:
reportAllErrors<MessageIds>({
sortNodesExcludingEslintDisabled,
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
availableMessageIds,
sourceCode,
options,
context,
nodes,
})
Add the missing import at the top of the file:
import { getLinesBetween } from '../utils/get-lines-between'
🤖 Prompt for AI Agents
In rules/sort-object-types.ts around lines 349 to 357, reportAllErrors is called
without the newlinesBetweenValueGetter so it cannot compute missed/extra
blank-line errors; add the missing import "import { getLinesBetween } from
'../utils/get-lines-between'" at the top of the file and pass
newlinesBetweenValueGetter: getLinesBetween (or equivalent getter) into the
reportAllErrors call alongside the existing arguments so the function can detect
spacing diagnostics when options.newlinesBetween is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (9)
docs/content/rules/sort-sets.mdx (1)
450-452
: Broken link to testsTests live under test/rules/sort-sets.test.ts now.
Update:
- - [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-sets.test.ts) + - [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-sets.test.ts)rules/sort-object-types.ts (3)
67-83
: Default still uses deprecated customGroups shape. Switch to array.For v5, defaultOptions.customGroups should be [] (array), not {} (object).
Apply:
- customGroups: {}, + customGroups: [],
16-16
: Schema still allows deprecated customGroups object. Remove it for v5.Drop deprecatedCustomGroupsJsonSchema from oneOf to enforce the new API.
Apply:
-import { - buildUseConfigurationIfJsonSchema, - buildCustomGroupsArrayJsonSchema, - deprecatedCustomGroupsJsonSchema, +import { + buildUseConfigurationIfJsonSchema, + buildCustomGroupsArrayJsonSchema, partitionByCommentJsonSchema, partitionByNewLineJsonSchema, newlinesBetweenJsonSchema, buildCommonJsonSchemas, groupsJsonSchema, regexJsonSchema, } from '../utils/common-json-schemas'- customGroups: { - oneOf: [ - deprecatedCustomGroupsJsonSchema, - buildCustomGroupsArrayJsonSchema({ - additionalFallbackSortProperties: { sortBy: sortByJsonSchema }, - singleCustomGroupJsonSchema, - }), - ], - }, + customGroups: buildCustomGroupsArrayJsonSchema({ + additionalFallbackSortProperties: { sortBy: sortByJsonSchema }, + singleCustomGroupJsonSchema, + }),Also applies to: 93-101
85-119
: Repo-wide cleanup required: deprecated customGroups types/schemas still referencedMultiple files still reference DeprecatedCustomGroupsOption and deprecatedCustomGroupsJsonSchema — replace usages with CustomGroupsOption and the updated JSON schema, and update tests/docs.
- Definitions to update: types/common-options.ts (DeprecatedCustomGroupsOption ~line 461), utils/common-json-schemas.ts (deprecatedCustomGroupsJsonSchema ~line 192).
- Key consumers (non‑exhaustive): utils/* (validate-generated-groups-configuration.ts, make-newlines-between-fixes.ts, make-comment-above-fixes.ts, make-fixes.ts, get-newlines-between-option.ts, get-newlines-between-errors.ts, get-custom-groups-compare-options.ts, get-comment-above-that-should-exist.ts, compute-group.ts).
- Rule files to sweep: rules/sort-object-types.ts, rules/sort-objects.ts, rules/sort-imports.ts, rules/sort-jsx-props.ts, rules/sort-decorators.ts, rules/sort-heritage-clauses.ts, rules/sort-enums.ts, rules/sort-interfaces.ts.
- Tests/docs: many test files under test/ and docs/content/ reference customGroups — update examples and assertions.
Action: perform a repo-wide replace of the deprecated type/schema, update calling sites, and adjust tests/docs; run the test suite to verify no regressions.
package.json (1)
125-127
: Align peer range with stated drop of ESLint v8PR objective says “Drop legacy ESLint v8 support,” but peerDependencies still allow v8. Bump to v9+.
- "peerDependencies": { - "eslint": ">=8.45.0" - }, + "peerDependencies": { + "eslint": ">=9.0.0" + },docs/content/rules/sort-heritage-clauses.mdx (2)
185-189
: Update groups type to reflect inline newlinesBetween objectsDocs currently state
Array<string | string[]>
but you also support spacing objects between groups.-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: 'ignore' | 'always' | 'never' | number }>` +</sub>
321-333
: Migrate the example to the new array-based customGroupsThis section still shows the removed object API.
{ groups: [ 'withIdInterface', // [!code ++] 'unknown' ], - customGroups: { // [!code ++] - withIdInterface: '^WithId' // [!code ++] - } // [!code ++] + customGroups: [ // [!code ++] + { groupName: 'withIdInterface', elementNamePattern: '^WithId' } // [!code ++] + ] // [!code ++] }docs/content/rules/sort-decorators.mdx (1)
272-275
: Correct groups option type to include separator/metadata objects.Schema allows objects with newlinesBetween/commentAbove; docs currently don’t.
<sub> - type: `Array<string | string[]>` + type: `Array<string | string[] | { newlinesBetween?: 'always' | 'never' | number; commentAbove?: string | { pattern: string; flags?: string } | Array<string | { pattern: string; flags?: string }>} >` </sub>rules/sort-decorators.ts (1)
259-288
: Honor partition boundaries when reporting; avoid cross-partition false positives.Currently, nodes are flattened and reported once, so edges across partitions may incorrectly trigger order/spacing errors. Mirror the per-partition flow used in sort-heritage-clauses.
- function sortNodesExcludingEslintDisabled( - ignoreEslintDisabledNodes: boolean, - ): SortDecoratorsSortingNode[] { - return formattedMembers.flatMap(nodes => - sortNodesByGroups({ - getOptionsByGroupIndex: - buildGetCustomGroupOverriddenOptionsFunction(options), - ignoreEslintDisabledNodes, - groups: options.groups, - nodes, - }), - ) - } - let nodes = formattedMembers.flat() - - reportAllErrors<MessageId>({ - availableMessageIds: { - missedSpacingBetweenMembers: 'missedSpacingBetweenDecorators', - extraSpacingBetweenMembers: 'extraSpacingBetweenDecorators', - unexpectedGroupOrder: 'unexpectedDecoratorsGroupOrder', - unexpectedOrder: 'unexpectedDecoratorsOrder', - }, - ignoreFirstNodeHighestBlockComment: true, - sortNodesExcludingEslintDisabled, - sourceCode, - options, - context, - nodes, - }) + for (let nodes of formattedMembers) { + function createSortNodesExcludingEslintDisabled( + sortingNodes: SortDecoratorsSortingNode[], + ) { + return function (ignoreEslintDisabledNodes: boolean) { + return sortNodesByGroups({ + getOptionsByGroupIndex: + buildGetCustomGroupOverriddenOptionsFunction(options), + ignoreEslintDisabledNodes, + groups: options.groups, + nodes: sortingNodes, + }) + } + } + + reportAllErrors<MessageId>({ + availableMessageIds: { + missedSpacingBetweenMembers: 'missedSpacingBetweenDecorators', + extraSpacingBetweenMembers: 'extraSpacingBetweenDecorators', + unexpectedGroupOrder: 'unexpectedDecoratorsGroupOrder', + unexpectedOrder: 'unexpectedDecoratorsOrder', + }, + ignoreFirstNodeHighestBlockComment: true, + sortNodesExcludingEslintDisabled: + createSortNodesExcludingEslintDisabled(nodes), + sourceCode, + options, + context, + nodes, + }) + }
♻️ Duplicate comments (5)
vite.config.ts (1)
10-12
: import.meta.dirname breaks on Node 20 — use ESM-safe __dirnameNode 20 doesn’t support import.meta.dirname. Replace with an ESM-safe __dirname shim.
Apply:
import dts from 'vite-plugin-dts' import path from 'node:path' +import { fileURLToPath } from 'node:url' + +// ESM-safe __dirname for Node 20+ +const __dirname = path.dirname(fileURLToPath(import.meta.url)) entry: [ - path.resolve(import.meta.dirname, 'index.ts'), - path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'), + path.resolve(__dirname, 'index.ts'), + path.resolve(__dirname, 'utils', 'alphabet.ts'), ], include: [ - path.join(import.meta.dirname, 'index.ts'), - path.join(import.meta.dirname, 'types'), - path.join(import.meta.dirname, 'rules'), - path.join(import.meta.dirname, 'utils'), + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'types'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'), ],Also applies to: 29-33
rules/sort-decorators/types.ts (1)
19-24
: Remove DeprecatedCustomGroupsOption from public Options (v5).Keep only CustomGroupsOption to match docs/runtime.
Apply:
- customGroups: - | CustomGroupsOption<SingleCustomGroup> - | DeprecatedCustomGroupsOption + customGroups: CustomGroupsOption<SingleCustomGroup>docs/content/rules/sort-decorators.mdx (3)
255-263
: Fix newlinesBetween type and values to match schema.Docs omit 'always' and 'never'. Update type and bullets.
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'always' | 'never' | number | 'ignore'`</sub> <sub>default: `'ignore'`</sub> Specifies how to handle newlines between groups. -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'always'` — Exactly one blank line between groups. +- `'never'` — No blank lines between groups. +- `0` — No blank lines between groups. +- Any other number — Enforce this exact number of blank lines between groups; forbid blank lines inside groups.
352-359
: Align CustomGroupDefinition typings (fallbackSort, newlinesInside).Match runtime/types: broaden fallbackSort; allow 'always' | 'never' | number for newlinesInside.
interface CustomGroupDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
367-378
: Align CustomGroupAnyOfDefinition typings (fallbackSort, newlinesInside).Same corrections as above.
interface CustomGroupAnyOfDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }
🧹 Nitpick comments (11)
docs/content/rules/sort-sets.mdx (1)
290-292
: Terminology: say “Set elements”, not “Array elements”This rule documents Sets; calling them “Array elements” here is confusing.
Apply:
- - `literal` — Array elements that are not spread values. - - `spread` — Array elements that are spread values. + - `literal` — Set elements that are not spread values. + - `spread` — Set elements that are spread values.test/rules/sort-sets.test.ts (1)
965-993
: anyOf test isn’t exercising a SpreadElementCode uses the string '...foo' instead of a spread (...foo), so the spread selector path isn’t covered.
Consider:
- In code/output blocks, replace '...foo' with ...foo (no quotes) to cover both literal and spread cases.
test/rules/sort-array-includes.test.ts (1)
1148-1169
: anyOf test doesn’t cover a real spread'...foo' is a string literal; the spread branch isn’t validated.
Change '...foo' → ...foo (no quotes) in code/output to exercise the spread selector path too.
vite.config.ts (1)
19-21
: Remove exports: 'auto' for ES-only buildRollup’s output.exports is for CJS; with formats: ['es'] it’s redundant.
output: { preserveModules: true, - exports: 'auto', },
package.json (2)
15-25
: Add explicit "import" condition to exportsESM-only packages typically expose "import". Keeping "default" as a fallback is fine.
"exports": { ".": { "types": "./dist/index.d.ts", - "default": "./dist/index.js" + "import": "./dist/index.js", + "default": "./dist/index.js" }, "./alphabet": { "types": "./dist/alphabet.d.ts", - "default": "./dist/utils/alphabet.js" + "import": "./dist/utils/alphabet.js", + "default": "./dist/utils/alphabet.js" }, "./package.json": "./package.json" },
13-15
: Consider declaring sideEffects: falseIf the plugin has no top-level side effects (typical for ESLint plugins), mark it for better tree-shaking.
"license": "MIT", "author": "Azat S. <[email protected]>", + "sideEffects": false, "type": "module",rules/sort-heritage-clauses/types.ts (1)
31-35
: Nit: avoid reserved-word confusion with 'unknown'Using 'unknown' as a string literal is fine, but consider a more explicit literal like 'unknown-group' to avoid confusion with TS's unknown type in tooling.
docs/content/rules/sort-heritage-clauses.mdx (2)
413-415
: Fix test link pathTests live under test/rules now.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-heritage-clauses.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-heritage-clauses.test.ts)
38-46
: Consider correcting the line-length “Try it out” exampleDocs say shorter lines first, but the example shows longer-first ordering. Either set order: 'desc' in the snippet or flip the items.
docs/content/rules/sort-decorators.mdx (2)
251-252
: Clarify partitionByNewLine behavior.Make it explicit that sorting still occurs within partitions.
-When `true`, the rule will not sort the decorators if there is an empty line between them. +When `true`, any blank line acts as a partition boundary; sorting is applied within each partition only (not across partitions).
264-266
: Grammar: “option” (singular).-You can also enforce the newline behavior between two specific groups through the `groups` options. +You can also enforce the newline behavior between two specific groups through the `groups` option.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (36)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(4 hunks)docs/content/rules/sort-interfaces.mdx
(0 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(0 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)package.json
(5 hunks)rules/sort-array-includes.ts
(3 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-decorators.ts
(5 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(5 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-interfaces.ts
(0 hunks)rules/sort-named-exports.ts
(1 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(1 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(1 hunks)rules/sort-object-types/types.ts
(0 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(1 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(1 hunks)test/rules/sort-interfaces.test.ts
(0 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(0 hunks)test/rules/sort-sets.test.ts
(3 hunks)vite.config.ts
(1 hunks)
💤 Files with no reviewable changes (12)
- docs/content/rules/sort-named-imports.mdx
- docs/content/rules/sort-exports.mdx
- docs/content/rules/sort-named-exports.mdx
- test/rules/sort-object-types.test.ts
- rules/sort-object-types/types.ts
- rules/sort-interfaces.ts
- rules/sort-array-includes/types.ts
- test/rules/sort-exports.test.ts
- docs/content/rules/sort-interfaces.mdx
- rules/sort-exports/types.ts
- docs/content/rules/sort-object-types.mdx
- test/rules/sort-interfaces.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/content/rules/sort-intersection-types.mdx
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/content/rules/sort-array-includes.mdx
- rules/sort-named-imports.ts
- test/rules/sort-named-imports.test.ts
- rules/sort-named-exports/types.ts
- rules/sort-named-imports/types.ts
- rules/sort-named-exports.ts
🧰 Additional context used
🧬 Code graph analysis (7)
rules/sort-heritage-clauses/types.ts (2)
types/common-options.ts (7)
CustomGroupsOption
(103-140)DeprecatedCustomGroupsOption
(473-473)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(499-499)utils/common-json-schemas.ts (1)
regexJsonSchema
(237-246)
rules/sort-decorators/types.ts (3)
types/common-options.ts (7)
CustomGroupsOption
(103-140)DeprecatedCustomGroupsOption
(473-473)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(499-499)types/sorting-node.ts (1)
SortingNode
(18-102)utils/common-json-schemas.ts (1)
regexJsonSchema
(237-246)
rules/sort-object-types.ts (13)
rules/sort-object-types/types.ts (3)
SortObjectTypesSortingNode
(395-403)Selector
(145-150)Modifier
(158-158)utils/is-node-function-type.ts (1)
isNodeFunctionType
(49-60)rules/sort-object-types/is-member-optional.ts (1)
isMemberOptional
(15-23)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(111-163)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)rules/sort-object-types/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(27-74)utils/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(93-124)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-array-includes.ts (5)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (2)
Options
(24-68)Selector
(100-100)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-decorators.ts (7)
rules/sort-decorators/types.ts (1)
Options
(17-32)utils/common-json-schemas.ts (5)
deprecatedCustomGroupsJsonSchema
(192-208)buildCustomGroupsArrayJsonSchema
(320-369)partitionByNewLineJsonSchema
(286-290)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(73-96)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)
rules/sort-exports.ts (4)
types/sorting-node.ts (1)
SortingNode
(18-102)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
rules/sort-heritage-clauses.ts (10)
rules/sort-heritage-clauses/types.ts (1)
Options
(15-25)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(320-369)partitionByNewLineJsonSchema
(286-290)partitionByCommentJsonSchema
(259-280)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/compute-group.ts (1)
computeGroup
(111-163)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(143-154)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
🪛 ESLint
test/rules/sort-heritage-clauses.test.ts
[error] 395-395: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 400-400: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 446-446: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 451-451: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 489-489: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 494-494: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 527-527: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 532-532: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 554-554: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 605-605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 616-616: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 675-675: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 685-685: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 748-748: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 761-761: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 815-815: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 823-823: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 873-873: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 879-879: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 916-916: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 944-944: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 979-979: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 987-987: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1028-1028: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1038-1038: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1080-1080: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1087-1087: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1126-1126: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1132-1132: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1161-1161: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1172-1172: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1210-1210: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1226-1226: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1253-1253: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1272-1272: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1285-1285: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1318-1318: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1355-1355: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1362-1362: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1382-1382: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1402-1402: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1416-1416: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1453-1453: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1460-1460: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1480-1480: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1492-1492: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1514-1514: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-decorators.test.ts
[error] 674-674: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 701-701: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 791-791: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 798-798: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 829-829: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 851-851: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 887-887: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 929-929: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 999-999: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1089-1089: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1099-1099: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1157-1157: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1166-1166: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1228-1228: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1240-1240: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1293-1293: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1300-1300: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1349-1349: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1354-1354: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1390-1390: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1416-1416: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1450-1450: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1457-1457: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1497-1497: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1506-1506: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1547-1547: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1553-1553: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1591-1591: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1596-1596: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1608-1608: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1655-1655: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
vite.config.ts
[error] 27-27: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
🔇 Additional comments (35)
docs/content/rules/sort-sets.mdx (2)
274-274
: Default groups doc looks correctDefaulting to groups: ['literal'] matches the new API.
398-401
: Examples updated to groups API — LGTMBoth Flat and Legacy config snippets correctly use groups: ['literal'].
Also applies to: 428-431
test/rules/sort-sets.test.ts (2)
235-241
: Explicit groups in partitioned scenarios — goodUsing groups: ['spread'] with partitionByNewLine is consistent with the new API.
Also applies to: 1757-1763, 3279-3285
243-253
: Switched to group-order message IDs — goodunexpectedSetsGroupOrder with leftGroup/rightGroup fits the groups model.
Also applies to: 255-262, 1767-1775, 1777-1784, 3289-3297, 3299-3306
test/rules/sort-array-includes.test.ts (3)
263-268
: Adoption of groups in partitioned tests — LGTMgroups: ['spread'] usage is correct across partitions.
Also applies to: 313-320, 2060-2065, 2111-2116, 3836-3841, 3888-3893
271-281
: Message IDs now reflect group ordering — LGTMunexpectedArrayIncludesGroupOrder + leftGroup/rightGroup aligns with API changes.
Also applies to: 282-291, 476-486, 487-495, 4048-4059, 4060-4068
867-873
: Custom group ordering examples — LGTMgroups: ['spread', 'literal'] with group-order errors is correct.
Also applies to: 2637-2669, 4414-4446
test/rules/sort-named-exports.test.ts (3)
116-122
: Good migration to groups-based API (type exports).Using groups: ['type-export'] with the new unexpectedNamedExportsGroupOrder message is correct and keeps intent explicit.
Also applies to: 167-167
1486-1492
: Consistent group-order assertions for natural sort.The rightGroup/leftGroup data and groups option mirror the alphabetical suite—nice consistency.
Also applies to: 1537-1537
2856-2862
: Line-length suite aligns with groups model.The partition-by-comment + groups: ['type-export'] path looks sound.
Also applies to: 2907-2907
rules/sort-exports.ts (2)
50-52
: Type alias simplification is correct.Dropping groupKind from the node shape and aliasing to SortingNode<...> matches the new common model.
151-163
: Flattened partitions + centralized reporting look correct.
- Sorting per partition via sortNodesByGroups and then reportAllErrors is consistent with other rules.
- buildGetCustomGroupOverriddenOptionsFunction returning only options is fine (nodeValue getters default).
Also applies to: 165-179
rules/sort-array-includes.ts (4)
56-58
: Type alias matches shared SortingNode contract.No groupKind leakage—good.
68-69
: Sensible default: groups ['literal'].Preserves “literals before spreads” behavior without legacy groupKind.
196-198
: Selector derivation is correct.Mapping SpreadElement → 'spread', others → 'literal' cleanly feeds predefined groups.
245-257
: Sorting pipeline mirrors shared utils correctly.Partitioning → grouped sort → reportAllErrors is aligned with v5 architecture.
Also applies to: 259-267
rules/sort-object-types.ts (8)
216-223
: Skipping call/construct signatures is correct.They are not sortable “members” here, so continuing early avoids noise.
228-259
: Selector/modifier derivation looks solid.
- Adds index-signature/method/member/property in priority order.
- Tracks optional/required and multiline.
260-268
: Value extraction for sort-by-value is correct.Capturing TSPropertySignature annotation text enables 'value' sorting.
269-287
: Group computation aligns with new predefined/custom groups flow.Precompute + computeGroup usage is consistent with utilities.
288-313
: Partitioning logic is correct.shouldPartition + partitionId assignment mirrors other rules.
316-347
: Per-group overrides are correctly applied.getCustomGroupsCompareOptions supplies sortBy/fallback getters; group-level ignore on missing value is correct.
349-357
: Centralized error reporting wiring is correct.Pipeline matches shared reportAllErrors contract.
85-119
: Confirm whether ignorePattern is intended to remain in v5.PR objectives mention removing legacy options (incl. ignorePattern). If it’s to be removed, excise it here as well (schema, defaults, logic). If it stays, ensure docs reflect it.
Would you like a follow-up patch to remove ignorePattern, or should we keep it and update docs?
package.json (1)
41-43
: No action required — require('./package.json') works as used by the release scripts.
Ran: node -p "require('./package.json').version" → 4.15.0
Location: package.json (lines 41–43)rules/sort-heritage-clauses/types.ts (1)
15-25
: LGTM: Options shape matches new API (groups/newlines/partitions)Types line up with GroupsOptions, PartitionByCommentOption, and NewlinesBetweenOption.
test/rules/sort-heritage-clauses.test.ts (4)
364-407
: LGTM: elementNamePattern variants thoroughly coveredCovers string, array, regex, and mixed-array cases for grouping. Good breadth.
409-457
: LGTM: per-group sort overrides validatedValidates type/order override on a custom group vs global defaults.
562-626
: LGTM: spacing removal with newlinesBetween ('never'/0) checksGood to see both error kinds and output normalization asserted.
1052-1096
: LGTM: newlinesInside behavior coveredCovers 'always'/1 and 'never'/0 within groups.
test/rules/sort-decorators.test.ts (3)
665-753
: LGTM: decorator grouping by elementNamePattern variantsMirrors heritage-clauses coverage; consistent and comprehensive.
808-883
: LGTM: per-group sort override + fallbackSort testsEnsures tie-break via fallback and group-local type/order precedence.
1110-1177
: LGTM: newline insertion with newlinesBetween ('always'/1)Covers error messaging and output formatting well.
docs/content/rules/sort-decorators.mdx (1)
518-519
: Verify “Test source” link path.Tests appear to live under test/rules/sort-decorators.test.ts now; update if so.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-decorators.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-decorators.test.ts)rules/sort-heritage-clauses.ts (1)
182-211
: Good: partition-aware reporting avoids cross-partition errors.Per-partition sort+report mirrors shouldPartition semantics and prevents false positives.
interface CustomGroupDefinition { | ||
groupName: string | ||
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | ||
order?: 'asc' | 'desc' | ||
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | ||
newlinesInside?: number | ||
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expand CustomGroupDefinition types (add 'custom'; correct newlinesInside union)
Matches the code and tests where 'custom' and 'always'/'never' are valid.
interface CustomGroupDefinition {
groupName: string
- type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
+ type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
order?: 'asc' | 'desc'
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
- newlinesInside?: number
+ newlinesInside?: 'always' | 'never' | number
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
interface CustomGroupDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | |
newlinesInside?: number | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
} | |
interface CustomGroupDefinition { | |
groupName: string | |
type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' | |
order?: 'asc' | 'desc' | |
fallbackSort?: { type: string; order?: 'asc' | 'desc' } | |
newlinesInside?: 'always' | 'never' | number | |
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] | |
} |
🤖 Prompt for AI Agents
In docs/content/rules/sort-heritage-clauses.mdx around lines 265-273, the
CustomGroupDefinition TypeScript declaration is missing the 'custom' option in
the type union and newlinesInside only allows number; update the type field to
include 'custom' (i.e. 'alphabetical' | 'natural' | 'line-length' | 'unsorted' |
'custom') and change newlinesInside to accept number | 'always' | 'never' to
match tests and implementation, then save and run the test suite to verify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
test/rules/sort-enums.test.ts (1)
4903-4921
: Duplicate enum member key ('m') in fixtureIn “detects numeric enums correctly”,
'm'
appears twice, which is invalid for enums and may confuse the test intent. Use unique keys.enum Enum { 'i' = ~2, // -3 'k' = -1, 'j' = - 0.1, 'e' = - (((1 + 1) * 2) ** 2) / 4 % 2, // 0 'f' = 0, 'h' = +1, 'g' = 3 - 1, // 2 'b' = 5^6, // 3 'l' = 1 + 3, // 4 'm' = 2.1 ** 2, // 4.41 'a' = 20 >> 2, // 5 - 'm' = 7 & 6, // 6 + 'n' = 7 & 6, // 6 'c' = 5 | 6, // 7 'd' = 2 << 2, // 8 }package.json (1)
125-127
: Peer range contradicts “drop ESLint v8” objective.If v8 support is dropped, widen the peer to ESLint 9+ to prevent accidental installs on v8.
"peerDependencies": { - "eslint": ">=8.45.0" + "eslint": ">=9.0.0" },
♻️ Duplicate comments (1)
package.json (1)
60-61
: Deduplicate @typescript-eslint/types and align versions.The package appears in both dependencies (^8.43.0) and devDependencies (^6.13.0). Keep a single entry (devDependencies is typical) and align to ^8.43.0 to avoid duplicate installs and type skew.
"dependencies": { - "@typescript-eslint/types": "^8.43.0", "@typescript-eslint/utils": "^8.43.0", "natural-orderby": "^5.0.0" }, @@ "devDependencies": { @@ - "@typescript-eslint/types": "^6.13.0", + "@typescript-eslint/types": "^8.43.0",Also applies to: 84-84
🧹 Nitpick comments (3)
rules/sort-enums.ts (1)
145-149
: Keep enum member name strictly typed as stringUsing
member.id.value
directly risks astring | number
drift if a numeric literal sneaks in; downstream code (e.g.,doesCustomGroupMatch
,dependencyNames: string[]
, andSortingNodeWithDependencies.name
) is string-oriented. Coerce to string at the source to make the contract explicit.- let name = - member.id.type === 'Literal' - ? member.id.value - : sourceCode.getText(member.id) + let name: string = + member.id.type === 'Literal' + ? String(member.id.value) + : sourceCode.getText(member.id)package.json (2)
28-30
: Minor: simplify files path."files" entries don’t need the "./" prefix.
"files": [ - "./dist" + "dist" ],
41-43
: Nit: use ESM-friendly version extraction in release scripts.These commands rely on require in a Node REPL context; it works today but can be future-proofed by reading JSON via fs.
Alternative snippet:
- node -p "JSON.parse(require('fs').readFileSync('./package.json','utf8')).version"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
package.json
(4 hunks)rules/sort-enums.ts
(1 hunks)test/rules/sort-enums.test.ts
(6 hunks)
🧰 Additional context used
🪛 ESLint
test/rules/sort-enums.test.ts
[error] 97-97: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1656-1656: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3215-3215: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🔇 Additional comments (3)
test/rules/sort-enums.test.ts (1)
66-74
: LGTM: numeric-like enum keys migrated to string-literalsThe updates to quote number-like enum member names align tests with TS grammar and the rule’s name handling. Looks good.
Also applies to: 90-103, 1626-1662, 1649-1662, 3188-3192, 3209-3213
package.json (2)
3-3
: Version still 4.15.0 while releasing v5.0.0.Confirm whether version bump is handled by the release script or should be committed in this PR. If manual, bump here.
- "version": "4.15.0", + "version": "5.0.0",
20-23
: Align "./alphabet" subpath export in package.jsonexports['./alphabet'] currently maps "types" -> "./dist/alphabet.d.ts" and "default" -> "./dist/utils/alphabet.js"; dist/ is not present in the repo, so verify the intended build output and make the paths consistent.
If JS is at dist/alphabet.js:
"./alphabet": { - "types": "./dist/alphabet.d.ts", - "default": "./dist/utils/alphabet.js" + "types": "./dist/alphabet.d.ts", + "default": "./dist/alphabet.js" },If JS truly lives under dist/utils/, move the d.ts accordingly:
"./alphabet": { - "types": "./dist/alphabet.d.ts", - "default": "./dist/utils/alphabet.js" + "types": "./dist/utils/alphabet.d.ts", + "default": "./dist/utils/alphabet.js" },
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
docs/content/rules/sort-imports.mdx (2)
459-463
: Fix grammar: “between above your groups”Tighten the sentence.
-You may place `commentAbove` objects between above your groups to enforce the presence of a comment containing the -content of `commentAbove`. +You may place `commentAbove` objects above your groups to require a comment containing the value of `commentAbove`.
709-711
: Mark "Legacy Config" as deprecated (planned removal in v5.0.0)Multiple types/docs are annotated "Will be removed in v5.0.0" and the package still exposes legacy configs for ESLint v8; update all "Legacy Config" tabs (e.g., docs/content/rules/sort-imports.mdx:709–711) to indicate deprecation or remove them.
- name: 'Legacy Config', + name: 'Legacy Config (ESLint v8 — deprecated)',rules/sort-imports.ts (2)
566-581
: Possible runtime NPE:doesCustomGroupMatch
receives undefinedselectors/modifiers
for deprecated paths
computeGroupExceptUnknown
is invoked beforeselectors/modifiers
are populated (e.g., Lines 175–181), yet the matcher is called with non-null assertions. IfdoesCustomGroupMatch
assumes arrays, this can throw.let computedCustomGroup = computeGroup({ customGroupMatcher: customGroup => doesCustomGroupMatch({ - modifiers: modifiers!, - selectors: selectors!, + // Handle deprecated paths where these are intentionally unset + modifiers: modifiers ?? [], + selectors: selectors ?? [], elementName: name, customGroup, }),
126-135
: Guard access to context.physicalFilename — fallback to context.filenameSome ESLint runtimes may not expose context.physicalFilename; use a safe fallback so tsconfig discovery can't break.
- filePath: context.physicalFilename, + filePath: + // ESLint v9 exposes `physicalFilename`; fall back to `filename` if absent. + (context as any).physicalFilename ?? context.filename,Location: rules/sort-imports.ts:129-133 (single occurrence found).
🧹 Nitpick comments (9)
docs/content/rules/sort-imports.mdx (5)
326-326
: Clarify requirement wording for tsconfig-path selectorRecommend making it explicit that
tsconfig.rootDir
must be set in this rule’stsconfig
option.-- 'tsconfig-path' — `tsconfig` [paths](https://www.typescriptlang.org/tsconfig/#paths) alias imports. Requires [`tsconfig.rootDir`](#tsconfig) to be set. +- 'tsconfig-path' — `tsconfig` [paths](https://www.typescriptlang.org/tsconfig/#paths) alias imports. Requires setting [`tsconfig.rootDir`](#tsconfig) in this rule’s `tsconfig` option.
197-203
: Typo case: “Refer To” → “Refer to”-Specifies the sorting locales. Refer To [String.prototype.localeCompare() - locales](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#locales). +Specifies the sorting locales. Refer to [String.prototype.localeCompare() - locales](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#locales).
229-232
: Makeflags
optional (align with other regex-typed options) or confirm intended differenceElsewhere (
elementNamePattern
) usesflags?: string
, but hereRegExpPattern
showsflags: string
. Align or document why it differs.-- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. +- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters.
604-612
: Match lodash subpaths in exampleUse a regex that also matches
lodash/…
subpaths.{ groupName: 'lodash', - elementNamePattern: 'lodash', + elementNamePattern: '^lodash($|/)', }
38-46
: Minor wording: “Supporting for new import types”Use concise phrasing.
-1. Supporting for new import types: +1. Support for additional import types:test/rules/sort-imports.test.ts (3)
6374-6410
: Same here: nested tsconfig LGTM; add after reset for stability.The
tsconfig: { rootDir: '.' }
update aligns with the new options. Mirror anafter
reset next to the existingbefore
hook.before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },
10136-10173
: Consistent tsconfig usage; add after reset to prevent cross-test bleed.Matches the new API. Add
after: vi.resetAllMocks()
adjacent tobefore
.before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },
2554-2599
: Add after hook to reset mocks; migrate/verify leftover tsconfigRootDir usages.Add an after hook to avoid spy leakage from mockReadClosestTsConfigByPathWith.
before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },rg shows tsconfigRootDir still in rules/sort-imports.ts, read-closest-ts-config-by-path.ts and several tests — update those callers/tests to the nested tsconfig option or keep the compatibility mapping in place.
rules/sort-imports.ts (1)
72-98
: Drop of standalone tsconfigRootDir: typing LGTM; prefer const + satisfies for defaultOptionsGood switch to using only
tsconfig.rootDir
. Minor type/style tweak to prevent widening and accidental mutation:-let defaultOptions: Required<Omit<Options[0], 'maxLineLength' | 'tsconfig'>> & - Pick<Options[0], 'maxLineLength' | 'tsconfig'> = { +const defaultOptions = { groups: [ 'type-import', ['value-builtin', 'value-external'], 'type-internal', 'value-internal', ['type-parent', 'type-sibling', 'type-index'], ['value-parent', 'value-sibling', 'value-index'], 'ts-equals-import', 'unknown', ], internalPattern: ['^~/.+', '^@/.+'], fallbackSort: { type: 'unsorted' }, partitionByComment: false, partitionByNewLine: false, specialCharacters: 'keep', sortSideEffects: false, type: 'alphabetical', environment: 'node', newlinesBetween: 1, customGroups: [], ignoreCase: true, locales: 'en-US', alphabet: '', order: 'asc', -} +} satisfies Required<Omit<Options[0], 'maxLineLength' | 'tsconfig'>> & + Pick<Options[0], 'maxLineLength' | 'tsconfig'>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/content/rules/sort-imports.mdx
(1 hunks)rules/sort-imports.ts
(3 hunks)rules/sort-imports/types.ts
(0 hunks)test/rules/sort-imports.test.ts
(7 hunks)
💤 Files with no reviewable changes (1)
- rules/sort-imports/types.ts
🧰 Additional context used
🧬 Code graph analysis (1)
rules/sort-imports.ts (1)
rules/sort-imports/types.ts (1)
Options
(30-151)
🔇 Additional comments (5)
docs/content/rules/sort-imports.mdx (1)
724-726
: Links verified — no update requiredBoth files exist at rules/sort-imports.ts and test/rules/sort-imports.test.ts, so the documented "Rule source" and "Test source" links are correct.
test/rules/sort-imports.test.ts (4)
12029-12033
: LGTM: migrated to tsconfig.rootDir in misc/internal classification test.
12053-12057
: LGTM: external classification uses tsconfig.rootDir correctly.
12077-12083
: LGTM: unresolved imports default to external with tsconfig.rootDir.
12105-12113
: LGTM: fallback path (TS unavailable) with tsconfig.rootDir is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
rules/sort-object-types.ts (1)
67-83
: Remove deprecated ignorePattern for v5.0.0.Release goals state deprecated options (including ignorePattern) must be removed. It’s still present in defaultOptions, jsonSchema, and used at runtime. Replace with useConfigurationIf.declarationMatchesPattern (or instruct users to set type: 'unsorted' under a matching condition).
Apply:
@@ let defaultOptions: Required<Options[0]> = { fallbackSort: { type: 'unsorted', sortBy: 'name' }, partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', specialCharacters: 'keep', useConfigurationIf: {}, type: 'alphabetical', - ignorePattern: [], ignoreCase: true, customGroups: {}, locales: 'en-US', sortBy: 'name', alphabet: '', order: 'asc', groups: [], } @@ newlinesBetween: newlinesBetweenJsonSchema, - ignorePattern: regexJsonSchema, sortBy: sortByJsonSchema, groups: groupsJsonSchema, @@ - if (parentNodeName && matches(parentNodeName, options.ignorePattern)) { - return - } + // No ignorePattern in v5; use `useConfigurationIf` to scope behavior instead.Also applies to: 110-113, 207-209
rules/sort-object-types/types.ts (3)
164-179
: Remove vestigial 'multiline' selector mapping.AllowedModifiersPerSelector includes a 'multiline' key, but 'multiline' is no longer a Selector. Keeping it is inconsistent and confusing.
Apply:
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - /** Index signatures cannot have modifiers. */ 'index-signature': never }
222-230
: Tighten IndexSignatureGroup to exclude modifiers.Docs say index signatures can’t have modifiers, but the type currently composes modifier permutations. Make it a plain 'index-signature'.
Apply:
-type IndexSignatureGroup = JoinWithDash< - [ - OptionalModifier, - RequiredModifier, - MultilineModifier, - IndexSignatureSelector, - ] -> +type IndexSignatureGroup = IndexSignatureSelector
99-109
: Remove deprecated ignorePattern from Options for v5.0.0.The type still exposes ignorePattern with a deprecation note “Will be removed in v5.0.0.” Since this is v5, drop it from Options.
test/rules/sort-object-types.test.ts (1)
8193-8207
: Update ignore test to v5 API (replace ignorePattern).ignorePattern is removed in v5. Rewrite the test to scope an unsorted configuration via useConfigurationIf.declarationMatchesPattern.
Apply:
- await valid({ - code: dedent` - type IgnoreType = { - b: 'b' - a: 'a' - } - `, - options: [ - { - ignorePattern: ['Ignore'], - }, - ], - }) + await valid({ + code: dedent` + type IgnoreType = { + b: 'b' + a: 'a' + } + `, + options: [ + { + useConfigurationIf: { declarationMatchesPattern: 'Ignore' }, + type: 'unsorted', + }, + ], + })
♻️ Duplicate comments (1)
rules/sort-object-types.ts (1)
348-356
: Pass newlinesBetweenValueGetter to enable spacing diagnostics.Without it, reportAllErrors can’t compute missed/extra blank lines reliably when newlinesBetween is configured. This was raised before.
Apply:
@@ -import { reportAllErrors } from '../utils/report-all-errors' +import { reportAllErrors } from '../utils/report-all-errors' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })
🧹 Nitpick comments (10)
test/rules/sort-interfaces.test.ts (1)
4-4
: Address ESLint no-unsafe-call on tagged template (dedent).If CI flags
@typescript-eslint/no-unsafe-call
fordedent\
...`, add
@types/dedentor switch to a typed helper (e.g.,
common-tags’
stripIndent`) for tests.rules/sort-jsx-props/types.ts (1)
155-155
: Use const for immutable list
allSelectors
is not reassigned. Preferconst
.-export let allSelectors: Selector[] = ['prop'] +export const allSelectors: Selector[] = ['prop']test/rules/sort-jsx-props.test.ts (2)
4383-4387
: Schema validation test is a good safeguard; add a negative caseConsider asserting that invalid configs like
customGroups: [{ selector: 'shorthand' }]
are rejected to lock the contract after narrowing Selector.Example to add near this test:
await expect( validateRuleJsonSchema([ // emulate a rule schema that would allow invalid selector; should fail against current schema { properties: { customGroups: { properties: { selector: { enum: ['shorthand'] } } } } } as any, ]), ).rejects.toThrow()
4356-4368
: Nice coverage for mixing predefined and custom groupsThis ensures 'multiline-prop'/'shorthand-prop' coexist with custom names. Consider adding one case for 'shorthand-multiline-prop' if supported by
JoinWithDash
to fully exercise combinations.rules/sort-objects/types.ts (3)
151-158
: Selector union cleanup looks good; trim dead keys in AllowedModifiersPerSelectorWith 'multiline' no longer a Selector, keys 'multiline' and 'index-signature' in
AllowedModifiersPerSelector
are unused noise. Remove for clarity.interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - - /** Index signatures are not supported in regular objects. */ - 'index-signature': never }
293-293
: Use const for immutable list
allSelectors
is constant.-export let allSelectors: Selector[] = ['member', 'method', 'property'] +export const allSelectors: Selector[] = ['member', 'method', 'property']
308-313
: Make schema map constant
singleCustomGroupJsonSchema
is also immutable.-export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { modifiers: buildCustomGroupModifiersJsonSchema(allModifiers), selector: buildCustomGroupSelectorJsonSchema(allSelectors), elementValuePattern: regexJsonSchema, elementNamePattern: regexJsonSchema, }test/rules/sort-objects.test.ts (3)
1666-1685
: Confirm 'multiline-member' is an allowed built-in group.If this replaces legacy 'multiline', ensure the rule’s schema/types accept 'multiline-member' and both multiline properties and methods are matched. Optionally add a small valid/invalid pair covering a multiline method and a multiline property together to prove the selector.
4494-4513
: Verify 'multiline-member' group in natural mode.Double-check schema acceptance and that both multiline properties and methods fall under this group in natural sorting as well.
7321-7340
: Verify 'multiline-member' group in line-length mode.Same check as above to ensure parity across sort types.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
rules/sort-jsx-props.ts
(0 hunks)rules/sort-jsx-props/types.ts
(3 hunks)rules/sort-object-types.ts
(1 hunks)rules/sort-object-types/types.ts
(1 hunks)rules/sort-objects.ts
(0 hunks)rules/sort-objects/types.ts
(3 hunks)test/rules/sort-interfaces.test.ts
(24 hunks)test/rules/sort-jsx-props.test.ts
(14 hunks)test/rules/sort-object-types.test.ts
(25 hunks)test/rules/sort-objects.test.ts
(9 hunks)
💤 Files with no reviewable changes (2)
- rules/sort-objects.ts
- rules/sort-jsx-props.ts
🧰 Additional context used
🧬 Code graph analysis (5)
rules/sort-object-types/types.ts (1)
types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-object-types.ts (12)
rules/sort-object-types/types.ts (3)
SortObjectTypesSortingNode
(383-391)Selector
(144-148)Modifier
(156-156)utils/is-node-function-type.ts (1)
isNodeFunctionType
(49-60)rules/sort-object-types/is-member-optional.ts (1)
isMemberOptional
(15-23)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(111-163)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)rules/sort-object-types/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(27-74)utils/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(93-124)utils/report-all-errors.ts (1)
reportAllErrors
(203-326)
test/rules/sort-jsx-props.test.ts (1)
test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-jsx-props/types.ts (4)
rules/sort-object-types/types.ts (2)
Selector
(144-148)allSelectors
(334-339)rules/sort-objects/types.ts (2)
Selector
(157-157)allSelectors
(293-293)rules/sort-exports/types.ts (2)
Selector
(103-103)allSelectors
(139-139)rules/sort-named-imports/types.ts (2)
Selector
(109-109)allSelectors
(156-156)
rules/sort-objects/types.ts (2)
rules/sort-jsx-props/types.ts (2)
Selector
(126-126)allSelectors
(155-155)rules/sort-object-types/types.ts (2)
Selector
(144-148)allSelectors
(334-339)
🪛 ESLint
test/rules/sort-interfaces.test.ts
[error] 565-565: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 571-571: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 599-599: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 605-605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3235-3235: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3241-3241: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3269-3269: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3275-3275: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5891-5891: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5897-5897: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5925-5925: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5931-5931: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-objects.test.ts
[error] 1617-1617: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4445-4445: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 7272-7272: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-object-types.test.ts
[error] 351-351: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 357-357: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 385-385: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 391-391: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2932-2932: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2938-2938: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2966-2966: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2972-2972: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5520-5520: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5526-5526: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5554-5554: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5560-5560: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🔇 Additional comments (15)
test/rules/sort-interfaces.test.ts (5)
466-466
: Group rename to optional-multiline-member is correct.Renamed IDs align with the removal of legacy group names and keep expectations consistent.
Also applies to: 475-475, 489-489, 3136-3136, 3145-3145, 3160-3160, 5792-5792, 5801-5801, 5816-5816
552-583
: Precedence test “index-signature over member” looks good across modes.Solid coverage validating the new generic “member” bucket vs index signatures.
Also applies to: 3222-3253, 5878-5910
586-618
: Precedence test “method over member” is correct and consistent.Confirms “method” outranks the generic “member” group in all sorting types.
Also applies to: 3256-3287, 5912-5943
751-751
: Use of multiline-member in customGroups and groups arrays is consistent.The updates correctly reflect the new member-based grouping model.
Also applies to: 759-769, 806-807, 3421-3421, 3430-3430, 3439-3439, 3476-3476, 6076-6076, 6085-6085, 6094-6094, 6132-6132
489-489
: Confirm schema/docs include new group IDs (member, multiline-member, optional-multiline-member).Ensure JSON Schema, README, and rule docs list these identifiers to prevent config drift.
Also applies to: 751-751, 580-580
rules/sort-jsx-props/types.ts (1)
140-140
: Confirm JoinWithDash yields intended group tokensPlease verify
JoinWithDash<[ShorthandModifier, MultilineModifier, PropertySelector]>
produces: 'prop' | 'shorthand-prop' | 'multiline-prop' | 'shorthand-multiline-prop' (and not require both modifiers nor alter token order).If needed, I can add a tiny type-test file to assert these unions at build time.
test/rules/sort-jsx-props.test.ts (2)
203-205
: LGTM: renamed groups to 'shorthand-prop'The updates align with the new selector/modifier model and expected group identifiers.
Also applies to: 1590-1592, 2970-2971
307-309
: LGTM: 'multiline-prop' group usageConsistent with the new typings and grouping semantics.
Also applies to: 1694-1696, 3074-3075
test/rules/sort-objects.test.ts (3)
1598-1629
: Member grouping update looks correct (methods prioritized).Test title, payload (leftGroup: 'member'), and groups: ['method', 'member'] align with the new selector semantics.
4426-4457
: Member grouping update looks correct (methods prioritized).Matches the alphabetical variant; payload and groups are consistent.
7253-7284
: Member grouping update looks correct (methods prioritized).Line-length variant mirrors the other suites; looks good.
rules/sort-object-types.ts (1)
239-241
: Good: multiline is treated as a modifier only, and 'member' selector is always present.
This matches the new grouping model and avoids prior ambiguity.Also applies to: 251-252
rules/sort-object-types/types.ts (1)
231-241
: LGTM: PropertyGroup introduction aligns tests and rule semantics.test/rules/sort-object-types.test.ts (2)
252-276
: Group renames to 'member' and 'multiline-member' look correct.Updates match the new Property/Member grouping model and align with rule/type changes.
Also applies to: 275-276, 2920-2950, 2953-2985, 5507-5573, 7988-7993
338-369
: Sanity-check: precedence tests for index-signature/method over member.Assertions and groups arrays correctly prefer 'index-signature' and 'method' over the generic 'member'.
If CI allows, re-run the suite focusing on these blocks to ensure no regressions in group resolution order.
Also applies to: 372-404, 2919-2950, 2953-2985, 5507-5573
memberProperty: something, | ||
} | ||
`, | ||
code: dedent` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typescript/no-unsafe-call on dedent tagged templates.
ESLint flags the tagged calls because dedent’s types are any
. Prefer a typed alternative.
Apply this import change (top of file):
-import dedent from 'dedent'
+import dedent from 'ts-dedent'
If switching packages is undesirable, alternatively cast once:
// near imports
import dedentUntyped from 'dedent'
const dedent: (s: TemplateStringsArray, ...v: unknown[]) => string =
dedentUntyped as unknown as (s: TemplateStringsArray, ...v: unknown[]) => string
Or relax no-unsafe-call in test overrides, but code fix is preferred.
Also applies to: 4445-4445, 7272-7272
🧰 Tools
🪛 ESLint
[error] 1617-1617: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🤖 Prompt for AI Agents
In test/rules/sort-objects.test.ts around line 1617, ESLint flags the dedent
tagged template because dedent's types are any; replace the untyped import with
a typed alternative by updating the top-of-file import to a properly typed
dedent (or cast the imported dedent to the signature (s: TemplateStringsArray,
...v: unknown[]) => string) so the tagged template calls are typed and
no-unsafe-call errors are resolved; apply the same change for occurrences around
lines 4445 and 7272 if present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
rules/sort-decorators.ts (1)
140-156
: Handle TSParameterProperty in Decorator visitor (constructor parameter properties).Visitor only matches decorator.parent.type === 'Identifier' (parent.parent.type === 'FunctionExpression') and will skip parameter properties wrapped in TSParameterProperty; detect TSParameterProperty (or unwrap .parameter) and call sortDecorators on its decorators so constructor/parameter-property decorators are sorted. Location: rules/sort-decorators.ts — Decorator visitor.
utils/compute-group.ts (1)
82-99
: Deep‑flatten groups and filter strings only; current Set may miss nested groups or include config objects
options.groups
supports nested arrays and non‑string config entries. Usingflat()
(depth 1) risks ignoring deeper groups and treating objects as valid entries, causing valid custom/predefined groups to be rejected. Build the lookup set by recursively collecting only string group names.Apply:
- // For lookup performance. - let groupsSet = new Set(options.groups.flat()) + // For lookup performance: collect string group names from possibly nested arrays and ignore config objects. + const groupsSet = collectGroupNames(options.groups) + + function collectGroupNames(groups: GroupsOptions<string>): Set<string> { + let set = new Set<string>() + let stack: unknown[] = [groups] + while (stack.length) { + let item = stack.pop() as unknown + if (Array.isArray(item)) { + for (let sub of item) stack.push(sub) + } else if (typeof item === 'string') { + set.add(item) + } + // ignore objects like { newlinesBetween: ... } + } + return set + }test/rules/sort-imports.test.ts (1)
22-28
: Restore spies after each test to prevent cross-test leakageSome tests stub
readClosestTsConfigByPath
(andgetTypescriptImport
) but don’t always restore them. Add a global cleanup to avoid subtle pollution across cases and suites.describe('sort-imports', () => { + afterEach(() => { + vi.restoreAllMocks() + })rules/sort-imports.ts (1)
354-369
: Enable spacing errors: provide newlinesBetweenValueGetter.Without it, ‘missed/extra spacing’ messages won’t fire.
reportAllErrors<MessageId>({ availableMessageIds: { @@ sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(sortingNodeGroups), sourceCode, - options, + options, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), context, nodes, })And import:
+import { getLinesBetween } from '../utils/get-lines-between'
test/rules/sort-interfaces.test.ts (2)
7909-7915
: Remove deprecatedignorePattern
from tests or update PR objectives/docsPR intends to drop the deprecated
ignorePattern
, but tests/rules/docs still reference it — either keep the option and update the PR/docs, or migrate tests to a conditional unsorted config.
- Fix this test: test/rules/sort-interfaces.test.ts:7911 — replace the options block with a conditional unsorted config, e.g. { useConfigurationIf: { declarationMatchesPattern: 'Ignore' }, type: 'unsorted' }.
- Update or remove all other occurrences found in tests/rules/utils and docs (examples: test/rules/sort-objects.test.ts ~8784–8872, test/rules/sort-object-types.test.ts:7973, test/rules/sort-jsx-props.test.ts ~4270–4283, utils/get-settings.ts, test/utils/get-settings.test.ts, rules/*.ts, docs/content/**).
466-476
: Standardize on "optional-multiline-member" — remove legacy "multiline-optional-member"Code/tests already use "optional-multiline-member" (24 hits); the legacy alias "multiline-optional-member" appears only in docs: docs/content/rules/sort-interfaces.mdx:483 and docs/content/rules/sort-object-types.mdx:449 — remove/update those references and confirm schema/types/README list only "optional-multiline-member".
♻️ Duplicate comments (9)
rules/sort-jsx-props/types.ts (2)
106-111
: Selector JSDoc is stale; only 'prop' is supportedKeep guidance aligned with the narrowed selector surface; use modifiers for shorthand/multiline.
Apply:
- /** - * The selector type for this group. Can be 'prop' for regular props, - * 'multiline' for multi-line props, or 'shorthand' for shorthand props. - */ + /** + * The selector type for this group. Allowed: 'prop' only. + * Use modifiers ('shorthand' | 'multiline') to target those cases. + */
119-124
: Clarify Selector doc to reflect narrowed surfaceDocument that specificity is via modifiers.
Apply:
-/** - * Union type of all available JSX prop selectors. Used to categorize different - * types of JSX props. - */ +/** + * Selector for JSX props. Only "prop" is supported; specificity is expressed via modifiers. + */ export type Selector = PropertySelectortest/rules/sort-objects.test.ts (1)
1-7
: Fix typescript/no-unsafe-call on dedent by using a typed alternativeUse
ts-dedent
(typed) to silence the rule without overrides.Apply:
-import dedent from 'dedent' +import dedent from 'ts-dedent'Or, if keeping
dedent
:import dedentUntyped from 'dedent' const dedent: (s: TemplateStringsArray, ...v: unknown[]) => string = dedentUntyped as unknown as (s: TemplateStringsArray, ...v: unknown[]) => stringTo verify and locate remaining imports:
#!/bin/bash rg -nP "import\s+dedent\s+from\s+['\"]dedent['\"]" -C2docs/content/rules/sort-heritage-clauses.mdx (5)
148-159
: Fix copy: decorators → heritage clauses; make RegExpPattern.flags optional.Still references decorators and requires flags. Apply:
### partitionByComment <sub>default: `false`</sub> -Enables the use of comments to separate class decorators into logical groups. +Enables the use of comments to separate heritage clauses into logical groups. - `true` — All comments will be treated as delimiters, creating partitions. - `false` — Comments will not be used as delimiters. -- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. +- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters. -- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. +- `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. -- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters. +- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters.
168-176
: Document full newlinesBetween union and semantics.Align with implementation:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'ignore' | 'always' | 'never' | number`</sub> @@ -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report newline errors. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups (equivalent to `0`). +- `number` — Require exactly this number of blank lines between groups.
265-273
: Expand CustomGroupDefinition types (‘custom’; newlinesInside union).interface CustomGroupDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
279-291
: Unify CustomGroupAnyOfDefinition.fallbackSort type and mention selector.interface CustomGroupAnyOfDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } newlinesInside?: number anyOf: Array<{ - selector?: string + selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }And document selector in Attributes (see next comment).
295-304
: Document the ‘selector’ attribute.#### Attributes - `groupName` — The group's name, which needs to be put in the [`groups`](#groups) option. +- `selector` — (AnyOf only) AST selector to narrow which elements the subgroup matches. - `elementNamePattern` — If entered, will check that the name of the element matches the pattern entered. - `type` — Overrides the [`type`](#type) option for that custom group. `unsorted` will not sort the group. - `order` — Overrides the [`order`](#order) option for that custom group. - `fallbackSort` — Overrides the [`fallbackSort`](#fallbacksort) option for that custom group. - `newlinesInside` — Enforces a specific newline behavior between elements of the group.
rules/sort-object-types.ts (1)
341-349
: Missing newlinesBetweenValueGetter → spacing diagnostics won’t trigger.Pass a getter so missed/extra blank-line errors work.
reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })Add import:
+import { getLinesBetween } from '../utils/get-lines-between'
🧹 Nitpick comments (33)
test/rules/sort-decorators.test.ts (2)
6-6
: Lint: typescript/no-unsafe-call on tagged template (dedent).Static analysis flags “unsafe call” on many dedent template tags. If this isn’t a false positive, ensure dedent is correctly typed:
- Prefer ts-dedent (typed) or add @types/dedent.
- Alternatively, add a small ambient type for tests.
Example ambient d.ts (tests only):
declare module 'dedent' { function dedent(strings: TemplateStringsArray, ...values: any[]): string export default dedent }
6319-6327
: Helper naming/intent.duplicate5Times works, but a param for count would make it reusable across files (e.g., duplicateErrors(n, errors)).
rules/sort-decorators.ts (2)
49-67
: Make defaults immutable and type‑checked at compile time.Use const + satisfies to lock defaults to Required<Options[0]> and catch drift early.
-let defaultOptions: Required<Options[0]> = { +const defaultOptions = { fallbackSort: { type: 'unsorted' }, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', sortOnProperties: true, sortOnParameters: true, sortOnAccessors: true, type: 'alphabetical', sortOnClasses: true, sortOnMethods: true, ignoreCase: true, customGroups: [], locales: 'en-US', alphabet: '', order: 'asc', groups: [], -} +} satisfies Required<Options[0]>
4-7
: Combine type/value imports from types module.Minor import tidy to reduce duplication.
-import type { - SortDecoratorsSortingNode, - Options, -} from './sort-decorators/types' -… -import { singleCustomGroupJsonSchema } from './sort-decorators/types' +import { + type SortDecoratorsSortingNode, + type Options, + singleCustomGroupJsonSchema, +} from './sort-decorators/types'Also applies to: 30-30
rules/sort-object-types/types.ts (1)
52-58
: API shape looks solid; small typing cleanup suggestion.
- customGroups extension with
fallbackSort.sortBy
is clear and consistent.- Suggest narrowing
IndexSignatureGroup
to just'index-signature'
(index signatures have no modifiers per AllowedModifiersPerSelector), to avoid permitting unattainable groups likerequired-index-signature
. This keeps type-level guidance tight.Also applies to: 228-238
utils/get-newlines-between-option.ts (1)
25-30
: LGTM on requiring customGroups; behavior matches same-group newlinesInside.Consider precomputing a name→customGroup map at caller level if this runs in tight loops, but not blocking.
docs/content/rules/sort-objects.mdx (1)
370-383
: Update docs: reflect new customGroups API, remove deprecated options, fix test link
- Replace the customGroups type doc that currently shows
{ [groupName: string]: string | string[] }
with the array-of-objects shape (or reference CustomGroupsOption) in docs/content/rules/sort-objects.mdx (example config area ≈ lines 363–402).- Remove deprecated options (e.g., ignorePattern, destructureOnly) from the canonical Usage/config snippets so examples match the current API.
- Fix the Resources "Test source" link in docs/content/rules/sort-objects.mdx — it currently points to test/sort-objects.test.ts; update to test/rules/sort-objects.test.ts (the actual test file is test/rules/sort-objects.test.ts).
test/utils/get-newlines-between-option.test.ts (1)
380-387
: Nit: tighten helper contract docs and namingNow that
customGroups
defaults to an array, the helper effectively always supplies an array. Consider reflecting that in the test descriptions to avoid implying “undefined”.Apply this diff to update the description that still mentions “not defined”:
- 'should return the global option (`%s`) if "customGroups" is not defined', + 'should return the global option (`%s`) when "customGroups" is empty or omitted',utils/get-newlines-between-errors.ts (1)
48-50
: Docstring says “Optional” but the type is requiredThe property is non‑optional in the type. Make the JSDoc consistent.
Apply this diff:
- /** Optional custom groups configuration. */ - customGroups: CustomGroupsOption + /** Custom groups configuration (required). */ + customGroups: CustomGroupsOptionutils/make-newlines-between-fixes.ts (1)
29-30
: Docstring says “Optional” but the type is requiredAlign JSDoc with the signature.
Apply this diff:
- /** Optional custom groups configuration. */ - customGroups: CustomGroupsOption + /** Custom groups configuration (required). */ + customGroups: CustomGroupsOptiontest/rules/sort-object-types.test.ts (3)
338-367
: “member” fallback precedence: add one positive (valid) caseYou exercised “index-signature over member”. Add a simple valid case proving a plain property falls into
member
and stays after the specific group. This guards regressions in the fallback classifier.Also applies to: 2849-2880, 5367-5398
372-403
: “method over member”: assert adjacency (no unintended blank lines)Current tests check order only. Add one valid case asserting no spacing change occurs when both are same partition and
newlinesBetween
doesn’t mandate separation.Also applies to: 2883-2914, 5402-5433
2110-2238
: Config precedence with multipleuseConfigurationIf
blocksNice coverage. Consider an extra test where both blocks match to assert precedence is by array order (first match wins). This will document and lock expected behavior.
Also applies to: 4721-4749, 7232-7260
docs/content/rules/sort-jsx-props.mdx (6)
303-305
: Fix regex precedence in allNamesMatchPattern.'^r|g|b$' matches strings starting with 'r' OR containing 'g' OR ending with 'b'. Use '^(r|g|b)$' (or '^[rgb]$') to match exactly r, g, or b.
Apply this diff:
- allNamesMatchPattern: '^r|g|b$', + allNamesMatchPattern: '^(r|g|b)$',
484-492
: Tighten the “callback” example pattern.'^on.+' also matches 'one'/'only'. Prefer '^on[A-Z].*' for React-style event handlers.
Apply this diff:
- elementNamePattern: '^on.+' + elementNamePattern: '^on[A-Z].*'
245-255
: Document missing newlinesBetween values ('always' | 'never').Types allow 'always' and 'never', but docs list only 'ignore' | number. Add both and brief semantics.
Apply this diff:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'ignore' | 'always' | 'never' | number`</sub> @@ -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Preserve current spacing (no fixes). +- `'always'` — Enforce exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `0` — Alias of `'never'`. +- Any other number — Enforce that exact number of blank lines between groups; forbid newlines inside groups.
221-237
: Incorrect type/description for [DEPRECATED] ignorePattern.This section shows an object with allNamesMatchPattern, which belongs to useConfigurationIf, not ignorePattern. For this rule, ignorePattern matches the JSX tag name (string | regex | arrays).
Apply this diff:
-<sub> - type: - ``` - { - allNamesMatchPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - } - ``` -</sub> -<sub>default: `[]`</sub> - -Use the [useConfigurationIf.tagMatchesPattern](#useconfigurationif) option alongside [type: unsorted](#type) instead. - -Specifies names or patterns for JSX elements that should be ignored by this rule. This can be useful if you have specific components that you do not want to sort. +<sub> + type: `string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]` +</sub> +<sub>default: `[]`</sub> + +Deprecated. Prefer `useConfigurationIf.tagMatchesPattern` with `type: 'unsorted'`. + +Specifies tag names or patterns for JSX elements to ignore (skip sorting).
422-434
: Allow 'always' | 'never' for newlinesInside in interfaces.Types support
'always' | 'never' | number
, but docs list onlynumber
.Apply this diff:
- newlinesInside?: number + newlinesInside?: 'always' | 'never' | numberAlso applies to: 440-453
575-576
: Update “Resources” links to new locations.Tests moved under test/rules with Vitest. Update links to avoid 404/old paths.
Apply this diff:
-- [Rule source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/rules/sort-jsx-props.ts) -- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-jsx-props.test.ts) +- [Rule source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/rules/sort-jsx-props.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-jsx-props.test.ts)If the path differs (e.g., tests/ vs test/), adjust accordingly.
utils/get-comment-above-that-should-exist.ts (2)
17-22
: Docstring says “Optional” but property is now required.Update the comment to avoid confusion.
Apply this diff:
- /** Optional custom groups configuration. */ + /** Custom groups configuration. */ customGroups: CustomGroupsOption
94-99
: Guard when rightGroupIndex is 0; avoid non-null assertion and negative index.When rightGroupIndex === 0,
groups[-1]
yields undefined. The!
is misleading even if guarded later. Early-return for index 0 and remove the assertion.Apply this diff:
- let groupAboveRight = options.groups[rightGroupIndex - 1]! + if (rightGroupIndex === 0) { + return null + } + let groupAboveRight = options.groups[rightGroupIndex - 1] if (!isCommentAboveOption(groupAboveRight)) { return null } @@ - return { - comment: groupAboveRight.commentAbove, + return { + comment: groupAboveRight.commentAbove, exists: !!matchingCommentsAbove, }Also applies to: 106-109, 111-113
utils/make-fixes.ts (1)
138-154
: Skip newlines computation when it’s a no-op.Micro-optimization: avoid calling makeNewlinesBetweenFixes when global newlinesBetween is 'ignore' and there are no per-group overrides.
Apply this diff:
- if (options?.groups) { + if (options?.groups) { + const hasGroupOverrides = + options.groups.some(g => typeof g === 'object' && 'newlinesBetween' in g) + if (options.newlinesBetween === 'ignore' && !hasGroupOverrides) { + // No spacing work needed + } else { let newlinesFixes = makeNewlinesBetweenFixes({ options: { ...options, newlinesBetween: options.newlinesBetween, groups: options.groups, }, newlinesBetweenValueGetter, sortedNodes, sourceCode, fixer, nodes, }) if (newlinesFixes.length > 0) { return [...orderFixes, ...newlinesFixes] } + } }rules/sort-jsx-props.ts (1)
44-46
: Module-level cache lifecycle.Minor: cachedGroupsByModifiersAndSelectors is module-scoped and persists across files/runs. Consider clearing it per rule invocation (e.g., in create) to avoid unbounded growth across diverse modifier/selector combos (low risk here).
utils/validate-generated-groups-configuration.ts (1)
9-11
: Also validate duplicate custom group names.We validate duplicate groups, but not duplicate customGroups.groupName entries. Add a quick check to prevent ambiguous resolution.
Apply this diff:
export function validateGeneratedGroupsConfiguration({ selectors, modifiers, options, }: ValidateGenerateGroupsConfigurationParameters): void { - let availableCustomGroupNames = new Set( - options.customGroups.map(customGroup => customGroup.groupName), - ) + const customNames = options.customGroups.map(cg => cg.groupName) + const dupCustom = customNames.filter( + (n, i) => customNames.indexOf(n) !== i, + ) + if (dupCustom.length > 0) { + throw new Error(`Duplicated custom group(s): ${Array.from(new Set(dupCustom)).join(', ')}`) + } + let availableCustomGroupNames = new Set(customNames)Also applies to: 79-81, 83-91
utils/compute-group.ts (1)
55-66
: JSDoc example still references removed “name” paramThe param was dropped; example should not include it.
Apply:
- * predefinedGroups: ['external'], - * name: 'react-dom', + * predefinedGroups: ['external'],rules/sort-object-types.ts (1)
247-251
: Don’t assign optional/required to TSIndexSignature.Index signatures aren’t optional/required; current logic misclassifies them.
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }rules/sort-heritage-clauses.ts (1)
150-160
: Set correct partitionId when pushing.Currently all nodes use 0. Assign the partition index on push.
- let sortingNode: SortingNode = { + let sortingNode: Omit<SortingNode, 'partitionId'> = { isEslintDisabled: isNodeEslintDisabled( @@ - partitionId: 0, group, name, } @@ - formattedMembers.at(-1)!.push(sortingNode) + formattedMembers.at(-1)!.push({ + ...sortingNode, + partitionId: formattedMembers.length, + })Also applies to: 174-175
test/rules/sort-interfaces.test.ts (6)
11-15
: Use const for tester destructuringNo reassignment; prefer const.
- let { invalid, valid } = createRuleTester({ + const { invalid, valid } = createRuleTester({ parser: typescriptParser, name: 'sort-interfaces', rule, })
17-23
: Prefer const for immutable optionsYou already assert as const; declare with const.
- let options = { + const options = { type: 'alphabetical', order: 'asc', } as constRepeat in other describe blocks for consistency.
552-584
: Coverage for index-signature > member precedence looks solidNice focused assertions and autofix outputs.
Consider adding one triad test showing full ordering in a single interface: index-signature → method → member, with groups: ['index-signature','method','member'].
Also applies to: 3127-3159, 5688-5720
586-618
: Method > member precedence validated; unify sample literal quotingOutputs mix 'something' and "something". Not wrong, but uniform quotes reduce noise in snapshots.
Also applies to: 3161-3193, 5722-5754
2318-2349
: Great addition: conditional configs via useConfigurationIf + allNamesMatchPatternConsider one extra case to assert fallback selection when none of the conditional configs match (proves default branch is applied).
Also applies to: 4896-4924, 7450-7478
7-7
: Use public export for Alphabet in tests (if available)
To exercise published API, import from the package’s ./alphabet export instead of an internal path (keep as-is if tests run purely against sources).-import { Alphabet } from '../../utils/alphabet' +import { Alphabet } from '../../alphabet'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (43)
docs/content/rules/sort-heritage-clauses.mdx
(5 hunks)docs/content/rules/sort-interfaces.mdx
(1 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-object-types.mdx
(1 hunks)docs/content/rules/sort-objects.mdx
(1 hunks)rules/sort-decorators.ts
(5 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-enums.ts
(2 hunks)rules/sort-heritage-clauses.ts
(5 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-imports.ts
(6 hunks)rules/sort-imports/types.ts
(1 hunks)rules/sort-interfaces.ts
(1 hunks)rules/sort-jsx-props.ts
(2 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-object-types.ts
(3 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(1 hunks)rules/sort-object-types/types.ts
(2 hunks)rules/sort-objects.ts
(2 hunks)rules/sort-objects/types.ts
(4 hunks)test/rules/sort-decorators.test.ts
(2 hunks)test/rules/sort-heritage-clauses.test.ts
(5 hunks)test/rules/sort-imports.test.ts
(24 hunks)test/rules/sort-interfaces.test.ts
(15 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-object-types.test.ts
(18 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(0 hunks)test/rules/sort-objects.test.ts
(29 hunks)test/utils/compute-group.test.ts
(3 hunks)test/utils/get-custom-groups-compare-options.test.ts
(0 hunks)test/utils/get-newlines-between-option.test.ts
(4 hunks)types/common-options.ts
(0 hunks)utils/common-json-schemas.ts
(0 hunks)utils/compute-group.ts
(4 hunks)utils/get-comment-above-that-should-exist.ts
(2 hunks)utils/get-custom-groups-compare-options.ts
(2 hunks)utils/get-newlines-between-errors.ts
(1 hunks)utils/get-newlines-between-option.ts
(1 hunks)utils/make-comment-above-fixes.ts
(2 hunks)utils/make-fixes.ts
(2 hunks)utils/make-newlines-between-fixes.ts
(1 hunks)utils/report-all-errors.ts
(0 hunks)utils/validate-generated-groups-configuration.ts
(5 hunks)
💤 Files with no reviewable changes (5)
- utils/report-all-errors.ts
- test/utils/get-custom-groups-compare-options.test.ts
- test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
- utils/common-json-schemas.ts
- types/common-options.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/content/rules/sort-interfaces.mdx
- docs/content/rules/sort-object-types.mdx
- rules/sort-interfaces.ts
- rules/sort-decorators/types.ts
- rules/sort-heritage-clauses/types.ts
- rules/sort-objects/types.ts
🧰 Additional context used
🧬 Code graph analysis (19)
utils/get-newlines-between-option.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
utils/get-custom-groups-compare-options.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
utils/make-comment-above-fixes.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
utils/make-fixes.ts (1)
types/common-options.ts (3)
NewlinesBetweenOption
(203-226)CustomGroupsOption
(103-140)GroupsOptions
(445-451)
utils/get-newlines-between-errors.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
utils/compute-group.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-imports/types.ts (1)
SingleCustomGroup
(182-194)
rules/sort-imports/types.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
utils/get-comment-above-that-should-exist.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
rules/sort-jsx-props.ts (1)
utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)
rules/sort-enums.ts (1)
utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)
rules/sort-object-types/types.ts (3)
types/common-options.ts (2)
CustomGroupsOption
(103-140)FallbackSortOption
(319-331)rules/sort-objects/types.ts (1)
SingleCustomGroup
(122-138)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-objects.ts (1)
utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)
rules/sort-object-types.ts (12)
utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)rules/sort-object-types/types.ts (4)
sortByJsonSchema
(350-353)SortObjectTypesSortingNode
(380-388)Selector
(141-145)Modifier
(153-153)utils/is-node-function-type.ts (1)
isNodeFunctionType
(49-60)rules/sort-object-types/is-member-optional.ts (1)
isMemberOptional
(15-23)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)rules/sort-object-types/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(27-72)utils/get-custom-groups-compare-options.ts (1)
getCustomGroupsCompareOptions
(89-118)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
utils/validate-generated-groups-configuration.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
rules/sort-decorators.ts (10)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-heritage-clauses.ts (10)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-exports/types.ts (3)
SingleCustomGroup
(72-91)Selector
(103-103)allSelectors
(139-139)
utils/make-newlines-between-fixes.ts (1)
types/common-options.ts (2)
NewlinesBetweenOption
(203-226)CustomGroupsOption
(103-140)
rules/sort-imports.ts (5)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
🪛 ESLint
test/rules/sort-interfaces.test.ts
[error] 565-565: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 571-571: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 599-599: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 605-605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3140-3140: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3146-3146: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3174-3174: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3180-3180: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5701-5701: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5707-5707: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5735-5735: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5741-5741: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-object-types.test.ts
[error] 351-351: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 357-357: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 385-385: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 391-391: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2862-2862: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2868-2868: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2896-2896: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2902-2902: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5380-5380: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5386-5386: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5414-5414: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5420-5420: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-decorators.test.ts
[error] 480-480: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 507-507: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 597-597: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 604-604: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 635-635: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 657-657: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 693-693: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 735-735: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 805-805: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 895-895: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 905-905: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 963-963: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 972-972: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1034-1034: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1046-1046: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1099-1099: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1106-1106: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1155-1155: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1160-1160: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1196-1196: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1222-1222: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1256-1256: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1263-1263: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1303-1303: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1312-1312: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1353-1353: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1359-1359: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1397-1397: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1402-1402: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1414-1414: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1461-1461: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2854-2854: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2863-2863: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2881-2881: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2889-2889: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-objects.test.ts
[error] 1575-1575: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4397-4397: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4431-4431: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4437-4437: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 7211-7211: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-heritage-clauses.test.ts
[error] 200-200: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 213-213: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 237-237: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 248-248: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 273-273: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 278-278: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 298-298: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 303-303: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 343-343: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 348-348: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 394-394: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 399-399: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 437-437: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 442-442: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 475-475: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 480-480: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 502-502: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 553-553: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 564-564: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 623-623: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 633-633: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 696-696: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 709-709: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 763-763: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 771-771: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 821-821: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 827-827: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 864-864: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 892-892: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 927-927: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 935-935: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 976-976: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 986-986: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1028-1028: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1035-1035: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1074-1074: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1080-1080: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1109-1109: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1120-1120: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1158-1158: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1174-1174: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1201-1201: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1220-1220: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1233-1233: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1266-1266: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1303-1303: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1310-1310: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1330-1330: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1350-1350: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1364-1364: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1401-1401: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1408-1408: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1428-1428: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1440-1440: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1462-1462: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-imports.test.ts
[error] 4312-4312: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4349-4349: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4361-4361: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
reportAllErrors<MessageId>({ | ||
availableMessageIds: { | ||
missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', | ||
extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', | ||
unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', | ||
unexpectedOrder: 'unexpectedHeritageClausesOrder', | ||
}, | ||
sortNodesExcludingEslintDisabled: | ||
createSortNodesExcludingEslintDisabled(nodes), | ||
sourceCode, | ||
options, | ||
context, | ||
nodes, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provide newlinesBetweenValueGetter to report spacing errors.
reportAllErrors<MessageId>({
availableMessageIds: {
@@
- sourceCode,
- options,
+ sourceCode,
+ options,
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
context,
nodes,
})
And import:
+import { getLinesBetween } from '../utils/get-lines-between'
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', | |
unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', | |
unexpectedOrder: 'unexpectedHeritageClausesOrder', | |
}, | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) | |
import { getLinesBetween } from '../utils/get-lines-between' | |
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', | |
unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', | |
unexpectedOrder: 'unexpectedHeritageClausesOrder', | |
}, | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
newlinesBetweenValueGetter: (left, right) => | |
getLinesBetween(sourceCode, left, right), | |
context, | |
nodes, | |
}) |
🤖 Prompt for AI Agents
In rules/sort-heritage-clauses.ts around lines 192-205, the call to
reportAllErrors is missing the newlinesBetweenValueGetter option; add
newlinesBetweenValueGetter: newlinesBetweenValueGetter to the object passed into
reportAllErrors so spacing errors are reported, and add an import for
newlinesBetweenValueGetter from the utility module where other value getters
live (import newlinesBetweenValueGetter from the appropriate utils path at the
top of the file).
}, | ||
it('handles hash symbol in internal patterns correctly', async () => { | ||
await valid({ | ||
code: dedent` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix ESLint no-unsafe-call on dedent tagged templates (newly added lines)
Static analysis flags the tagged use of dedent
here. Quick unblock: locally disable the rule for these lines. Longer-term, consider switching the tests to ts-dedent
(typed) or using dedent(String.raw\
...`) across the suite.
- code: dedent`
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+ code: dedent`
...
- output: dedent`
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+ output: dedent`
...
- code: dedent`
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+ code: dedent`
Also applies to: 4349-4349, 4361-4361
🧰 Tools
🪛 ESLint
[error] 4312-4312: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🤖 Prompt for AI Agents
In test/rules/sort-imports.test.ts around lines 4312, 4349, and 4361, ESLint
flags the tagged use of `dedent` as a no-unsafe-call; to quickly unblock tests,
add a local ESLint disable comment immediately before each offending line to
silence @typescript-eslint/no-unsafe-call for that single line (i.e., use an
eslint-disable-next-line for that rule), run the linter to confirm only those
lines are suppressed, and consider the longer-term alternatives noted in the
comment (ts-dedent or dedent(String.raw`...`).
newlinesBetween: NewlinesBetweenOption | ||
|
||
/** Custom groups configuration for advanced grouping. */ | ||
customGroups: CustomGroupsOption | ||
|
||
/** Groups configuration defining available groups and their order. */ | ||
groups?: GroupsOptions<string> | ||
groups: GroupsOptions<string> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Required fields inside an optional options object.
newlinesBetween, customGroups, and groups are required but options itself is optional. Verify all callers always pass options with these fields; otherwise, make options required.
🏁 Script executed:
#!/bin/bash
# List all invocations to ensure `options` is provided.
rg -nP "makeFixes\s*\(" -C3
Length of output: 1312
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== make-fixes.ts (1-220) ==="
nl -ba utils/make-fixes.ts | sed -n '1,220p' || true
echo "=== make-fixes.ts (220-480) ==="
nl -ba utils/make-fixes.ts | sed -n '220,480p' || true
echo "=== makeFixes call sites ==="
rg -nP "makeFixes\\s*\\(" -C3 || true
echo "=== utils/report-errors.ts (120-160) ==="
nl -ba utils/report-errors.ts | sed -n '120,160p' || true
echo "=== rules/sort-switch-case.ts (240-280) ==="
nl -ba rules/sort-switch-case.ts | sed -n '240,280p' || true
Length of output: 1654
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== locate makeFixes definition ==="
rg -nP "export\s+(?:const|function)\s+makeFixes|const\s+makeFixes\s*[:=]|function\s+makeFixes\s*\(" --hidden || true
echo
echo "=== show make-fixes.ts (full) with line numbers ==="
awk '{printf "%5d: %s\n", NR, $0}' utils/make-fixes.ts || true
echo
echo "=== show call sites for makeFixes with context ==="
rg -nP "makeFixes\\s*\\(" -n -C8 || true
echo
echo "=== utils/report-errors.ts (110-160) ==="
awk 'NR>=110 && NR<=160{printf "%5d: %s\n", NR, $0}' utils/report-errors.ts || true
echo
echo "=== rules/sort-switch-case.ts (240-280) ==="
awk 'NR>=240 && NR<=280{printf "%5d: %s\n", NR, $0}' rules/sort-switch-case.ts || true
Length of output: 13066
Make nested fields in MakeFixesParameters optional or require callers to always pass options.
A call site omits options (rules/sort-switch-case.ts — makeFixes at ~254–260), while MakeFixesParameters declares options?: { newlinesBetween: NewlinesBetweenOption; customGroups: CustomGroupsOption; groups: GroupsOptions } (utils/make-fixes.ts). Either:
- Preferred: mark newlinesBetween, customGroups, groups as optional in utils/make-fixes.ts; or
- Alternative: make options required and update all callers to pass a complete options object (e.g., rules/sort-switch-case.ts and utils/report-errors.ts).
🤖 Prompt for AI Agents
In utils/make-fixes.ts around lines 29–36, the nested fields inside the optional
options object are currently required which causes call sites that omit options
to fail; change the declaration so newlinesBetween, customGroups, and groups are
optional (e.g., add ? to each field or replace the options type with
Partial<...>) so callers can omit the entire options object, and update any
dependent types/usages if necessary; alternatively, if you choose the other
approach, make the top-level options required and update all callers
(rules/sort-switch-case.ts and utils/report-errors.ts) to pass a complete
options object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
rules/sort-object-types/types.ts (1)
225-233
: Index signatures can’t be optional/required — simplify IndexSignatureGroupThe current JoinWithDash includes Optional/Required/Multiline for index-signature, which are invalid. Restrict the group type to the selector only.
Apply:
-type IndexSignatureGroup = JoinWithDash< - [ - OptionalModifier, - RequiredModifier, - MultilineModifier, - IndexSignatureSelector, - ] -> +type IndexSignatureGroup = JoinWithDash<[IndexSignatureSelector]>rules/sort-interfaces.ts (1)
20-36
: Drop deprecatedignorePattern
from v5 (types, defaults, schema, code, docs, tests).ignorePattern remains in defaults/types/schema/implementation/docs/tests and must be removed or replaced by the new configuration approach (e.g., useConfigurationIf.*).
Files/locations found (action required):
- utils/get-settings.ts (+ test: test/utils/get-settings.test.ts)
- rules/sort-interfaces.ts (defaultOptions)
- rules/sort-objects.ts (defaultOptions, usage: matches(..., options.ignorePattern), jsonSchema)
- rules/sort-object-types.ts (defaultOptions, usage, jsonSchema)
- rules/sort-object-types/types.ts
- rules/sort-objects/types.ts
- rules/sort-jsx-props.ts (defaultOptions, usage, jsonSchema)
- rules/sort-jsx-props/types.ts
- docs/content/guide/getting-started.mdx
- docs/content/rules/*.mdx (sort-object-types, sort-jsx-props, sort-objects, sort-interfaces)
- tests referencing ignorePattern under test/rules/*
Required changes:
- Remove ignorePattern from all Option type definitions.
- Remove ignorePattern from JSON schemas (drop regexJsonSchema entries).
- Remove from defaultOptions in all rules.
- Refactor code that reads options.ignorePattern (matches(...) checks) to use the intended v5 mechanism (useConfigurationIf.*) or equivalent logic.
- Update/remove tests that assert ignorePattern behavior.
- Update docs and add migration notes for v5.
rules/sort-maps.ts (1)
249-258
: String-literal Map keys are returned with quotes; this breaks pattern matching.getNodeName uses Literal.raw (""foo""), so allNamesMatchPattern/customGroups won’t match '^foo$'. Use Literal.value when it’s a string.
if (element.type === 'ArrayExpression') { let [left] = element.elements if (!left) { return `${left}` - } else if (left.type === 'Literal') { - return left.raw + } else if (left.type === 'Literal') { + // Prefer unquoted value for string literals; fall back to raw otherwise. + // @ts-expect-error TS narrows value on Literal + return typeof left.value === 'string' ? String(left.value) : left.raw } return sourceCode.getText(left) }docs/content/rules/sort-objects.mdx (1)
575-579
: customGroups type is outdated; docs show deprecated shape.The page says the object-based API is deprecated but the type still documents it. Switch to the array-based definitions, consistent with other pages.
-<sub> - type: `{ [groupName: string]: string | string[] }` -</sub> +<sub> + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>` +</sub>rules/sort-objects.ts (1)
336-340
: Partition ID off-by-one can merge partitions during sort.partitionId is 1-based (length) while partitions are 0-based indices (last bucket at length - 1). This can allow cross-partition reordering in downstream sorting.
Use the current bucket index:
- accumulator.at(-1)!.push({ + accumulator.at(-1)!.push({ ...sortingNode, - partitionId: accumulator.length, + partitionId: accumulator.length - 1, })rules/sort-jsx-props.ts (3)
55-69
: v5 target: remove deprecated ignorePattern from defaults.Per the v5 goals, drop ignorePattern from defaultOptions.
let defaultOptions: Required<Options[number]> = { fallbackSort: { type: 'unsorted' }, specialCharacters: 'keep', newlinesBetween: 'ignore', partitionByNewLine: false, useConfigurationIf: {}, type: 'alphabetical', - ignorePattern: [], ignoreCase: true, customGroups: [], locales: 'en-US', alphabet: '', order: 'asc', groups: [], }
95-101
: Remove runtime support for ignorePattern.Eliminate the deprecated ignorePattern branch and rely on useConfigurationIf.tagMatchesPattern only.
- let shouldIgnore = matches( - sourceCode.getText(node.openingElement.name), - options.ignorePattern, - ) - if (shouldIgnore || !isSortable(node.openingElement.attributes)) { - return - } + // ignorePattern removed in v5
216-233
: Schema still exposes deprecated ignorePattern.Drop ignorePattern from the public JSON schema for this rule.
properties: { ...commonJsonSchemas, useConfigurationIf: buildUseConfigurationIfJsonSchema({ additionalProperties: { tagMatchesPattern: regexJsonSchema, }, }), customGroups: buildCustomGroupsArrayJsonSchema({ singleCustomGroupJsonSchema, }), partitionByNewLine: partitionByNewLineJsonSchema, newlinesBetween: newlinesBetweenJsonSchema, - ignorePattern: regexJsonSchema, groups: groupsJsonSchema, },
♻️ Duplicate comments (5)
test/rules/sort-imports.test.ts (1)
4312-4312
: Fix ESLint no-unsafe-call for new dedent tagged templatesSilence the rule locally for these new lines to unblock CI. Longer term: consider
ts-dedent
ordedent(String.raw\
...`) across tests.await valid({ - code: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent` ... await invalid({ - output: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + output: dedent` ... - code: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent`Also applies to: 4349-4349, 4361-4361
rules/sort-heritage-clauses.ts (1)
192-205
: Pass newlinesBetweenValueGetter to enable spacing diagnostics.Without it, spacing errors may be missed. Add the getter and import getLinesBetween.
import { reportAllErrors } from '../utils/report-all-errors' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { @@ sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), context, nodes, })test/rules/sort-objects.test.ts (1)
4-4
: Fix typescript/no-unsafe-call on dedent import.Use a typed dedent to satisfy ESLint. This single import change fixes all flagged tagged-template calls in this file.
-import dedent from 'dedent' +import dedent from 'ts-dedent'rules/sort-object-types.ts (2)
240-244
: Don’t assign optional/required to index signatures.Index signatures don’t have optionality; assigning required/optional produces misleading groups.
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }
334-343
: Enable spacing diagnostics for object types.Pass newlinesBetweenValueGetter to support missed/extra blank-line errors when newlinesBetween is configured.
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, availableMessageIds, sourceCode, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), options, context, nodes, })Also applies to: 1-22
🧹 Nitpick comments (27)
rules/sort-intersection-types.ts (1)
20-33
: Prefer const + satisfies for immutability and tighter typingUse const and the satisfies operator to keep literals narrow and enable better DCE/treeshaking. No runtime change.
Apply:
-let defaultOptions: Required<Options[number]> = { +const defaultOptions = { fallbackSort: { type: 'unsorted' }, specialCharacters: 'keep', newlinesBetween: 'ignore', partitionByComment: false, partitionByNewLine: false, type: 'alphabetical', ignoreCase: true, locales: 'en-US', customGroups: [], alphabet: '', order: 'asc', groups: [], -} +} satisfies Required<Options[number]>;rules/sort-switch-case.ts (1)
30-38
: Prefer const for immutable defaults
defaultOptions
isn’t reassigned. Usingconst
prevents accidental mutation.Apply:
-let defaultOptions: Required<Options[number]> = { +const defaultOptions: Required<Options[number]> = {rules/sort-union-types.ts (1)
50-63
: Make defaults immutableUse
const
to guard against reassignment.-let defaultOptions: Required<Options[number]> = { +const defaultOptions: Required<Options[number]> = {rules/sort-variable-declarations.ts (1)
50-63
: Use const for defaultOptionsMinor immutability/readability win.
-let defaultOptions: Required<Options[number]> = { +const defaultOptions: Required<Options[number]> = {utils/filter-options-by-all-names-match.ts (1)
80-94
: Logic is sound; clarify empty inputs behaviorCurrent logic treats empty
nodeNames
as matching (vacuous truth). If that’s intended, great; if not, add an explicit guard.Option if you want “no names ⇒ no conditional match”:
export function filterOptionsByAllNamesMatch<T extends Options>({ contextOptions, nodeNames, }: { contextOptions: T[] nodeNames: string[] }): T[] { - return contextOptions.filter(options => { + if (nodeNames.length === 0) return contextOptions + return contextOptions.filter(options => { let allNamesMatchPattern = options.useConfigurationIf?.allNamesMatchPattern return ( !allNamesMatchPattern || nodeNames.every(nodeName => matches(nodeName, allNamesMatchPattern)) ) }) }rules/sort-classes.ts (1)
65-102
: Minor: declare immutable defaultsFollow the same const pattern for consistency and safety.
-let defaultOptions: Required<SortClassesOptions[number]> = { +const defaultOptions: Required<SortClassesOptions[number]> = {utils/filter-options-by-declaration-comment-matches.ts (1)
35-37
: Normalize JSDoc/block comment text before regex matchingRaw block comments include leading “*” and spacing; trimming alone can cause false negatives. Normalize comment text per line before matches().
Apply:
- return parentComment.some(comment => - matches(comment.value.trim(), declarationCommentMatchesPattern), - ) + return parentComment.some(comment => + matches(normalizeCommentValue(comment.value), declarationCommentMatchesPattern), + )Add below in the file (outside this hunk):
function normalizeCommentValue(value: string): string { return value .split('\n') .map(line => line.replace(/^\s*\*?\s?/, '').trimEnd()) .join('\n') .trim() }rules/sort-object-types/types.ts (1)
167-182
: Remove vestigial 'multiline' selector mappingAllowedModifiersPerSelector includes a 'multiline' key even though 'multiline' is not a Selector anymore. This is dead surface; deleting it tightens types.
Apply:
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - /** Index signatures cannot have modifiers. */ 'index-signature': never }test/rules/sort-imports.test.ts (4)
2431-2438
: Reset spies after tsconfig mockingAdd
after: vi.resetAllMocks()
to prevent cross-test leakage fromreadClosestTsConfigByPath
mocks.before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },
6081-6088
: Reset spies after tsconfig mocking (natural block)Same leak risk here; reset mocks.
before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },
9766-9773
: Reset spies after tsconfig mocking (line-length block)Mirror the reset to keep tests isolated.
before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },
11263-11308
: Optional: factor repeated customGroups into a helperThe long list is duplicated between valid/invalid cases; consider a small builder to cut noise.
const cg = (name: string) => (pattern: string) => ({ elementNamePattern: pattern, groupName: name })rules/sort-heritage-clauses.ts (1)
150-175
: Set partitionId per-partition (align with other rules).Currently always 0; set it based on the current partition index.
- let sortingNode: SortingNode = { + let sortingNodeBase: Omit<SortingNode, 'partitionId'> = { isEslintDisabled: isNodeEslintDisabled( heritageClause, eslintDisabledLines, ), size: rangeToDiff(heritageClause, sourceCode), node: heritageClause, - partitionId: 0, group, name, } @@ - formattedMembers.at(-1)!.push(sortingNode) + formattedMembers.at(-1)!.push({ + ...sortingNodeBase, + partitionId: formattedMembers.length - 1, + })rules/sort-imports.ts (2)
356-371
: Provide newlinesBetweenValueGetter to actually report spacing errors.Wire the getter and import getLinesBetween.
import { reportAllErrors } from '../utils/report-all-errors' import { shouldPartition } from '../utils/should-partition' import { computeGroup } from '../utils/compute-group' import { rangeToDiff } from '../utils/range-to-diff' import { getSettings } from '../utils/get-settings' import { isSortable } from '../utils/is-sortable' import { complete } from '../utils/complete' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { unexpectedDependencyOrder: 'unexpectedImportsDependencyOrder', missedSpacingBetweenMembers: 'missedSpacingBetweenImports', extraSpacingBetweenMembers: 'extraSpacingBetweenImports', unexpectedGroupOrder: 'unexpectedImportsGroupOrder', missedCommentAbove: 'missedCommentAboveImport', unexpectedOrder: 'unexpectedImportsOrder', }, sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(sortingNodeGroups), sourceCode, - options, + options, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), context, nodes, })
396-404
: Guard against empty tsconfig.rootDir strings in schema.Add minLength to avoid accidental '' which disables tsconfig resolution.
rootDir: { description: 'Specifies the tsConfig root directory.', - type: 'string', + type: 'string', + minLength: 1, },rules/sort-decorators.ts (1)
269-283
: Hook up newlinesBetweenValueGetter so spacing messages are emitted.Add the getter and import getLinesBetween.
import { reportAllErrors } from '../utils/report-all-errors' import { shouldPartition } from '../utils/should-partition' import { computeGroup } from '../utils/compute-group' import { rangeToDiff } from '../utils/range-to-diff' import { getSettings } from '../utils/get-settings' import { isSortable } from '../utils/is-sortable' import { complete } from '../utils/complete' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenDecorators', extraSpacingBetweenMembers: 'extraSpacingBetweenDecorators', unexpectedGroupOrder: 'unexpectedDecoratorsGroupOrder', unexpectedOrder: 'unexpectedDecoratorsOrder', }, ignoreFirstNodeHighestBlockComment: true, sortNodesExcludingEslintDisabled, sourceCode, - options, + options, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), context, nodes, })test/utils/filter-options-by-all-names-match.test.ts (1)
19-27
: Add coverage for array patterns and anchored regex.Optional: extend tests to ensure arrays and anchors behave as expected.
it('returns options where all node names match `allNamesMatchPattern`', () => { let barContextOptions = buildContextOptions('bar') let contextOptions = [buildContextOptions('foo'), barContextOptions] let nodeNames = ['bar1', 'bar&foo'] expect(filterOptionsByAllNamesMatch({ contextOptions, nodeNames })).toEqual( [barContextOptions], ) }) + + it('supports array patterns and anchored regex', () => { + let contextOptions = [ + buildContextOptions(['^lib-', '^core-']), + buildContextOptions(['^app-']), + ] + let nodeNames = ['lib-utils', 'core-types'] + expect( + filterOptionsByAllNamesMatch({ contextOptions, nodeNames }), + ).toEqual([contextOptions[0]]) + })test/utils/filter-options-by-declaration-comment-matches.test.ts (2)
4-4
: Avoid coupling tests to AST_TOKEN_TYPES for comments; use literal 'Line' to match TSESTree.Comment.AST_TOKEN_TYPES may drift; TSESLint expects comments with type 'Line' | 'Block'. Use string literals and drop the import.
-import { AST_TOKEN_TYPES } from '@typescript-eslint/utils' +// (no import needed)return { getCommentsBefore: () => comments.map(comment => ({ - loc: null as unknown as TSESTree.SourceLocation, - type: AST_TOKEN_TYPES.Line, + loc: null as unknown as TSESTree.SourceLocation, + type: 'Line', value: comment, range: [0, 0], })), } as unknown as TSESLint.SourceCodeAlso applies to: 71-80
40-55
: Nice positive match case; consider adding array/regex forms.Add a case for ['foo', { pattern: 'bar', flags: 'i' }] to exercise all RegexOption shapes.
docs/content/rules/sort-objects.mdx (1)
302-317
: Conflicting guidance: points to declarationMatchesPattern, which isn’t listed for this rule.Either (a) add declarationMatchesPattern to useConfigurationIf for sort-objects, or (b) change this deprecation note to reference declarationCommentMatchesPattern/callingFunctionNamePattern + type: 'unsorted'.
-Use the [useConfigurationIf.declarationMatchesPattern](#useconfigurationif) option alongside [type: unsorted](#type) instead. +Use [useConfigurationIf.declarationCommentMatchesPattern](#useconfigurationif) (and/or `callingFunctionNamePattern`) alongside [type: 'unsorted'] instead.docs/content/rules/sort-object-types.mdx (1)
339-349
: *Invalid regex example (‘Metadata$’).Leading '*' is not a valid JS regex. Use '.*Metadata$' (or '^.*Metadata$') to avoid user confusion.
- declarationMatchesPattern: '*Metadata$', + declarationMatchesPattern: '.*Metadata$',test/rules/sort-object-types.test.ts (1)
338-370
: Tests use a property literally named “member”, which reads like a group name.This can be misread in failure diffs (leftGroup: 'member', left: 'member'). Consider renaming the property to something neutral (e.g., propX) to reduce ambiguity while preserving the scenario.
Also applies to: 372-404, 2906-2937, 2940-2971, 5424-5456, 5458-5490
docs/content/rules/sort-interfaces.mdx (1)
373-383
: *Invalid regex example (‘Metadata$’).Use '.*Metadata$' to show a valid pattern.
- declarationMatchesPattern: '*Metadata$', + declarationMatchesPattern: '.*Metadata$',rules/sort-object-types/get-custom-groups-compare-options.ts (1)
51-55
: Minor readability: avoid destructuring assignment with a leading semicolon.Use a direct assignment to reduce cognitive overhead.
- if ('sortBy' in customGroup && customGroup.sortBy) { - ;({ sortBy } = customGroup) - } + if ('sortBy' in customGroup && customGroup.sortBy) { + sortBy = customGroup.sortBy + }test/rules/sort-interfaces.test.ts (2)
2443-2496
: declarationCommentMatchesPattern: solid coverage.Line-comment gating is exercised with both valid and invalid cases. Consider adding one block-comment case to mirror object rules’ tests for symmetry.
360-411
: Same-line comments and semicolons: consistent after-fix outputs.A few outputs mix
'something'
and"something"
across suites; not harmful but consider unifying quotes to reduce churn in snapshots.Also applies to: 3019-3043, 5580-5604
rules/sort-objects/types.ts (1)
168-183
: Tighten AllowedModifiersPerSelector for regular objects.multiline and index-signature aren’t valid selectors for this rule; keeping them here is confusing. Consider removing these keys.
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - - /** Index signatures are not supported in regular objects. */ - 'index-signature': never }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-object-types.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(5 hunks)rules/sort-array-includes.ts
(5 hunks)rules/sort-classes.ts
(1 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-enums.ts
(5 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-imports.ts
(6 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(1 hunks)rules/sort-jsx-props.ts
(7 hunks)rules/sort-maps.ts
(3 hunks)rules/sort-modules.ts
(2 hunks)rules/sort-named-exports.ts
(2 hunks)rules/sort-named-imports.ts
(2 hunks)rules/sort-object-types.ts
(10 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(3 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-objects.ts
(10 hunks)rules/sort-objects/types.ts
(5 hunks)rules/sort-switch-case.ts
(1 hunks)rules/sort-union-types.ts
(1 hunks)rules/sort-variable-declarations.ts
(1 hunks)test/rules/sort-imports.test.ts
(25 hunks)test/rules/sort-interfaces.test.ts
(18 hunks)test/rules/sort-object-types.test.ts
(19 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(1 hunks)test/rules/sort-objects.test.ts
(31 hunks)test/utils/filter-options-by-all-names-match.test.ts
(1 hunks)test/utils/filter-options-by-declaration-comment-matches.test.ts
(1 hunks)test/utils/get-matching-context-options.test.ts
(0 hunks)utils/filter-options-by-all-names-match.ts
(3 hunks)utils/filter-options-by-declaration-comment-matches.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- test/utils/get-matching-context-options.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
- rules/sort-named-exports.ts
- rules/sort-named-imports.ts
- rules/sort-enums.ts
🧰 Additional context used
🧬 Code graph analysis (24)
utils/filter-options-by-declaration-comment-matches.ts (4)
rules/sort-object-types/types.ts (1)
Options
(28-112)rules/sort-objects/types.ts (1)
Options
(25-120)types/common-options.ts (1)
RegexOption
(477-477)utils/matches.ts (1)
matches
(39-60)
utils/filter-options-by-all-names-match.ts (3)
rules/sort-interfaces.ts (1)
Options
(12-12)rules/sort-object-types/types.ts (1)
Options
(28-112)rules/sort-objects/types.ts (1)
Options
(25-120)
test/utils/filter-options-by-declaration-comment-matches.test.ts (2)
utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)types/common-options.ts (1)
RegexOption
(477-477)
rules/sort-switch-case.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-112)
rules/sort-intersection-types.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-union-types/types.ts (1)
Options
(22-54)
test/utils/filter-options-by-all-names-match.test.ts (2)
utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)types/common-options.ts (1)
RegexOption
(477-477)
rules/sort-union-types.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-union-types/types.ts (1)
Options
(22-54)
rules/sort-variable-declarations.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-variable-declarations/types.ts (1)
Options
(23-55)
rules/sort-maps.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-maps/types.ts (1)
Options
(20-64)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)
rules/sort-classes.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-classes/types.ts (1)
SortClassesOptions
(25-66)
rules/sort-modules.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-modules/types.ts (1)
SortModulesOptions
(25-59)
rules/sort-array-includes.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (1)
Options
(24-68)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
test/rules/sort-imports.test.ts (1)
rules/sort-imports/types.ts (1)
Options
(29-141)
rules/sort-objects/types.ts (1)
types/common-options.ts (2)
RegexOption
(477-477)CustomGroupsOption
(103-140)
rules/sort-heritage-clauses.ts (11)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-exports.ts (5)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-object-types/types.ts (2)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-imports.ts (8)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)rules/sort-imports/validate-side-effects-configuration.ts (1)
validateSideEffectsConfiguration
(19-48)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
rules/sort-decorators.ts (6)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (3)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-interfaces.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-112)
rules/sort-jsx-props.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-jsx-props/types.ts (1)
Options
(24-71)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
rules/sort-objects.ts (6)
rules/sort-objects/types.ts (1)
Options
(25-120)utils/common-json-schemas.ts (2)
regexJsonSchema
(219-228)buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
rules/sort-object-types.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-112)utils/matches.ts (1)
matches
(39-60)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)
rules/sort-object-types/get-custom-groups-compare-options.ts (1)
rules/sort-object-types/types.ts (1)
Options
(28-112)
🪛 ESLint
test/rules/sort-object-types.test.ts
[error] 351-351: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 357-357: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 385-385: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 391-391: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2381-2381: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2410-2410: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2417-2417: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2919-2919: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2925-2925: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2953-2953: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2959-2959: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5415-5415: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5437-5437: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5443-5443: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5471-5471: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5477-5477: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-interfaces.test.ts
[error] 565-565: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 571-571: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 599-599: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 605-605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2399-2399: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2427-2427: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2433-2433: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2453-2453: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2489-2489: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3197-3197: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3203-3203: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3231-3231: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 3237-3237: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5758-5758: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5764-5764: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5792-5792: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 5798-5798: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-imports.test.ts
[error] 4312-4312: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4349-4349: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4361-4361: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
test/rules/sort-objects.test.ts
[error] 1575-1575: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2189-2189: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2192-2192: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2332-2332: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2352-2352: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2381-2381: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2388-2388: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 4501-4501: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 7315-7315: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🔇 Additional comments (42)
rules/sort-intersection-types.ts (1)
20-20
: Approve — Required<Options[number]> is correct; verify no leftover Options[0]Switching to Required<Options[number]> avoids tuple-index narrowing and aligns with the shared Options[] typing.
Automated search produced no output; run locally to confirm no occurrences remain:
rg -nP --type=ts '\bOptions\[\s*0\s*\]' -C2 rg -nP --type=ts '\bRequired<\s*Options\[\s*0\s*\]\s*>' -C2rules/sort-switch-case.ts (1)
30-38
: Type tweak to Options[number] is correct and aligns with repo-wide patternUsing
Required<Options[number]>
future‑proofs the defaultOptions typing for tuple/array Options. No behavior change.rules/sort-union-types.ts (1)
50-63
: Consistent shift to Options[number]Matches the new options-array convention; default object keys look compatible with the rule’s Options.
rules/sort-variable-declarations.ts (1)
50-63
: Options[number] typing LGTMBrings this rule in line with others; no runtime impact.
rules/sort-classes.ts (1)
65-102
: Adopting SortClassesOptions[number] is appropriateType-only change; default keys align with the rule types and usage.
utils/filter-options-by-all-names-match.ts (1)
49-49
: Docs updated to new API name — verify no stale imports remainExamples now call filterOptionsByAllNamesMatch; ensure every import/usage of the old getMatchingContextOptions is replaced across the repo.
Check: utils/filter-options-by-all-names-match.ts (lines 49, 62).
Re-run verification from repo root: rg -n --hidden --no-ignore-vcs -S '\bgetMatchingContextOptions\b' -g '!dist/**' -C3 || git grep -n 'getMatchingContextOptions'rules/sort-modules.ts (2)
66-66
: Type widening to Options[number] looks goodMatches the project-wide typing pattern for defaultOptions. No behavioral changes.
171-171
: Consistent parameter typingUsing Required<SortModulesOptions[number]> for analyzeModule keeps types aligned with completed options.
rules/sort-array-includes.ts (3)
32-32
: Switch to filterOptionsByAllNamesMatch is appropriateCorrectly scopes options based on element names; aligns with the new matching utilities.
56-58
: Type alias simplification is fineUsing SortingNode<TSESTree.SpreadElement | TSESTree.Expression> removes the unused groupKind surface.
60-74
: Default groups contain only 'literal' — spreads become “unknown”With groups: ['literal'], SpreadElements fall into the unknown bucket and will be sorted unless explicitly ignored. If the intent is to leave spreads untouched by default, treat unknown groups as ignored during sorting (see next comment).
Do we want spreads sorted by default? If not, apply the next change.
rules/sort-exports.ts (4)
50-52
: Type alias clean-up is solidRemoving groupKind from the node type aligns with the groups-based architecture.
54-67
: Default options with empty groups preserve mixed sortingEmpty groups mean all nodes share the same group; the rule still sorts consistently by name. Looks good.
151-162
: Groups-based sorting flow LGTMUsing sortNodesByGroups with per-group overrides is consistent with other rules. No need to ignore unknowns here since groups are empty by default.
165-179
: Error reporting wiring is correctMessage IDs map correctly; flattened nodes passed into reportAllErrors match expected contract.
rules/sort-object-types/types.ts (2)
35-40
: New declarationCommentMatchesPattern hook looks correctMatches the new conditional-config pattern used elsewhere; documentation is clear.
58-64
: Per-custom-group fallbackSort extension is a nice additionAllows finer control without widening global options.
test/rules/sort-imports.test.ts (5)
1462-1475
: LGTM: good coverage for per-group newlinesBetween overriding globalAccurately exercises precedence with a sentinel
unusedGroup
.
1534-1551
: LGTM: “never” fences between groups regardless of global settingSolid assertions on spacing normalization.
1613-1626
: LGTM: ignore/never/0 interaction preservedScenarios look correct and future‑proof for spacing behavior.
7908-7917
: LGTM: targeted customGroups with modifiersNice demonstration of value‑only selector via
modifiers: ['value']
.
11559-11570
: LGTM: precise typing for groups in helper
Options[number]['groups']
keeps the tests aligned with the exported type.test/utils/filter-options-by-declaration-comment-matches.test.ts (1)
11-25
: Good coverage for “undefined/empty” behavior.docs/content/rules/sort-objects.mdx (1)
414-432
: Great addition of declarationCommentMatchesPattern examples.docs/content/rules/sort-object-types.mdx (1)
351-369
: Nice, clear example for declarationCommentMatchesPattern.test/rules/sort-object-types.test.ts (2)
2370-2425
: Solid coverage for declarationCommentMatchesPattern in rule tests.
2210-2238
: Good move to two-option arrays for allNamesMatchPattern scenarios.This mirrors runtime matching precedence and prevents false positives.
Also applies to: 4778-4806, 7290-7317
docs/content/rules/sort-interfaces.mdx (1)
385-403
: Clear, practical example for declarationCommentMatchesPattern.rules/sort-object-types/get-custom-groups-compare-options.ts (1)
8-11
: API shape update looks good and matches Options[number] usage across the repo.Also applies to: 31-37
rules/sort-maps.ts (1)
81-89
: No action required — complete() safely handles undefined; filterOptionsByAllNamesMatch may return []filterOptionsByAllNamesMatch can return [] when no context option matches (tests cover this), and complete(matchedContextOptions[0], settings, defaultOptions) uses a default parameter ({}), so passing undefined is safe.
test/rules/sort-interfaces.test.ts (7)
552-584
: Group name “member”: scenarios covered; looks good.The new “member” predefined group is exercised across alphabetical/natural/line‑length. Assertions and options arrays align with the new grouping surface.
Please confirm docs list “member” in the predefined groups for sort-interfaces so users can discover it.
Also applies to: 3184-3216, 5745-5777
586-618
: Method over member precedence: consistent across modes.Test cases clearly assert method > member ordering with matching fixes. No action needed.
Also applies to: 3219-3250, 5779-5811
2321-2349
: Multi-configuration selection with allNamesMatchPattern is correct.Two-option arrays demonstrate precedence fallback and targeted activation (foo vs RGB). Good coverage.
Also applies to: 4961-4980, 7507-7534
2389-2440
: declarationMatchesPattern flow validated.Tests cover enable-on-name then fallback to default options. Good.
Also applies to: 5021-5072, 7575-7626
1398-1417
: Partition-by-newline behavior: nice set of positive/negative tests.Readability looks good; fixes preserve blank lines between partitions.
Also applies to: 4029-4050, 6588-6611
1869-1887
: Whitespace normalization tests: helpful.These catch spacing fixups alongside ordering. No issues.
Also applies to: 4501-4519, 7055-7072
452-516
: Complex predefined groups: expectations updated to new group names.The switch to optional‑multiline‑member etc. is reflected correctly.
Also applies to: 3084-3147, 5646-5709
rules/sort-objects.ts (5)
66-85
: Defaults updated to array-based Options and empty customGroups: good.Typings and defaults (Required<Options[number]>, customGroups: [], groups: []) look consistent with the new schema.
Ensure docs for sort-objects reflect: top-level customGroups array, declarationCommentMatchesPattern, and destructuredObjects.groups flag.
426-453
: JSON schema: top-level customGroups and declarationCommentMatchesPattern wired correctly.Schema changes align with the new API surface.
99-106
: Context option matching pipeline is clear and ordered.Filtering by names, then declaration comment, then calling function is sensible and predictable.
Also applies to: 111-121
241-345
: Formatting pipeline and modifiers/selectors classification looks solid.Method/property detection, multiline modifier, predefined groups caching, and computeGroup usage are correct.
146-150
: ESLint-disable awareness preserved via sortNodesExcludingEslintDisabled.Good separation of sorting with ignore toggles and centralized reporting.
Also applies to: 381-395
import type { TSESLint } from '@typescript-eslint/utils' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enable spacing diagnostics (missed/extra blank lines).
Pass newlinesBetweenValueGetter so reportAllErrors can evaluate newlinesBetween for JSX props.
+import { getLinesBetween } from '../utils/get-lines-between'
@@
for (let currentNodes of formattedMembers) {
@@
reportAllErrors<MessageId>({
availableMessageIds: {
missedSpacingBetweenMembers: 'missedSpacingBetweenJSXPropsMembers',
extraSpacingBetweenMembers: 'extraSpacingBetweenJSXPropsMembers',
unexpectedGroupOrder: 'unexpectedJSXPropsGroupOrder',
unexpectedOrder: 'unexpectedJSXPropsOrder',
},
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
sortNodesExcludingEslintDisabled:
createSortNodesExcludingEslintDisabled(currentNodes),
nodes: currentNodes,
sourceCode,
options,
context,
})
Also applies to: 198-212
🤖 Prompt for AI Agents
In rules/sort-jsx-props.ts around lines 1-2 and also apply the same change at
198-212, enable spacing diagnostics for missed/extra blank lines by passing the
newlinesBetweenValueGetter into the reportAllErrors call (so reportAllErrors can
evaluate the newlinesBetween option for JSX props); add or import a
newlinesBetweenValueGetter function if missing and thread it through to where
reportAllErrors is invoked, ensuring the call signature includes this getter and
that reportAllErrors uses it when computing spacing/newline diagnostics.
if (callParent) { | ||
return { | ||
name: sourceCode.getText(callParent.callee), | ||
type: 'CallExpression', | ||
node: callParent, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Normalize callingFunctionNamePattern callee text to reduce false positives.
Using sourceCode.getText(callParent.callee) can include arbitrary expressions (e.g., (0, foo.bar)
). Consider extracting a dotted identifier when possible to make matching predictable.
Example:
function getCalleeName(expr: TSESTree.Expression): string | null {
if (expr.type === 'Identifier') return expr.name
if (expr.type === 'MemberExpression' && !expr.computed && expr.property.type === 'Identifier') {
return expr.property.name // or `${obj}.${prop}` if desired
}
return null
}
Then fall back to getText only when null.
🤖 Prompt for AI Agents
In rules/sort-objects.ts around lines 571 to 577, the code uses
sourceCode.getText(callParent.callee) which can return arbitrary wrapped
expressions and cause false positives; change this to first normalize the callee
by extracting a stable name: if callee.type is Identifier return its name; if
MemberExpression and not computed and property is Identifier return the property
name or a dotted "object.property" string as desired; only if those checks fail,
fall back to sourceCode.getText(callParent.callee); then use that normalized
string in the returned object so callingFunctionNamePattern matching is
predictable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (17)
test/rules/sort-sets.test.ts (2)
978-985
: Fix quoted spread literals ('...foo'): they should be spreads, not strings.These cases currently test a string literal instead of a
SpreadElement
, weakening coverage of thespread
selector.Apply per block (3 occurrences):
- '...foo', + ...foo,and
- '...foo', + ...foo,Also applies to: 985-991, 2500-2506, 2507-2513, 4022-4028, 4029-4035
4597-4603
: Invalid Set constructor in “custom → sorts elements in sets”.
new Set('a','b',...)
is not valid usage; pass an iterable.Apply:
- new Set( - 'a', - 'b', - 'c', - 'd', - ) + new Set([ + 'a', + 'b', + 'c', + 'd', + ])rules/sort-object-types/types.ts (2)
225-233
: Fix group type construction (avoids impossible 'optional-required-*' and removes modifiers from index-signature).Current JoinWithDash over literal tokens produces a single impossible key (e.g., 'optional-required-multiline-property'), and index signatures are documented as having no modifiers. Define groups via template unions and keep index-signature bare.
- type IndexSignatureGroup = JoinWithDash< - [ - OptionalModifier, - RequiredModifier, - MultilineModifier, - IndexSignatureSelector, - ] - > + // Index signatures cannot have modifiers. + type IndexSignatureGroup = 'index-signature' - type PropertyGroup = JoinWithDash< - [OptionalModifier, RequiredModifier, MultilineModifier, PropertySelector] - > + // Compose allowed modifier prefixes without impossible combos. + type ModifierPrefix<S extends string> = + | S + | `optional-${S}` + | `required-${S}` + | `multiline-${S}` + | `optional-multiline-${S}` + | `required-multiline-${S}` + + type PropertyGroup = ModifierPrefix<'property'> - type MemberGroup = JoinWithDash< - [OptionalModifier, RequiredModifier, MultilineModifier, MemberSelector] - > + type MemberGroup = ModifierPrefix<'member'> - type MethodGroup = JoinWithDash< - [OptionalModifier, RequiredModifier, MultilineModifier, MethodSelector] - > + type MethodGroup = ModifierPrefix<'method'>Also applies to: 241-243, 267-269, 278-281
96-101
: Remove deprecatedignorePattern
across the codebase or keep & document (mandatory refactor required).ignorePattern is still referenced in runtime logic, defaults, types, schemas, tests, and docs — deleting the type alone will break the repo. Update all usages or keep and document a migration path.
- Key locations that must be changed:
- rules/sort-object-types.ts (default + schema + runtime check using options.ignorePattern — e.g. runtime check around line ~194)
- rules/sort-object-types/types.ts (ignorePattern: RegexOption)
- rules/sort-objects.ts / rules/sort-objects/types.ts (defaults, runtime matches(..., options.ignorePattern), schema)
- rules/sort-jsx-props.ts / rules/sort-jsx-props/types.ts (defaults, runtime use of options.ignorePattern, schema)
- rules/sort-interfaces.ts / rules/sort-interfaces/types.ts
- utils/get-settings.ts (declaration and settings list include ignorePattern)
- tests: test/rules/*.test.ts (many tests pass/expect ignorePattern) and test/utils/get-settings.test.ts
- docs: docs/content/rules/*.mdx and docs/content/guide/getting-started.mdx (DEPRECATED sections and examples)
- Actions:
- If dropping in v5: remove ignorePattern declarations and defaults, remove schema entries, refactor runtime checks to the appropriate useConfigurationIf.* replacement (e.g., declarationMatchesPattern / tagMatchesPattern where applicable), update utils/get-settings, update tests and docs, add migration notes/changelog entry, run full test suite.
- If keeping until v5: keep code paths and types, mark rule-level support explicitly, add a clear removal timeline in docs/migrations, and update tests/docs to reflect the timeline.
test/rules/sort-array-includes.test.ts (3)
1183-1196
: Fix: use spread element, not a string literal, in anyOf test'...foo' should be a spread element (...foo). The current quotes make it a literal and fail to exercise selector: 'spread'.
- '...foo', + ...foo,
2979-2993
: Fix: use spread element, not a string literal, in anyOf test (natural section)Same issue in the natural sorting block.
- '...foo', + ...foo,
4756-4768
: Fix: use spread element, not a string literal, in anyOf test (line-length section)Same issue in the line-length sorting block.
- '...foo', + ...foo,docs/content/rules/sort-array-includes.mdx (1)
250-258
: Docs/API mismatch: newlinesBetween supports 'always' and 'never'Schema and tests allow 'always'|'never' in addition to numbers/'ignore'. Update docs.
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `number | 'ignore' | 'always' | 'never'`</sub> @@ -Specifies how to handle newlines between groups. +Specifies how to handle newlines between groups. @@ -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'never'` — No newlines are allowed (equivalent to `0`). +- `'always'` — Enforce at least one newline (use a number for an exact count). +- `0` — No newlines are allowed. +- Any other number — Enforce this exact number of newlines between each group, and forbid newlines inside groups.docs/content/rules/sort-objects.mdx (1)
575-578
: customGroups type still shows deprecated object shapeThis section still documents
{ [groupName: string]: string | string[] }
although the page migrates to the array API. Update to the new array type to prevent user confusion.-<sub> - type: `{ [groupName: string]: string | string[] }` -</sub> +<sub> + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>` +</sub>docs/content/rules/sort-jsx-props.mdx (1)
221-233
: Fix incorrect type for [DEPRECATED] ignorePatternThe type block shows a wrapped object with allNamesMatchPattern, which is unrelated to ignorePattern. Suggest using the direct pattern types.
Apply this diff:
-### [DEPRECATED] ignorePattern - -<sub> - type: - ``` - { - allNamesMatchPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - } - ``` -</sub> +### [DEPRECATED] ignorePattern + +<sub> + type: + ``` + string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] + ``` +</sub> <sub>default: `[]`</sub>test/rules/sort-object-types.test.ts (1)
252-276
: Useoptional-multiline-member
consistently (docs + schema check required)Tests already use the new identifier (
test/rules/sort-object-types.test.ts
,test/rules/sort-interfaces.test.ts
); documentation still contains the old formmultiline-optional-member
(examples in docs/content/rules/sort-object-types.mdx and docs/content/rules/sort-interfaces.mdx). Replace stalemultiline-optional-member
occurrences withoptional-multiline-member
and verify the groups JSON/schema/generator (rules/sort-object-types/types.ts, utils/generate-predefined-groups*, utils/common-json-schemas*) accept the new identifier.rules/sort-named-imports.ts (1)
1-6
: Change SortNamedImportsSortingNode to SortingNode<TSESTree.ImportSpecifier>rules/sort-named-imports/types.ts currently declares SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause> (line 95) but the rule builds sorting nodes from ImportSpecifier nodes (e.g., checks specifier.type === 'ImportSpecifier' and uses the specifier as the node). Update the type to SortingNode<TSESTree.ImportSpecifier>.
test/rules/sort-interfaces.test.ts (1)
7966-7979
: Remove deprecated ignorePattern in v5; switch to useConfigurationIf.v5 scope removes ignorePattern. Update this test to the new conditional-config to keep parity.
- options: [ - { - ignorePattern: ['Ignore'], - type: 'line-length', - order: 'desc', - }, - ], + options: [ + { + useConfigurationIf: { declarationMatchesPattern: 'Ignore' }, + // prevent sorting when the declaration matches + type: 'unsorted', + }, + ],docs/content/rules/sort-heritage-clauses.mdx (1)
376-403
: Drop legacy ESLint v8 config example or mark unsupported in v5 ESM-only.Since v5 drops ESLint v8 and is ESM-only, the .eslintrc.js example is misleading. Recommend removal.
- { - source: dedent` - // .eslintrc.js - module.exports = { - plugins: [ - 'perfectionist', - ], - rules: { - 'perfectionist/sort-heritage-clauses': [ - 'error', - { - type: 'alphabetical', - order: 'asc', - fallbackSort: { type: 'unsorted' }, - ignoreCase: true, - specialCharacters: 'keep', - partitionByComment: false, - partitionByNewLine: false, - newlinesBetween: 'ignore', - groups: [], - customGroups: [], - }, - ], - }, - } - `, - name: 'Legacy Config', - value: 'legacy', - },rules/sort-jsx-props/types.ts (1)
65-70
: Remove deprecated ignorePattern in v5.The v5 plan removes ignorePattern across rules. Drop it from the public Options type.
- /** - * @deprecated Since v4.11.0. Will be removed in v5.0.0. Use - * {@link `useConfigurationIf.tagMatchesPattern`} instead. - */ - ignorePattern: RegexOptionutils/make-newlines-between-fixes.ts (2)
165-171
: Fix EOL handling (CRLF gets split, yielding “\r\n\n” artifacts).The helpers assume LF only and use
indexOf('\n')
, which splits CRLF pairs and can produce mixed line endings on Windows. Preserve the file’s native EOL detected fromsourceCode.text
and use it consistently for insertions and normalization.Apply this diff:
@@ - let rangeReplacement = computeRangeReplacement({ + // Preserve file EOL style (LF vs CRLF) + let eol: '\n' | '\r\n' = sourceCode.text.includes('\r\n') ? '\r\n' : '\n' + + let rangeReplacement = computeRangeReplacement({ isOnSameLine: sortingNode.node.loc.end.line === nextSortingNode.node.loc.start.line, textBetweenNodes, newlinesBetween, + eol, }) @@ -function computeRangeReplacement({ - textBetweenNodes, - newlinesBetween, - isOnSameLine, -}: { - textBetweenNodes: string - newlinesBetween: number - isOnSameLine: boolean -}): undefined | string { - let textBetweenNodesWithoutInvalidNewlines = - getStringWithoutInvalidNewlines(textBetweenNodes) +function computeRangeReplacement({ + textBetweenNodes, + newlinesBetween, + isOnSameLine, + eol, +}: { + textBetweenNodes: string + newlinesBetween: number + isOnSameLine: boolean + eol: '\n' | '\r\n' +}): undefined | string { + let textBetweenNodesWithoutInvalidNewlines = + getStringWithoutInvalidNewlines(textBetweenNodes, eol) @@ - rangeReplacement = addNewlineBeforeFirstNewline(rangeReplacement) + rangeReplacement = addNewlineBeforeFirstNewline(rangeReplacement, eol) } if (!isOnSameLine) { return rangeReplacement } - return addNewlineBeforeFirstNewline(rangeReplacement) + return addNewlineBeforeFirstNewline(rangeReplacement, eol) } @@ -function addNewlineBeforeFirstNewline(value: string): string { - let firstNewlineIndex = value.indexOf('\n') +function addNewlineBeforeFirstNewline(value: string, eol: '\n' | '\r\n'): string { + let firstNewlineIndex = value.indexOf(eol) if (firstNewlineIndex === -1) { - return `${value}\n` + return `${value}${eol}` } - return `${value.slice(0, firstNewlineIndex)}\n${value.slice(firstNewlineIndex)}` + return `${value.slice(0, firstNewlineIndex)}${eol}${value.slice(firstNewlineIndex)}` } @@ -function getStringWithoutInvalidNewlines(value: string): string { - return value.replaceAll(/\n\s*\n/gu, '\n').replaceAll(/\n+/gu, '\n') +function getStringWithoutInvalidNewlines(value: string, eol: '\n' | '\r\n'): string { + // Collapse whitespace-only blank lines and multiple consecutive line breaks. + return value + .replace(/\r?\n[ \t]*\r?\n/gu, eol) + .replace(/(?:\r?\n){2,}/gu, eol) }Also applies to: 232-238, 249-251
103-121
: Map sortedNodes -> original indices before using nodes[i]; current indexing can produce wrong rangessortedNodes is the post‑sort ordering while nodes is the original order. The loop indexes both with i (computes semantics from sortedNodes but reads ranges from nodes.at(i)/nodes.at(i+1)), so when reordering occurs the pair used to compute newlines may not match the pair whose range is replaced.
- File: utils/make-newlines-between-fixes.ts (around lines 103–121) — stop using nodes.at(i)/nodes.at(i+1) directly.
- Fix: build an index map (use utils/create-node-index-map.ts), then for each sorted pair do:
- leftIdx = nodeIndexMap.get(sortedSortingNode)!, rightIdx = nodeIndexMap.get(nextSortedSortingNode)!
- derive sortingNode = nodes[Math.min(leftIdx, rightIdx)] and nextSortingNode = nodes[Math.max(leftIdx, rightIdx)]
- use those for getNodeRange/getLinesBetween and replacement.
- Add dev-only asserts (e.g., sortedNodes.length === nodes.length and nodeIndexMap.has(...)) and tests that cover reordered pairs.
♻️ Duplicate comments (19)
vite.config.ts (2)
10-12
: Fix: import.meta.dirname breaks on Node 20 — use ESM-safe __dirnameThis config will crash on Node 20. Replace import.meta.dirname with an ESM-safe __dirname shim.
Apply within this block:
- path.resolve(import.meta.dirname, 'index.ts'), - path.resolve(import.meta.dirname, 'utils', 'alphabet.ts'), + path.resolve(__dirname, 'index.ts'), + path.resolve(__dirname, 'utils', 'alphabet.ts'),Add near the imports (top of file):
import { fileURLToPath } from 'node:url' const __dirname = path.dirname(fileURLToPath(import.meta.url))
29-32
: Same issue in dts include — switch to __dirnameUse the same ESM-safe __dirname here to keep Node 20 support.
- path.join(import.meta.dirname, 'index.ts'), - path.join(import.meta.dirname, 'types'), - path.join(import.meta.dirname, 'rules'), - path.join(import.meta.dirname, 'utils'), + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'types'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'),rules/sort-array-includes.ts (1)
60-74
: Defaultgroups: ['literal']
changes behavior for spreads. Verify intent.With this default, spreads get sorted under the “unknown” bucket. If the intention is to keep unlisted selectors (like spreads) stable by default, ignore them during sorting.
Apply:
function sortNodesExcludingEslintDisabled( ignoreEslintDisabledNodes: boolean, ): SortArrayIncludesSortingNode[] { return formattedMembers.flatMap(nodes => sortNodesByGroups({ getOptionsByGroupIndex: buildGetCustomGroupOverriddenOptionsFunction(options), ignoreEslintDisabledNodes, + isNodeIgnored: node => + getGroupIndex(options.groups, node) === options.groups.length, groups: options.groups, nodes, }), ) }Note: ensure
getGroupIndex
is imported from the shared groups utility used elsewhere in the codebase.test/rules/sort-objects.test.ts (2)
4-4
: Replace untyped dedent with typed variant to silence typescript/no-unsafe-call.Use ts-dedent (or cast once) to avoid unsafe tagged template calls in tests.
-import dedent from 'dedent' +import dedent from 'ts-dedent'
3156-3161
: Same remarks as earlier blocks.These mirrored changes/tests repeat the patterns already reviewed above (array-based customGroups, group precedence, and newline controls). No additional issues spotted.
Also applies to: 4482-4511, 4565-4567, 4637-4657, 5923-5955, 7296-7325, 7380-7380, 7451-7472, 8543-8550
rules/sort-heritage-clauses.ts (1)
192-205
: Blocker: missing newlinesBetweenValueGetter breaks spacing diagnosticsreportAllErrors requires newlinesBetweenValueGetter to report missed/extra spacing. Tests rely on missedSpacingBetweenHeritageClauses/extraSpacingBetweenHeritageClauses. Add the getter.
import { reportAllErrors } from '../utils/report-all-errors' import { shouldPartition } from '../utils/should-partition' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', unexpectedOrder: 'unexpectedHeritageClausesOrder', }, sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sourceCode, options, context, nodes, })rules/sort-jsx-props.ts (1)
198-212
: Enable spacing diagnostics (missed/extra blank lines)Pass
newlinesBetweenValueGetter
soreportAllErrors
can enforcenewlinesBetween
for JSX props.+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenJSXPropsMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenJSXPropsMembers', unexpectedGroupOrder: 'unexpectedJSXPropsGroupOrder', unexpectedOrder: 'unexpectedJSXPropsOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(currentNodes), nodes: currentNodes, sourceCode, options, context, })docs/content/rules/sort-heritage-clauses.mdx (5)
148-159
: Fix terminology (decorators → heritage clauses) and make RegExpPattern.flags optional.Apply to keep consistent with types and other rule docs.
### partitionByComment <sub>default: `false`</sub> -Enables the use of comments to separate class decorators into logical groups. +Enables the use of comments to separate heritage clauses into logical groups. - `true` — All comments will be treated as delimiters, creating partitions. - `false` — Comments will not be used as delimiters. -- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. +- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters. - `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. -- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters. +- `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters.
168-176
: Document full newlinesBetween union and semantics.-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'ignore' | 'always' | 'never' | number`</sub> <sub>default: `'ignore'`</sub> Specifies how to handle newlines between groups. - `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups (equivalent to `0`). +- `number` — Require exactly this number of blank lines between groups.
265-273
: Unify CustomGroupDefinition typing (add 'custom'; proper fallbackSort; newlinesInside union).interface CustomGroupDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
280-291
: Mirror typing fixes in CustomGroupAnyOfDefinition and keep selector documented in anyOf.interface CustomGroupAnyOfDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }
295-303
: Document the selector attribute in Attributes.#### Attributes - `groupName` — The group's name, which needs to be put in the [`groups`](#groups) option. +- `selector` — (AnyOf only) AST selector to narrow matching elements for this group item. - `elementNamePattern` — If entered, will check that the name of the element matches the pattern entered. - `type` — Overrides the [`type`](#type) option for that custom group. `unsorted` will not sort the group. - `order` — Overrides the [`order`](#order) option for that custom group. - `fallbackSort` — Overrides the [`fallbackSort`](#fallbacksort) option for that custom group. - `newlinesInside` — Enforces a specific newline behavior between elements of the group.
rules/sort-jsx-props/types.ts (2)
106-111
: Selector JSDoc is stale; only 'prop' is allowed.Update to avoid misconfiguration.
- /** - * The selector type for this group. Can be 'prop' for regular props, - * 'multiline' for multi-line props, or 'shorthand' for shorthand props. - */ + /** + * Selector for this group. Allowed: 'prop' only. + * Use modifiers ('shorthand' | 'multiline') for specificity. + */
119-124
: Align Selector JSDoc with narrowed type.-/** - * Union type of all available JSX prop selectors. Used to categorize different - * types of JSX props. - */ +/** + * Selector for JSX props. Only 'prop' is supported; specificity via modifiers. + */test/rules/sort-imports.test.ts (1)
4310-4379
: Fix ESLint no-unsafe-call for dedent (same issue as before).Add a one-line local disable before each newly added tagged
dedent
call here to silence@typescript-eslint/no-unsafe-call
(or switch tots-dedent
later). Mirrors the earlier review around these lines.@@ - await valid({ - code: dedent` + await valid({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent` @@ - output: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + output: dedent` @@ - code: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent`test/rules/sort-jsx-props.test.ts (2)
259-260
: Consistent migration to 'multiline-prop'.Group ordering and error data reflect the new identifier; assertions read well.
Also applies to: 284-285
868-875
: Custom group descriptors: coverage is solid.Multiple variations (string/array/regex objects) are exercised; keeps schema compatibility tight.
Also applies to: 934-943, 971-999, 1079-1092, 1188-1199, 1240-1267
rules/sort-object-types.ts (2)
240-245
: Don’t assign required/optional to index signatures.Index signatures aren’t optional; pushing 'required' creates misleading groups (e.g., required-index-signature).
Apply:
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }
334-343
: Enable spacing diagnostics by passing a newline getter.reportAllErrors lacks newlinesBetweenValueGetter, so missed/extra blank-line messages won't surface when newlinesBetween is set.
Apply:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, availableMessageIds, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sourceCode, options, context, nodes, })
🧹 Nitpick comments (45)
vite.config.ts (2)
9-16
: Prefer named entry object for stable outputsUse an entry object for explicit names; it plays nicer with d.ts generation and fileName callbacks.
- entry: [ - path.resolve(__dirname, 'index.ts'), - path.resolve(__dirname, 'utils', 'alphabet.ts'), - ], + entry: { + index: path.resolve(__dirname, 'index.ts'), + alphabet: path.resolve(__dirname, 'utils', 'alphabet.ts'), + },
14-15
: ESM-only: drop unused namename is only used for UMD/IIFE; for formats: ['es'] it’s redundant.
- name: 'eslint-plugin-perfectionist',
rules/sort-object-types/types.ts (1)
167-182
: Remove leftover 'multiline' selector mapping from AllowedModifiersPerSelector.We no longer expose a 'multiline' selector; keeping it here is misleading.
[raise_ninor_issue]
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - /** Index signatures cannot have modifiers. */ 'index-signature': never }docs/content/rules/sort-array-includes.mdx (3)
4-4
: Nit: “includes” (plural)-shortDescription: Enforce sorted arrays before include method +shortDescription: Enforce sorted arrays before includes method
199-205
: Nit: grammar-Specifies the sorting locales. Refer To [String.prototype.localeCompare() - locales](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#locales). +Specifies the sorting locales. Refer to [String.prototype.localeCompare() - locales](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#locales).
489-493
: Fix test link path-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-array-includes.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-array-includes.test.ts)docs/content/rules/sort-objects.mdx (4)
278-286
: newlinesBetween type/docs mismatchDocs say type: number | 'ignore', but elsewhere (examples and tests in repo) accept 'never' | 'always' too. Update the type and bullets to include these string values to avoid confusion.
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `number | 'ignore' | 'never' | 'always'`</sub> ... -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'never'` or `0` — No newlines are allowed. +- `'always'` — Enforce one blank line between groups. +- Any other positive number — Enforce this number of newlines between each group, and forbid newlines inside groups.
436-439
: groups type should include inline newlinesBetween objectsExamples below place
{ newlinesBetween: ... }
between groups. Reflect that in the declared type.-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: number | 'ignore' | 'never' | 'always' }>` +</sub>
307-309
: [DEPRECATED] ignorePattern: make flags optional for consistencyOther pattern types on this page use
flags?: string
. Adjust here too (even though deprecated) to avoid needless breaking in TS examples.- string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] + string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
350-351
: useConfigurationIf.declarationCommentMatchesPattern: flags should be optionalAlign with elementNamePattern/elementValuePattern signatures.
- declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] + declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]rules/sort-named-exports.ts (1)
54-68
: Add missing default for useConfigurationIf for parity with other rulesOther rules set
useConfigurationIf: {}
in defaults. Including it here keeps behavior consistent and avoids undefined checks downstream.let defaultOptions: Required<Options[number]> = { fallbackSort: { type: 'unsorted' }, specialCharacters: 'keep', partitionByNewLine: false, partitionByComment: false, newlinesBetween: 'ignore', type: 'alphabetical', ignoreAlias: false, customGroups: [], ignoreCase: true, locales: 'en-US', alphabet: '', order: 'asc', groups: [], + useConfigurationIf: {}, }
test/rules/sort-named-imports.test.ts (1)
342-348
: Confirmed message IDs exist; optional: make 'unknown' explicit in tests
- Confirmed: message IDs are defined in rules/sort-named-imports.ts (lines 46–49) and mapped to error constants (lines 182–185, 219–222) — tests using 'unexpectedNamedImportsGroupOrder' are valid.
- Optional: change the test assertion to ['type-import','unknown'] for clarity; docs don't show an explicit "auto-append unknown" mention.
test/rules/sort-object-types.test.ts (3)
2210-2237
: Dual configuration with useConfigurationIf: allNamesMatchPatternGood demonstration of multiple configurations with selective matching. Consider adding one negative case where no config matches to assert fallback selection.
Also applies to: 4778-4806, 7289-7317
2370-2425
: New: declarationCommentMatchesPattern coverageGreat addition validating declaration comment matching. Consider adding a case with multiple leading comments where only one matches to confirm nearest/any precedence.
2100-2156
: Inline members fix output formattingEnsuring consistent semicolons/commas in “inline” object type members is good. If available, add one snapshot to guard against regressions in whitespace.
Also applies to: 4668-4724, 7179-7235
docs/content/rules/sort-jsx-props.mdx (2)
335-339
: Include newlinesBetween object in groups typeExamples include { newlinesBetween: ... } entries, but the declared type omits this union.
Apply this diff:
-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: number | 'ignore' }>` +</sub>
575-577
: Fix test source link pathTests live under test/rules. Update link to avoid 404.
Apply this diff:
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-jsx-props.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-jsx-props.test.ts)docs/content/rules/sort-interfaces.mdx (4)
371-383
: Regex example typo in declarationMatchesPattern'*Metadata$' is not a valid regex. Use '.*Metadata$' (or 'Metadata$') to match suffix “Metadata”.
Apply this diff:
- useConfigurationIf: { - declarationMatchesPattern: '*Metadata$', - }, + useConfigurationIf: { + declarationMatchesPattern: '.*Metadata$', + },
408-411
: Include newlinesBetween object in groups typeExamples show { newlinesBetween: ... } but the union isn’t in the declared type.
Apply this diff:
-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: number | 'ignore' }>` +</sub>
512-520
: Close the interface code blockThe second example is missing the closing brace, which breaks copy-paste.
Apply this diff:
// 'required-method' method(): string +}
765-766
: Fix test source link pathPoint to test/rules to match repo layout.
Apply this diff:
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-interfaces.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-interfaces.test.ts)test/rules/sort-named-exports.test.ts (2)
166-169
: Explicitly includeunknown
in groups for clarity (optional)Some tests rely on implicit
unknown
injection. Consider addinggroups: ['type-export', 'unknown']
here to avoid ambiguity across rules that don’t auto-appendunknown
.If you prefer implicit behavior, please confirm
unknown
is auto-added by the rule’s option resolution for sort-named-exports.
1537-1538
: Mirror earlier nit (optional)Same optional clarity nit: consider
groups: ['type-export', 'unknown']
.docs/content/rules/sort-object-types.mdx (3)
731-733
: Fix broken “Test source” link pathRepository path includes
test/rules/
. Update link to avoid 404.-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-object-types.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-object-types.test.ts)
335-343
: Correct regex example
'*Metadata$'
isn’t a valid regex; use'.*Metadata$'
.- declarationMatchesPattern: '*Metadata$', + declarationMatchesPattern: '.*Metadata$',
671-676
: Remove deprecatedignorePattern
from usage snippets (v5)PR goals say deprecated options are eliminated in v5. The usage block still shows
ignorePattern
. Suggest removing for consistency (do the same in the Legacy Config block below).- ignorePattern: [],
If
ignorePattern
is intentionally kept in v5 as deprecated-but-supported, keep it and add a deprecation note near the snippet.rules/sort-named-imports.ts (1)
165-176
: Enable spacing diagnostics by passing a newline getterWithout
newlinesBetweenValueGetter
,missed/extra
spacing messages won’t trigger. ImportgetLinesBetween
and pass it toreportAllErrors
.+import { getLinesBetween } from '../utils/get-lines-between' @@ - reportAllErrors<MessageId>({ + reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenNamedImports', extraSpacingBetweenMembers: 'extraSpacingBetweenNamedImports', unexpectedGroupOrder: 'unexpectedNamedImportsGroupOrder', unexpectedOrder: 'unexpectedNamedImportsOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled, sourceCode, options, context, nodes, })test/rules/sort-decorators.test.ts (3)
803-850
: Negative regex grouping — nice edge caseCovers negative lookahead well. Optional: add a case‑insensitive negative pattern to ensure flags are honored in exclusion paths too.
446-469
: Tiny wording nit in test fixtures: “Not a JSDoc comment”For readability, add a space in “a JSDoc”. No behavioral change.
Apply this diff:
- // Not aJSDoc comment + // Not a JSDoc commentAlso applies to: 2881-2903
1412-1531
: partitionByNewLine — canonical; fix doc/test spellingSchema, types, defaults and rule options use partitionByNewLine. Update human-readable/test strings that use 'partitionByNewline' (e.g. test/utils/validate-newlines-and-partition-configuration.test.ts) to 'partitionByNewLine' to avoid confusion.
docs/content/rules/sort-heritage-clauses.mdx (2)
185-189
: Extend groups type to allow inline newlinesBetween objects.Your examples use objects between groups; reflect in the declared type.
-<sub> - type: `Array<string | string[]>` -</sub> +<sub> + type: `Array<string | string[] | { newlinesBetween: 'ignore' | 'always' | 'never' | number }>` +</sub>
416-418
: Verify “Test source” link path.Repo seems to use test/rules/*.test.ts. Confirm the target exists or update the URL accordingly.
rules/sort-jsx-props/types.ts (1)
50-58
: Add partitionByComment to Options for parity with other sorting rules.If this rule supports partitions by comment like others, expose it in the type.
- /** Controls the placement of newlines between different groups of JSX props. */ + /** Controls the placement of newlines between different groups of JSX props. */ newlinesBetween: NewlinesBetweenOption + /** Partition props by comments (block/line/regex). */ + partitionByComment: PartitionByCommentOptionAnd add the import:
-import type { +import type { NewlinesBetweenOption, CustomGroupsOption, CommonOptions, GroupsOptions, RegexOption, + PartitionByCommentOption, } from '../../types/common-options'test/rules/sort-imports.test.ts (5)
1462-1475
: DRY up repeated customGroups fixtures.This A/B groups fixture repeats many times across suites. Extract a shared constant to reduce noise and review surface.
- customGroups: [ - { - groupName: 'unusedGroup', - elementNamePattern: 'X', - }, - { - elementNamePattern: 'a', - groupName: 'a', - }, - { - elementNamePattern: 'b', - groupName: 'b', - }, - ], + customGroups: AB_GROUPS_WITH_UNUSED,Add near the top of the file (or a test utils module):
const AB_GROUPS_WITH_UNUSED = [ { groupName: 'unusedGroup', elementNamePattern: 'X' }, { groupName: 'a', elementNamePattern: 'a' }, { groupName: 'b', elementNamePattern: 'b' }, ] as const
1613-1626
: Repeat of A/B groups fixture.Once a shared constant is introduced, replace this inline array too.
5105-5118
: Same A/B customGroups duplication in “natural”.Apply the shared fixture here as well.
11263-11308
: Huge customGroups matrix: consider a builder to cut repetition.Generating these regex-backed groups via a tiny helper (e.g.,
group('validators', '^~/validators/.+')
) will make additions safer and reduce copy/paste risk.Example helper:
const group = (name: string, pattern: string, modifiers: readonly ('type'|'value')[] = []) => ({ groupName: name, elementNamePattern: pattern, modifiers }) as const
11356-11426
: Large invalid case mirrors the valid one—good negative coverage.If refactoring with a builder, reuse it here to keep valid/invalid in lockstep.
test/rules/sort-jsx-props.test.ts (2)
329-336
: Good move to array-based customGroups.The shape matches the new schema (elementNamePattern + groupName). Consider adding one negative test with an unknown group in groups to assert the validator error path.
1242-1267
: useConfigurationIf cascade looks right.Two-option array verifies conditional config vs default. Consider one additional case where neither predicate matches to assert default rule behavior.
rules/sort-decorators.ts (2)
254-283
: Pass newline getter to unlock spacing diagnostics.As with other rules, reportAllErrors benefits from newlinesBetweenValueGetter for missed/extra blank-line messages.
Apply:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenDecorators', extraSpacingBetweenMembers: 'extraSpacingBetweenDecorators', unexpectedGroupOrder: 'unexpectedDecoratorsGroupOrder', unexpectedOrder: 'unexpectedDecoratorsOrder', }, ignoreFirstNodeHighestBlockComment: true, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled, sourceCode, options, context, nodes, })
141-156
: Parameter decorators detection: broaden coverage.The Identifier + FunctionExpression check may miss function declarations and constructor parameters. Recommend tests and minor broadening.
Add tests for:
- function declaration parameters
- class constructor parameters
If gaps appear, consider detecting decorator.parent kinds beyond Identifier in parameter positions.
utils/make-newlines-between-fixes.ts (3)
156-164
: Avoid.at(...)
here; use tuple indexing to prevent accidentalundefined
and implicit “start=0” slices.
.at(1)
on a tuple is typed asnumber | undefined
; passing that toslice
can silently coerce to0
. Index directly to express intent and keep types strict.- let nextNodeRangeStart = getNodeRange({ - node: nextSortingNode.node, - sourceCode, - }).at(0)! + let [nextNodeRangeStart] = getNodeRange({ + node: nextSortingNode.node, + sourceCode, + }) @@ - let rangeToReplace: [number, number] = [ - currentNodeRange.at(1)!, - nextNodeRangeStart, - ] - let textBetweenNodes = sourceCode.text.slice( - currentNodeRange.at(1), - nextNodeRangeStart, - ) + let rangeToReplace: [number, number] = [currentNodeRange[1], nextNodeRangeStart] + let textBetweenNodes = sourceCode.text.slice(currentNodeRange[1], nextNodeRangeStart)Also applies to: 142-146
28-31
: Docstring says “Optional custom groups” but the property is required.Align the comment to avoid confusion for integrators and maintainers.
- /** Optional custom groups configuration. */ - customGroups: CustomGroupsOption + /** Custom groups configuration (required). */ + customGroups: CustomGroupsOption
112-118
: Micro‑opt: avoid repeatedgetGroupIndex
calls in the loop.Precompute group indices for
sortedNodes
once and reuse. Small win, clearer intent.- for (let i = 0; i < sortedNodes.length - 1; i++) { + let groupIndexById = new Map(sortedNodes.map(n => [n.id, getGroupIndex(options.groups, n)])) + for (let i = 0; i < sortedNodes.length - 1; i++) { @@ - let nodeGroupIndex = getGroupIndex(options.groups, sortedSortingNode) - let nextNodeGroupIndex = getGroupIndex( - options.groups, - nextSortedSortingNode, - ) + let nodeGroupIndex = groupIndexById.get(sortedSortingNode.id)! + let nextNodeGroupIndex = groupIndexById.get(nextSortedSortingNode.id)!(Adjust the key if
SortingNode
uses a different stable identity.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (79)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(5 hunks)docs/content/rules/sort-imports.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(5 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)package.json
(4 hunks)rules/sort-array-includes.ts
(5 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-classes.ts
(1 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-enums.ts
(5 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-imports.ts
(6 hunks)rules/sort-imports/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(1 hunks)rules/sort-jsx-props.ts
(7 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-maps.ts
(3 hunks)rules/sort-modules.ts
(2 hunks)rules/sort-named-exports.ts
(2 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(2 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(10 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(3 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-objects.ts
(10 hunks)rules/sort-objects/types.ts
(5 hunks)rules/sort-switch-case.ts
(1 hunks)rules/sort-union-types.ts
(1 hunks)rules/sort-variable-declarations.ts
(1 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(2 hunks)test/rules/sort-enums.test.ts
(6 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(5 hunks)test/rules/sort-imports.test.ts
(25 hunks)test/rules/sort-interfaces.test.ts
(18 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(19 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(1 hunks)test/rules/sort-objects.test.ts
(31 hunks)test/rules/sort-sets.test.ts
(3 hunks)test/utils/compute-group.test.ts
(3 hunks)test/utils/filter-options-by-all-names-match.test.ts
(1 hunks)test/utils/filter-options-by-declaration-comment-matches.test.ts
(1 hunks)test/utils/get-custom-groups-compare-options.test.ts
(0 hunks)test/utils/get-matching-context-options.test.ts
(0 hunks)test/utils/get-newlines-between-option.test.ts
(4 hunks)types/common-options.ts
(0 hunks)utils/common-json-schemas.ts
(0 hunks)utils/compute-group.ts
(4 hunks)utils/filter-options-by-all-names-match.ts
(3 hunks)utils/filter-options-by-declaration-comment-matches.ts
(1 hunks)utils/get-comment-above-that-should-exist.ts
(2 hunks)utils/get-custom-groups-compare-options.ts
(2 hunks)utils/get-newlines-between-errors.ts
(1 hunks)utils/get-newlines-between-option.ts
(1 hunks)utils/make-comment-above-fixes.ts
(2 hunks)utils/make-fixes.ts
(2 hunks)utils/make-newlines-between-fixes.ts
(1 hunks)utils/report-all-errors.ts
(0 hunks)utils/validate-generated-groups-configuration.ts
(5 hunks)vite.config.ts
(1 hunks)
💤 Files with no reviewable changes (11)
- test/utils/get-matching-context-options.test.ts
- test/rules/sort-exports.test.ts
- docs/content/rules/sort-exports.mdx
- types/common-options.ts
- rules/sort-exports/types.ts
- utils/common-json-schemas.ts
- test/utils/get-custom-groups-compare-options.test.ts
- utils/report-all-errors.ts
- rules/sort-array-includes/types.ts
- docs/content/rules/sort-named-imports.mdx
- docs/content/rules/sort-named-exports.mdx
🚧 Files skipped from review as they are similar to previous changes (33)
- rules/sort-switch-case.ts
- rules/sort-classes.ts
- rules/sort-maps.ts
- rules/sort-named-exports/types.ts
- docs/content/rules/sort-imports.mdx
- utils/filter-options-by-declaration-comment-matches.ts
- rules/sort-variable-declarations.ts
- docs/content/rules/sort-intersection-types.mdx
- utils/get-custom-groups-compare-options.ts
- rules/sort-modules.ts
- test/utils/get-newlines-between-option.test.ts
- rules/sort-union-types.ts
- test/utils/filter-options-by-declaration-comment-matches.test.ts
- rules/sort-named-imports/types.ts
- rules/sort-interfaces.ts
- rules/sort-exports.ts
- rules/sort-decorators/types.ts
- test/utils/filter-options-by-all-names-match.test.ts
- rules/sort-intersection-types.ts
- rules/sort-imports/types.ts
- utils/make-comment-above-fixes.ts
- test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
- utils/get-newlines-between-errors.ts
- utils/compute-group.ts
- utils/make-fixes.ts
- utils/get-newlines-between-option.ts
- package.json
- utils/get-comment-above-that-should-exist.ts
- rules/sort-objects/types.ts
- rules/sort-objects.ts
- docs/content/rules/sort-decorators.mdx
- rules/sort-heritage-clauses/types.ts
- docs/content/rules/sort-sets.mdx
🧰 Additional context used
🧬 Code graph analysis (15)
test/rules/sort-imports.test.ts (1)
rules/sort-imports/types.ts (1)
Options
(29-141)
rules/sort-enums.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-enums/types.ts (1)
Options
(20-68)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)
rules/sort-named-exports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-exports/types.ts (2)
Options
(26-66)SortNamedExportsSortingNode
(95-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
utils/validate-generated-groups-configuration.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
rules/sort-named-imports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-imports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
utils/make-newlines-between-fixes.ts (1)
types/common-options.ts (2)
NewlinesBetweenOption
(203-226)CustomGroupsOption
(103-140)
rules/sort-object-types/types.ts (2)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-object-types.ts (5)
rules/sort-object-types/types.ts (4)
Options
(28-112)SortObjectTypesSortingNode
(386-394)Selector
(147-151)Modifier
(159-159)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)utils/matches.ts (1)
matches
(39-60)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)
rules/sort-array-includes.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (2)
Options
(24-68)Selector
(100-100)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-decorators.ts (7)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (3)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-imports.ts (8)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)rules/sort-imports/validate-side-effects-configuration.ts (1)
validateSideEffectsConfiguration
(19-48)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
rules/sort-jsx-props.ts (4)
rules/sort-jsx-props/types.ts (1)
Options
(24-71)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
rules/sort-heritage-clauses.ts (11)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-jsx-props/types.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
rules/sort-object-types/get-custom-groups-compare-options.ts (2)
rules/sort-interfaces.ts (1)
Options
(12-12)rules/sort-object-types/types.ts (1)
Options
(28-112)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
docs/content/rules/sort-objects.mdx (1)
559-566
: customGroups type still shows deprecated map shapeUpdate the documented type to the new array-based definitions.
-<sub> - type: `{ [groupName: string]: string | string[] }` -</sub> +<sub> + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>` +</sub>rules/sort-object-types/types.ts (2)
161-176
: Invalid selector map entry and contradictions for index-signature
AllowedModifiersPerSelector
includes amultiline
selector that doesn’t exist.- Declares
index-signature: never
but elsewhere allows modifiers for index-signature groups.Remove the phantom selector and keep index-signature with no modifiers.
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - /** Index signatures cannot have modifiers. */ 'index-signature': never }
219-227
: IndexSignatureGroup should not include modifiersIndex signatures don’t accept
optional/required/multiline
modifiers. Limit the group to the selector.-type IndexSignatureGroup = JoinWithDash< - [ - OptionalModifier, - RequiredModifier, - MultilineModifier, - IndexSignatureSelector, - ] -> +type IndexSignatureGroup = JoinWithDash<[IndexSignatureSelector]>
♻️ Duplicate comments (2)
rules/sort-jsx-props.ts (1)
189-202
: Enable spacing diagnostics (missed/extra blank lines).Pass
newlinesBetweenValueGetter
soreportAllErrors
can evaluate thenewlinesBetween
option for JSX props.+import { getLinesBetween } from '../utils/get-lines-between' @@ for (let currentNodes of formattedMembers) { @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenJSXPropsMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenJSXPropsMembers', unexpectedGroupOrder: 'unexpectedJSXPropsGroupOrder', unexpectedOrder: 'unexpectedJSXPropsOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(currentNodes), nodes: currentNodes, sourceCode, options, context, })rules/sort-object-types.ts (1)
328-336
: Add newlinesBetweenValueGetter for spacing diagnostics.The
reportAllErrors
call is missing thenewlinesBetweenValueGetter
parameter, which prevents detection of missed/extra blank-line errors whenoptions.newlinesBetween
is configured.Apply this fix:
+ import { getLinesBetween } from '../utils/get-lines-between' reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })
🧹 Nitpick comments (10)
docs/content/rules/sort-objects.mdx (1)
334-335
: Makeflags
optional to match RegexOption
flags
should be optional (flags?: string
) for consistency with other docs and types.- declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] + declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]rules/sort-object-types/types.ts (1)
331-336
: Prefer const for exported constantsUse
const
for arrays/schemas; avoids accidental reassignment.-export let allSelectors: Selector[] = [ +export const allSelectors: Selector[] = [ @@ -export let allModifiers: Modifier[] = ['optional', 'required', 'multiline'] +export const allModifiers: Modifier[] = ['optional', 'required', 'multiline'] @@ -export let sortByJsonSchema: JSONSchema4 = { +export const sortByJsonSchema: JSONSchema4 = { @@ -export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = {Also applies to: 343-343, 350-353, 365-371
docs/public/llms.txt (1)
13-13
: Update ESLint compatibility statementPR drops ESLint v8; revise to v9+ to avoid confusion.
-- Compatible with ESLint v8.45.0 or greater +- Compatible with ESLint v9.0.0 or greaterindex.ts (2)
71-71
: Use const for immutable plugin nameMinor tidy-up.
-let pluginName = 'perfectionist' +const pluginName = 'perfectionist'
73-101
: Avoid double assertion; use satisfies for stronger typingThis keeps type safety without
unknown
casts.-let plugin = { +const plugin = { rules: { // ... }, meta: { version: packageVersion, name: packageName, }, -} as unknown as ESLint.Plugin +} satisfies ESLint.Plugindocs/content/rules/sort-import-attributes.mdx (1)
33-39
: Fix line-length preview: show actual length-based orderFor shorter-first default, expected order is
mode
,type
,integrity
.lineLength={dedent` import data from 'lib' with { - integrity: 'sha256-...', - mode: 'no-cors', - type: 'json', + mode: 'no-cors', + type: 'json', + integrity: 'sha256-...', } `}test/rules/sort-import-attributes.test.ts (2)
821-829
: Consider using exact alphabet definition instead of dynamic generation.The test generates an alphabet dynamically using
Alphabet.generateRecommendedAlphabet().sortByLocaleCompare('en-US')
, which could lead to non-deterministic behavior if the alphabet generation logic changes. Consider using a fixed alphabet string for more predictable test behavior.- let alphabet = Alphabet.generateRecommendedAlphabet() - .sortByLocaleCompare('en-US') - .getCharacters() - - let options = { - type: 'custom', - order: 'asc', - alphabet, - } as const + let options = { + type: 'custom', + order: 'asc', + alphabet: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', // Or another appropriate fixed alphabet + } as const
957-974
: Brittle AST mutation test - document the purpose and consider alternatives.This test mutates the AST to simulate a literal key without a value, which is fragile and could break with parser updates. The test should clearly document why this edge case is important and what real-world scenario it represents.
Consider adding a comment explaining the purpose:
it('uses the attribute source when a literal key lacks value', async () => { + // This test simulates a parser edge case where a literal key's value is undefined + // This can occur with certain parser configurations or malformed code + // The rule should fall back to using the source text representation in such cases function removeLiteralValue(program: TSESTree.Program): void {Also consider if this edge case could be tested more reliably through a different approach, such as using a fixture file with actual malformed syntax that triggers this condition naturally.
test/rules/sort-object-types.test.ts (1)
2210-2238
: Consider consolidating RGB pattern test configurations.The test defines two separate configurations with
allNamesMatchPattern: 'foo'
and the actual RGB pattern. The 'foo' configuration appears to be a dummy that will never match. Consider documenting why this dummy configuration is needed or removing it if unnecessary.options: [ - { - ...options, - useConfigurationIf: { - allNamesMatchPattern: 'foo', - }, - }, { ...options, customGroups: [rules/sort-jsx-props/types.ts (1)
130-131
: Type alias could be more explicit about custom groups.The
Group
type allows any string, which correctly supports custom group names. The documentation could be enhanced to make this clearer./** * Represents a group identifier for JSX prop categorization. Can be a - * predefined group, 'unknown' for uncategorized props, or a custom group name. + * predefined group (e.g., 'shorthand-prop', 'multiline-prop'), 'unknown' for + * uncategorized props, or a custom group name defined via customGroups. */ type Group = PropertyGroup | 'unknown' | string
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
docs/content/rules/sort-import-attributes.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(4 hunks)docs/public/llms.txt
(1 hunks)index.ts
(3 hunks)readme.md
(1 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-import-attributes/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-object-types.ts
(9 hunks)rules/sort-object-types/types.ts
(3 hunks)test/rules/sort-import-attributes.test.ts
(1 hunks)test/rules/sort-interfaces.test.ts
(16 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-object-types.test.ts
(19 hunks)
✅ Files skipped from review due to trivial changes (1)
- readme.md
🚧 Files skipped from review as they are similar to previous changes (1)
- rules/sort-interfaces.ts
🧰 Additional context used
🧬 Code graph analysis (7)
rules/sort-import-attributes.ts (22)
rules/sort-imports.ts (1)
MessageId
(59-65)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-import-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-import-attributes/types.ts (3)
types/common-options.ts (6)
RegexOption
(477-477)CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)types/sorting-node.ts (1)
SortingNode
(18-102)
test/rules/sort-import-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-object-types.ts (3)
utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)
rules/sort-jsx-props.ts (4)
rules/sort-jsx-props/types.ts (1)
Options
(24-65)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
rules/sort-object-types/types.ts (3)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)rules/sort-objects/types.ts (1)
SingleCustomGroup
(128-144)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-object-types/types.ts (3)
SingleCustomGroup
(114-133)Selector
(141-145)allSelectors
(331-336)
🔇 Additional comments (41)
docs/content/rules/sort-objects.mdx (3)
353-366
: Good: array-based customGroups example aligns with new APIExample correctly shows
groupName
+elementNamePattern
.
398-416
: Good: clear example for declarationCommentMatchesPatternDocs and example are consistent.
752-754
: Broken test link pathTests live under
test/rules/…
now. Adjust link.-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-objects.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-objects.test.ts)rules/sort-object-types/types.ts (4)
35-40
: Addition of declarationCommentMatchesPattern looks goodOption shape matches RegexOption usage.
58-65
: Per‑group fallbackSort extension is reasonableTyping extension for
fallbackSort
withsortBy
is consistent with global option.
235-238
: PropertyGroup introduction is consistentMatches the other selector groups’ pattern.
380-389
: Sorting node shape LGTM
value
for type-annotation text is appropriate; nullable is correct.docs/public/llms.txt (2)
17-26
: Good: link hygiene to canonical docsUpdated URLs look correct.
30-50
: Good: new rule listed
sort-import-attributes
entry added consistently with others.index.ts (1)
6-6
: Rule wiring for sort-import-attributes is correctImport, typing, and rules map entry are all present.
Please confirm the file exists at
rules/sort-import-attributes.ts
and is exported as default.Also applies to: 31-31, 77-77
docs/content/rules/sort-import-attributes.mdx (2)
146-157
: newlinesBetween semantics clearly describedMatches rule behavior; no changes needed.
268-275
: Version and resources look rightIntro version and paths align with the new rule.
docs/content/rules/sort-jsx-props.mdx (1)
269-283
: LGTM! Clear migration from object to array-based customGroups API.The documentation clearly shows the migration path from the deprecated object-based API to the new array-based format, making it easy for users to update their configurations.
rules/sort-import-attributes/types.ts (1)
16-31
: Well-structured type definitions for import attributes sorting.The
SingleCustomGroup
interface and related types are well-documented with clear JSDoc comments explaining their purpose. The type definitions properly leverage existing common types and schemas from the codebase.test/rules/sort-object-types.test.ts (2)
252-253
: Good adaptation to new member-based terminology.The test correctly updates group names from
optional-multiline
tooptional-multiline-member
, maintaining consistency with the new naming convention across the codebase.Also applies to: 261-262
2370-2425
: Excellent test coverage for the new declarationCommentMatchesPattern feature.The test thoroughly validates that type declarations with matching comments can skip sorting, providing good coverage for both positive and negative cases.
docs/content/rules/sort-interfaces.mdx (2)
375-394
: Clear documentation for the new declarationCommentMatchesPattern option.The documentation provides a clear example showing how to skip sorting for interfaces with specific comments, which is a useful feature for gradual migration or special cases.
330-343
: LGTM! Clear array-based customGroups example.The RGB color sorting example effectively demonstrates the new array-based customGroups API with proper groupName and elementNamePattern properties.
test/rules/sort-interfaces.test.ts (2)
2320-2349
: LGTM! Clean migration to array-based customGroups.The test correctly demonstrates the new array-based API with
elementNamePattern
andgroupName
fields. The multi-configuration approach withallNamesMatchPattern
filtering is well-tested.
2442-2497
: Good addition: Test coverage for declaration comment matching.The new test validates the
declarationCommentMatchesPattern
filter, which is an important pattern-matching feature. The test properly demonstrates both matching and non-matching scenarios.rules/sort-import-attributes.ts (2)
39-44
: Consider using a dedicated type for import attributes message IDs.The
MessageId
type is locally defined but follows the same pattern as other rules. For consistency with the broader codebase, this is appropriate.
203-212
: LGTM! Robust attribute name extraction.The
getAttributeName
function properly handles both Identifier and Literal key types with a sensible fallback to source text.rules/sort-jsx-props/types.ts (1)
113-117
: LGTM! Documentation updated to reflect selector constraints.The JSDoc comment has been properly updated to reflect that only 'prop' is a valid selector, addressing the previous concern about stale documentation.
test/rules/sort-jsx-props.test.ts (11)
203-204
: LGTM! Consistent renaming of shorthand groups.The change from
'unknown', 'shorthand'
to'unknown', 'shorthand-prop'
properly aligns with the new naming convention for predefined groups.
224-225
: LGTM! Error data updated for new group names.The error expectations correctly reflect the renamed groups (
'shorthand-prop'
instead of'shorthand'
).
259-259
: LGTM! Multiline groups renamed consistently.The multiline options now use
'multiline-prop'
instead of'multiline'
, maintaining consistency with the new naming pattern.
284-285
: LGTM! Error data reflects multiline group renaming.The error expectations correctly use the new
'multiline-prop'
group name.
329-334
: LGTM! CustomGroups migrated to array-based API.The migration from object-based
customGroups
to array-basedGroupDefinition
objects is implemented correctly. The new structure withelementNamePattern
andgroupName
properties aligns with the ESM changes.
867-872
: LGTM! Multiple customGroups example updated.The test correctly demonstrates creating multiple custom groups using the array-based API.
1187-1199
: LGTM! Test preserves inline comments with new API.The test correctly uses the new array-based customGroups structure while validating comment preservation during reordering.
1239-1267
: LGTM! useConfigurationIf tests updated for new structure.The conditional configuration tests properly demonstrate the new array-based options structure with multiple configurations filtered by
useConfigurationIf
.
2866-2867
: LGTM! Line-length sort tests updated consistently.All line-length sorting tests correctly use the renamed groups (
shorthand-prop
,multiline-prop
) and the array-based customGroups API.Also applies to: 2922-2923, 2998-3005
4118-4133
: LGTM! Unsorted type tests properly migrated.The unsorted type tests correctly demonstrate the array-based customGroups structure while preserving element order within groups.
1538-1539
: Verify test coverage for all renamed groups.While the tests cover
shorthand-prop
andmultiline-prop
, ensure all predefined group renamings are tested across different sort types.Also applies to: 1594-1595, 1659-1672
rules/sort-object-types.ts (7)
67-82
: LGTM! Default options properly updated for array-based customGroups.The change from
customGroups: {}
tocustomGroups: []
correctly reflects the migration to array-based custom groups. The typing update toRequired<Options[number]>
is also appropriate.
94-95
: LGTM! JSON schema supports declarationCommentMatchesPattern.The addition of
declarationCommentMatchesPattern
to the schema enables comment-based configuration filtering.
98-101
: LGTM! CustomGroups schema migrated to array builder.The migration to
buildCustomGroupsArrayJsonSchema
with fallback sort properties aligns with the ESM changes.
125-126
: LGTM! Parent node tracking improved.Passing the actual parent node instead of just the name enables richer pattern matching and comment-based filtering.
177-182
: LGTM! Context matching logic extracted and enhanced.The new
computeMatchedContextOptions
helper centralizes option filtering logic and supports both name-based and comment-based matching.
197-293
: LGTM! Sorting logic refactored to 2D array approach.The refactoring from reduce-based formatting to a 2D array with explicit partition handling is cleaner and more maintainable. The logic correctly:
- Skips call and construct signatures
- Assigns appropriate selectors and modifiers
- Handles partitioning based on newlines/comments
- Builds sorting nodes with proper group assignment
382-426
: LGTM! Comprehensive context matching implementation.The
computeMatchedContextOptions
function properly implements the filtering pipeline:
- Filters by all names matching pattern
- Filters by declaration comment matching pattern
- Checks declaration name pattern
This enables flexible configuration selection based on multiple criteria.
reportAllErrors<MessageId>({ | ||
availableMessageIds: { | ||
missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', | ||
extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', | ||
unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', | ||
unexpectedOrder: 'unexpectedImportAttributesOrder', | ||
}, | ||
sortNodesExcludingEslintDisabled: | ||
createSortNodesExcludingEslintDisabled(nodes), | ||
sourceCode, | ||
options, | ||
context, | ||
nodes, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newlinesBetweenValueGetter in reportAllErrors call.
The reportAllErrors
call is missing the newlinesBetweenValueGetter
parameter, which will prevent spacing diagnostics from working correctly.
+import { getLinesBetween } from '../utils/get-lines-between'
@@
reportAllErrors<MessageId>({
availableMessageIds: {
missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes',
extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes',
unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder',
unexpectedOrder: 'unexpectedImportAttributesOrder',
},
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
sortNodesExcludingEslintDisabled:
createSortNodesExcludingEslintDisabled(nodes),
sourceCode,
options,
context,
nodes,
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', | |
unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', | |
unexpectedOrder: 'unexpectedImportAttributesOrder', | |
}, | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) | |
import { getLinesBetween } from '../utils/get-lines-between' | |
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', | |
unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', | |
unexpectedOrder: 'unexpectedImportAttributesOrder', | |
}, | |
newlinesBetweenValueGetter: (left, right) => | |
getLinesBetween(sourceCode, left, right), | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) |
🤖 Prompt for AI Agents
In rules/sort-import-attributes.ts around lines 149 to 162, the call to
reportAllErrors is missing the newlinesBetweenValueGetter parameter which
prevents spacing diagnostics from working; add the newlinesBetweenValueGetter
argument (the existing function/variable in this module that computes required
newlines between values) to the reportAllErrors call so it receives
newlinesBetweenValueGetter along with the other parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
docs/content/rules/sort-objects.mdx (1)
559-562
: Fix customGroups type: object map is deprecated in v5; docs should show array formThe section still documents the old object-map shape. Update the type to the new array-based API to avoid misconfiguration.
-<sub> - type: `{ [groupName: string]: string | string[] }` -</sub> +<sub> + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>` +</sub>docs/content/rules/sort-jsx-props.mdx (1)
303-307
: Invalid regex example: leading '*' is not validUse a proper wildcard.
- tagMatchesPattern: '*Component$', + tagMatchesPattern: '.*Component$',rules/sort-object-types/types.ts (2)
219-226
: Do not allow modifiers on index-signature in Group type.Index signatures can’t be optional/required/multiline; type should not synthesize such groups.
-type IndexSignatureGroup = JoinWithDash< - [ - OptionalModifier, - RequiredModifier, - MultilineModifier, - IndexSignatureSelector, - ] -> +type IndexSignatureGroup = 'index-signature'
171-176
: Remove stale 'multiline' selector entry from AllowedModifiersPerSelector.There’s no Multiline selector anymore; keeping it is misleading.
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier /** Index signatures cannot have modifiers. */ 'index-signature': never }test/rules/sort-interfaces.test.ts (1)
2589-2601
: Fix invalid index-signature syntax in testsReplace bare index-signature entries with a typed index signature — TypeScript requires a colon and type.
Locations: test/rules/sort-interfaces.test.ts — lines 2591, 2598, 5166, 5173
- [key: string] + [key: string]: stringtest/rules/sort-jsx-props.test.ts (1)
15-22
: Move parser to languageOptions.parser (not inside parserOptions).languageOptions.parser must be set to the parser itself (typescriptParser); it's currently nested inside languageOptions.parserOptions and will be ignored.
File: test/rules/sort-jsx-props.test.ts (createRuleTester languageOptions block).Apply:
- parserOptions: { - tsconfigRootDir: path.join(import.meta.dirname, '../fixtures'), - extraFileExtensions: ['.svelte', '.astro', '.vue'], - ecmaFeatures: { jsx: true }, - project: './tsconfig.json', - parser: typescriptParser, - }, + parser: typescriptParser, + parserOptions: { + tsconfigRootDir: path.join(import.meta.dirname, '../fixtures'), + extraFileExtensions: ['.svelte', '.astro', '.vue'], + ecmaFeatures: { jsx: true }, + project: './tsconfig.json', + },
♻️ Duplicate comments (4)
rules/sort-jsx-props/types.ts (1)
100-104
: Stale JSDoc: only 'prop' selector is supported; use modifiers for specificityThe comment still lists 'multiline'/'shorthand' as selectors, which contradicts the types/schema.
- /** - * The selector type for this group. Can be 'prop' for regular props, - * 'multiline' for multi-line props, or 'shorthand' for shorthand props. - */ + /** + * Selector for this group. Allowed: 'prop' only. + * Use modifiers ('shorthand' | 'multiline') to target those cases. + */rules/sort-object-types.ts (2)
234-238
: Don’t assign optional/required to index signatures.Index signatures aren’t optional/required; adding these modifiers creates misleading groups (e.g., required-index-signature).
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }
328-337
: Enable spacing diagnostics: pass newlinesBetweenValueGetter.Without it, missed/extra blank‑line messages won’t be reported when newlinesBetween is set.
import { reportAllErrors } from '../utils/report-all-errors' +import { getLinesBetween } from '../utils/get-lines-between' ... reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })rules/sort-import-attributes.ts (1)
149-162
: Missing newlinesBetweenValueGetter in reportAllErrors call.Based on the past review comments and the
reportAllErrors
function signature in the relevant code snippets, the call is missing thenewlinesBetweenValueGetter
parameter which is required for spacing diagnostics to work correctly.Looking at the
utils/report-all-errors.ts
code, the function expects anewlinesBetweenValueGetter
parameter. Add the missing parameter:+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', unexpectedOrder: 'unexpectedImportAttributesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, })
🧹 Nitpick comments (24)
docs/content/rules/sort-objects.mdx (2)
368-369
: Tighten regex example for allNamesMatchPatternUse a grouped alternation to match exactly r|g|b.
- allNamesMatchPattern: '^r|g|b$', + allNamesMatchPattern: '^(?:r|g|b)$',
235-235
: Minor copy: “Refer to”Lowercase “to”.
-Specifies the sorting locales. Refer To +Specifies the sorting locales. Refer torules/sort-jsx-props/types.ts (1)
146-153
: Prefer const over let for immutable tablesThese exports are constant lookup tables; make them const.
-export let allSelectors: Selector[] = ['prop'] +export const allSelectors: Selector[] = ['prop'] as const @@ -export let allModifiers: Modifier[] = ['shorthand', 'multiline'] +export const allModifiers: Modifier[] = ['shorthand', 'multiline'] as const @@ -export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = {Also applies to: 158-163
rules/sort-interfaces.ts (1)
20-20
: Use const for defaultOptionsAvoid accidental mutation.
-let defaultOptions: Required<Options[number]> = { +const defaultOptions: Required<Options[number]> = {test/rules/sort-object-types.test.ts (1)
2199-2206
: Regex precision: anchor the whole token with a grouped alternation'^r|g|b$' can match unintended names. Use '^(?:r|g|b)$' (and same for the case-insensitive variant).
- ['string pattern', '^r|g|b$'], + ['string pattern', '^(?:r|g|b)$'], @@ - ['regex pattern', { pattern: '^R|G|B$', flags: 'i' }], + ['regex pattern', { pattern: '^(?:R|G|B)$', flags: 'i' }],Repeat the same change in the natural and line-length suites.
Also applies to: 4767-4774, 7278-7285
docs/content/rules/sort-interfaces.mdx (2)
309-315
: Make flags optional in Regex-like option types (keep docs consistent with code).Docs show flags as required; types use optional flags. Update the type block.
{ - allNamesMatchPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - declarationMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] + allNamesMatchPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] + declarationMatchesPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] + declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
753-755
: Fix outdated test link path.Tests live under test/rules now.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-interfaces.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-interfaces.test.ts)rules/sort-object-types/types.ts (1)
35-40
: Nit: clarify wording (“comment content” rather than “names”).Docstring mentions “matching names”; consider “matching content” for comment patterns.
test/rules/sort-jsx-props.test.ts (2)
1231-1235
: Tighten regex alternation precedence.Patterns like "^r|g|b$" match more than intended (e.g., any string containing "g"). Prefer grouping.
Apply this diff in each occurrence:
- '^r|g|b$' + '^(?:r|g|b)$'Also applies to: 2566-2570, 3901-3905
15-16
: Prefer portable import.meta.url over non‑standard import.meta.dirname.import.meta.dirname isn’t standard Node ESM. Use fileURLToPath to derive a directory for cross‑runtime robustness.
+import { fileURLToPath } from 'node:url' +import { dirname } from 'node:path' ... - tsconfigRootDir: path.join(import.meta.dirname, '../fixtures'), + tsconfigRootDir: path.join( + dirname(fileURLToPath(import.meta.url)), + '../fixtures' + ),rules/sort-export-attributes.ts (4)
63-63
: Potential issue: Use more specific type check forattributes
The current check for
node.attributes
may not be sufficient. Consider checking ifattributes
exists and is an array to avoid potential runtime errors.- let attributes: TSESTree.ImportAttribute[] | undefined = node.attributes + let attributes = node.attributes as TSESTree.ImportAttribute[] | undefined
86-86
: Fix typo: "import" should be "export" in test commentThe comment references import attributes but this is for export attributes.
- let name = getAttributeName(attribute, sourceCode) + let name = getAttributeName(attribute, sourceCode)
133-147
: Consider extracting duplicate sorting logicThis pattern of creating
createSortNodesExcludingEslintDisabled
is identical to the one insort-import-attributes.ts
. Consider extracting this into a shared utility function to reduce duplication.Would you like me to help create a shared utility function for this pattern that both rules can use?
39-44
: Consider using a shared type for MessageIdThe MessageId type follows a similar pattern across sorting rules. Consider creating a shared type builder utility to maintain consistency.
test/rules/sort-import-attributes.test.ts (2)
25-25
: Inconsistent test descriptions across sorting modesTest descriptions use "sorts import attributes" for alphabetical/natural modes but "sorts import attributes" for others. Consider using consistent terminology like "sorts export attributes" throughout.
Also applies to: 276-276, 551-551, 831-831, 862-862
975-993
: Consider simplifying the custom parser wrapperThe parser wrapper could be simplified by extracting the common logic into a helper function.
- let parserWithMissingLiteralValue = { - ...typescriptParser, - parseForESLint( - code: string, - parserOptions?: Parameters<typeof typescriptParser.parseForESLint>[1], - ) { - let result = typescriptParser.parseForESLint(code, parserOptions) - removeLiteralValue(result.ast) - return result - }, - parse( - code: string, - parserOptions?: Parameters<typeof typescriptParser.parse>[1], - ) { - let program = typescriptParser.parse(code, parserOptions) - removeLiteralValue(program) - return program - }, - } + function wrapParser<T extends { ast?: TSESTree.Program } | TSESTree.Program>( + parseFn: (...args: any[]) => T, + ) { + return (...args: Parameters<typeof parseFn>) => { + let result = parseFn(...args) + let ast = 'ast' in result ? result.ast : result + if (ast) removeLiteralValue(ast) + return result + } + } + + let parserWithMissingLiteralValue = { + ...typescriptParser, + parseForESLint: wrapParser(typescriptParser.parseForESLint), + parse: wrapParser(typescriptParser.parse), + }test/rules/sort-export-attributes.test.ts (2)
25-25
: Fix test description: "import" should be "export"Test descriptions incorrectly refer to "import attributes" instead of "export attributes".
- it('sorts import attributes', async () => { + it('sorts export attributes', async () => {- it('sorts multiline import attributes', async () => { + it('sorts multiline export attributes', async () => {Apply similar changes to lines 276, 301, 551, 576, and 831.
Also applies to: 276-276, 551-551
959-973
: Consider extracting shared test utilitiesThe
removeLiteralValue
function and parser wrapping logic is duplicated fromsort-import-attributes.test.ts
. Consider extracting these into shared test utilities.Would you like me to help create a shared test utility module for these common testing patterns?
rules/sort-export-attributes/types.ts (6)
17-20
: Fix documentation comment - refers to wrong rule.The JSDoc comment states "Configuration for a single custom group in import attributes sorting" but this file is for export attributes, not import attributes.
/** - * Configuration for a single custom group in import attributes sorting. + * Configuration for a single custom group in export attributes sorting. * * Allows defining custom groups based on attribute name patterns. */
47-51
: Fix documentation comment - refers to wrong rule.The JSDoc comment mentions "import attributes" but this should refer to "export attributes" since this is the export attributes rule.
/** - * Custom groups for organizing import attributes. Allows defining groups - * based on attribute names and values. + * Custom groups for organizing export attributes. Allows defining groups + * based on attribute names and values. */
53-57
: Fix documentation comment - refers to wrong rule.The JSDoc comment mentions "import attributes" but should refer to "export attributes".
/** - * Partition import attributes by comment delimiters. Attributes separated - * by specific comments are sorted independently. + * Partition export attributes by comment delimiters. Attributes separated + * by specific comments are sorted independently. */
59-63
: Fix documentation comment - refers to wrong rule.The JSDoc comment mentions "import attributes" but should refer to "export attributes".
/** - * Controls the placement of newlines between different groups of import - * attributes. + * Controls the placement of newlines between different groups of export + * attributes. */
65-69
: Fix documentation comment - refers to wrong rule.The JSDoc comment mentions "import attributes" but should refer to "export attributes".
/** - * Defines the order and grouping of import attributes. Attributes are - * sorted within their groups and groups are ordered as specified. + * Defines the order and grouping of export attributes. Attributes are + * sorted within their groups and groups are ordered as specified. */
71-75
: Fix documentation comment - refers to wrong rule.The JSDoc comment mentions "import attributes" but should refer to "export attributes".
/** - * Whether to partition import attributes by newlines. When true, attributes - * separated by empty lines are sorted independently. + * Whether to partition export attributes by newlines. When true, attributes + * separated by empty lines are sorted independently. */
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (24)
docs/content/rules/sort-export-attributes.mdx
(1 hunks)docs/content/rules/sort-import-attributes.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(4 hunks)docs/public/llms.txt
(1 hunks)index.ts
(3 hunks)package.json
(4 hunks)readme.md
(1 hunks)rules/sort-export-attributes.ts
(1 hunks)rules/sort-export-attributes/types.ts
(1 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-import-attributes/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-object-types.ts
(9 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-switch-case.ts
(2 hunks)test/rules/sort-export-attributes.test.ts
(1 hunks)test/rules/sort-import-attributes.test.ts
(1 hunks)test/rules/sort-interfaces.test.ts
(16 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-object-types.test.ts
(19 hunks)
✅ Files skipped from review due to trivial changes (3)
- docs/content/rules/sort-export-attributes.mdx
- readme.md
- docs/public/llms.txt
🚧 Files skipped from review as they are similar to previous changes (2)
- rules/sort-switch-case.ts
- rules/sort-jsx-props.ts
🧰 Additional context used
🧬 Code graph analysis (10)
test/rules/sort-export-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-import-attributes/types.ts (3)
types/common-options.ts (6)
RegexOption
(477-477)CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)types/sorting-node.ts (1)
SortingNode
(18-102)
test/rules/sort-import-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-export-attributes/types.ts (3)
types/common-options.ts (6)
RegexOption
(477-477)CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)types/sorting-node.ts (1)
SortingNode
(18-102)
rules/sort-import-attributes.ts (19)
rules/sort-import-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-export-attributes.ts (21)
rules/sort-imports.ts (1)
MessageId
(59-65)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-export-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-object-types/types.ts (2)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-named-imports/types.ts (3)
SingleCustomGroup
(74-92)Selector
(109-109)allSelectors
(156-156)
rules/sort-object-types.ts (3)
utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-interfaces.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-jsx-props/types.ts (1)
Options
(24-65)
🔇 Additional comments (30)
rules/sort-jsx-props/types.ts (1)
48-49
: API shape LGTMcustomGroups now uses the shared CustomGroupsOption. Consistent with other rules.
rules/sort-interfaces.ts (2)
20-35
: Defaults updated to array-based API and added order/groups — looks goodMatches repo-wide changes (array customGroups, explicit order/groups).
48-50
: Passing parentNode and context — correctThe call now forwards parent node and context explicitly; aligns with sort-object-types API.
docs/content/rules/sort-jsx-props.mdx (1)
269-287
: Docs reflect array-based customGroups — goodExamples and usage now show customGroups: [] and per-group descriptors; consistent with v5 API.
Also applies to: 483-506, 522-535
docs/content/rules/sort-interfaces.mdx (2)
330-343
: customGroups migration example looks good.Array-based descriptors read clearly and match the new API surface.
Please confirm the JSON schema warns on the old object-map shape for this rule.
375-393
: Nice addition: declarationCommentMatchesPattern.Example is clear and aligns with “do not sort” use cases.
test/rules/sort-interfaces.test.ts (3)
2443-2497
: Coverage for declarationCommentMatchesPattern looks solid.Good positive/negative tests for the new matcher.
2321-2349
: allNamesMatchPattern with multi-config precedence: good scenarios.The RGB cases validate selector routing correctly.
Also applies to: 4953-4981, 7507-7535
552-584
: Confirm availability of the 'member' predefined group for sort-interfaces.Tests depend on 'member' being a valid group token. Ensure rule docs/types surface it consistently.
Also applies to: 586-618, 3184-3216, 3219-3250, 5745-5777, 5780-5811
rules/sort-object-types/types.ts (3)
35-40
: Add declarationCommentMatchesPattern: LGTM.Matches Options/useConfigurationIf across rules.
58-64
: customGroups AdditionalOptions shape: LGTM.Fallback sort extension per group is clear and typed.
228-238
: PropertyGroup introduction: LGTM.This aligns with removing the standalone multiline selector.
test/rules/sort-jsx-props.test.ts (2)
203-204
: Group id rename to shorthand-prop/multiline-prop looks correct.Updated group ids in both config and error data align with the new public API.
Also applies to: 224-226, 259-260, 284-286, 1538-1539, 1559-1561, 1594-1595, 1619-1623, 2866-2867, 2887-2891, 2922-2923, 2947-2951
329-335
: Migration to array-based customGroups is consistent.Use of elementNamePattern/elementValuePattern and anyOf mirrors the new schema; per‑group overrides exercised appropriately.
Also applies to: 867-872, 934-942, 971-997, 1079-1092, 1664-1671
rules/sort-object-types.ts (5)
98-102
: Good: customGroups JSON schema now uses the array builder.Matches the public API shift and keeps fallbackSort.sortBy supported.
93-96
: New conditional: declarationCommentMatchesPattern.Welcome addition; enables doc‑driven config switching.
67-77
: defaultOptions updates align with new Options[number] shape.Type and defaults (customGroups: []) look right.
382-426
: Context option selection helper is clear and deterministic.Filters by allNamesMatch and declaration comment, then checks declaration name. Good separation of concerns.
197-206
: Approve: core sorting pipeline refactor — helpers verified
- Skips call/construct signatures; uses predefined groups + custom matcher; partitions with shouldPartition and tracks partitionId; honors value-based sorting via isNodeIgnoredForGroup.
- Sanity check: exports present at utils/get-lines-between.ts, utils/should-partition.ts, utils/sort-nodes-by-groups.ts. No further issues spotted.
rules/sort-export-attributes.ts (1)
204-212
: LGTM! Helper function handles both key types effectivelyThe
getAttributeName
function correctly handles both Identifier and Literal key types, with a proper fallback to source text when the value is missing.index.ts (1)
6-7
: LGTM! New rules properly integratedThe new
sort-import-attributes
andsort-export-attributes
rules are correctly imported and registered in the plugin configuration.Also applies to: 31-32, 79-80
package.json (2)
14-14
: LGTM! ESM migration properly configuredThe conversion to ES modules with
"type": "module"
and the Node.js version requirement update (^20.0.0 || >=22.0.0) align well with the v5.0.0 breaking changes.Also applies to: 129-129
60-61
: Keep @typescript-eslint/types in dependencies — runtime exports are imported.Value imports found that require the package at runtime: utils/is-partition-comment.ts:3 (AST_TOKEN_TYPES), rules/sort-object-types/is-member-optional.ts:3 (AST_NODE_TYPES). Many other files use
import type
only, but because runtime exports are used, do not move the package to devDependencies.Likely an incorrect or invalid review comment.
test/rules/sort-import-attributes.test.ts (2)
959-973
: Excellent edge case testing!The test for handling missing literal values through AST manipulation is a clever way to ensure the rule handles edge cases gracefully.
1243-1244
: LGTM! Comprehensive test coverageThe test suite is thorough and covers all major scenarios including:
- Multiple sorting strategies
- Grouping and partitioning
- ESLint disable directives
- Edge cases with missing values
- Schema validation
test/rules/sort-export-attributes.test.ts (1)
950-955
: LGTM! JSON schema validation includedGood practice including JSON schema validation in the test suite.
docs/content/rules/sort-import-attributes.mdx (1)
1-274
: LGTM - Well-structured documentation for the new import attributes rule.The documentation is comprehensive and properly aligned with the new sort-import-attributes rule. Based on the web search results, import attributes are a new ECMAScript 2025 feature that "allows module import statements and dynamic imports to pass on more information alongside the module specifier" with syntax like
import json from "./foo.json" with { type: "json" }
. This documentation correctly captures the feature's purpose and configuration options.rules/sort-import-attributes/types.ts (1)
1-81
: LGTM - Consistent type definitions following established patterns.The type definitions properly follow the established patterns from other sorting rules in the codebase, with appropriate use of common options, custom groups, and JSON schema definitions. The interface structure aligns well with the type definitions used in
rules/sort-export-attributes/types.ts
.rules/sort-import-attributes.ts (2)
203-212
: LGTM - Proper attribute name extraction.The helper function correctly handles both
Identifier
and literal keys for import attributes, with appropriate fallback to source text. This aligns with the AST structure for import attributes.
60-201
: LGTM - Well-structured rule implementation following established patterns.The rule implementation follows the established patterns from other sorting rules in the codebase, with proper:
- Option validation and configuration
- ESLint disabled lines handling
- Partitioning logic
- Group computation and sorting
- JSON schema definition
The implementation properly integrates with the plugin's infrastructure and provides appropriate error messages for the four different scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
docs/content/rules/sort-objects.mdx (4)
413-415
: Type for groups is too narrow (example below uses an object).Docs show
{ newlinesBetween: 0 }
insidegroups
, but the declared type excludes it.- type: `Array<string | string[]>` + type: `Array<string | string[] | { newlinesBetween: number }>`
521-555
: customGroups “type” still shows the deprecated object-map shape.The section deprecates the map but the type line advertises it. Replace with the array form.
-<sub> - type: `{ [groupName: string]: string | string[] }` -</sub> -<sub>default: `[]`</sub> +<sub> + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>` +</sub> +<sub>default: `[]`</sub>
699-731
: Legacy Config block may conflict with “ESM-only” and ESLint v9 focus.If v5 drops ESLint v8, consider removing or clearly labeling this as pre-v5/v8-only to avoid confusion.
- { - source: dedent` - // .eslintrc.js - module.exports = { - plugins: [ - 'perfectionist', - ], - rules: { - 'perfectionist/sort-objects': [ - 'error', - { - ... - }, - ], - }, - } - `, - name: 'Legacy Config', - value: 'legacy', - }, + // (Optional) Include legacy config only if supporting ESLint v8 in this version.
744-746
: Fix broken Test source link in docsrules/sort-objects.ts exists; the docs link points to test/sort-objects.test.ts (missing). The actual test is at test/rules/sort-objects.test.ts on main — update docs/content/rules/sort-objects.mdx (lines 744–746) to point to that path.
🧹 Nitpick comments (5)
docs/content/rules/sort-objects.mdx (3)
166-167
: Minor wording nit: link text should say “groups”.Change “[grouping]” to “[groups]” to match the option name.
- - 'unsorted' — Do not sort items. [`grouping`](#groups) and [`newlines behavior`](#newlinesbetween) are still enforced. + - 'unsorted' — Do not sort items. [`groups`](#groups) and [`newlines behavior`](#newlinesbetween) are still enforced.
248-251
: Make RegExpPattern flags optional for consistency.Elsewhere flags are optional; keep it aligned here.
- - `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. + - `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters.
323-327
: Unify optionality of flags across patterns.Use
flags?: string
for all unions to match other sections and typical typing.- allNamesMatchPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - callingFunctionNamePattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] - declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[] + allNamesMatchPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] + callingFunctionNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] + declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]rules/sort-objects/types.ts (2)
148-155
: Selector union dropped ‘multiline’, but helper map/docs still reference it.
Selector
no longer includes'multiline'
, yetAllowedModifiersPerSelector
and its JSDoc still define a'multiline'
selector entry. Clean up to avoid confusion.Apply:
interface AllowedModifiersPerSelector { /** Property members can be multiline, optional, or required. */ property: MultilineModifier | OptionalModifier | RequiredModifier /** Generic members can be multiline, optional, or required. */ member: MultilineModifier | OptionalModifier | RequiredModifier /** Method members can be multiline, optional, or required. */ method: MultilineModifier | OptionalModifier | RequiredModifier - /** Multiline members can only be optional or required. */ - multiline: OptionalModifier | RequiredModifier - - /** Index signatures are not supported in regular objects. */ - 'index-signature': never }Also adjust the nearby comments to reflect that “multiline” is only a modifier, not a selector.
Also applies to: 162-177
290-310
: Make exported registries immutable to prevent accidental mutation.Use
const
for arrays/registry objects.-export let allSelectors: Selector[] = ['member', 'method', 'property'] +export const allSelectors: Selector[] = ['member', 'method', 'property'] -export let allModifiers: Modifier[] = ['optional', 'required', 'multiline'] +export const allModifiers: Modifier[] = ['optional', 'required', 'multiline'] -export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = {If you want extra safety: type them as
readonly
arrays orObject.freeze(...)
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
docs/content/rules/sort-objects.mdx
(4 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-objects/types.ts
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
rules/sort-objects/types.ts (1)
types/common-options.ts (2)
RegexOption
(477-477)CustomGroupsOption
(103-140)
rules/sort-objects.ts (5)
rules/sort-objects/types.ts (1)
Options
(25-114)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
🔇 Additional comments (18)
docs/content/rules/sort-objects.mdx (2)
510-519
: Cross-check: object in groups relies on the broader type.This example requires the widened
groups
type proposed above.
638-655
: Good illustrative example of array-based customGroups.Clear migration-friendly example; regexes and grouping look correct.
rules/sort-objects.ts (12)
27-27
: Import for declaration-comment filter: LGTM.This aligns with new useConfigurationIf.declarationCommentMatchesPattern support.
37-37
: Import for all-names-match filter: LGTM.Matches the new options flow.
98-103
: Switch to computeMatchedContextOptions: LGTM.Good consolidation of context resolution.
117-119
: Object declarations gate: LGTM.Early‑return is correct for non‑declaration contexts when disabled.
355-377
: Helper to exclude ESLint‑disabled nodes: LGTM.Clear separation before dependency sorting; no behavior regressions spotted.
439-441
: Top‑level customGroups schema: LGTM.Correct move to array schema via builder.
566-571
: Normalize callee text to reduce false positives in callingFunctionNamePattern.Use a stable name (Identifier or MemberExpression.property) before falling back to raw source.
[Suggest_recommended_refactor]See diff in the previous comment adding getCalleeName and swapping sourceCode.getText(...) for it.
575-613
: Variable/Property ancestor resolution: LGTM.Clean separation and safe name extraction for Identifier keys.
497-503
: Fix parent node chosen for declarationCommentMatchesPattern.When the nearest ancestor is a Property, you currently treat it as VariableDeclarator and hop to
.parent
(ObjectExpression), which skews comment matching. Use the actual ancestor kind.Apply:
- let parentNodeForDeclarationComment = null - if (objectParent) { - parentNodeForDeclarationComment = - objectParent.type === 'VariableDeclarator' - ? objectParent.node.parent - : objectParent.node - } + let parentNodeForDeclarationComment = + objectParent == null + ? null + : objectParent.type === 'VariableDeclarator' + ? objectParent.node.parent + : objectParent.node
532-573
: Preserve actual ancestor kind in getObjectParent (don’t label Property as VariableDeclarator).The current union and return path conflate Property with VariableDeclarator, causing downstream mis‑classification.
Apply:
-function getObjectParent({ +function getObjectParent({ onlyFirstParent, - sourceCode, + sourceCode, node, }: { node: TSESTree.ObjectExpression | TSESTree.ObjectPattern - sourceCode: TSESLint.SourceCode + sourceCode: TSESLint.SourceCode onlyFirstParent: boolean -}): - | { - node: TSESTree.VariableDeclarator | TSESTree.Property - type: 'VariableDeclarator' - name: string | null - } - | { - node: TSESTree.CallExpression - type: 'CallExpression' - name: string | null - } - | null { +}): + | { node: TSESTree.VariableDeclarator; type: 'VariableDeclarator'; name: string | null } + | { node: TSESTree.Property; type: 'Property'; name: string | null } + | { node: TSESTree.CallExpression; type: 'CallExpression'; name: string | null } + | null { let variableParent = getVariableParent({ onlyFirstParent, node }) if (variableParent) { - return { - type: 'VariableDeclarator', - name: variableParent.name, - node: variableParent.node, - } + return variableParent.node.type === TSESTree.AST_NODE_TYPES.VariableDeclarator + ? { + type: 'VariableDeclarator', + name: variableParent.name, + node: variableParent.node, + } + : { + type: 'Property', + name: variableParent.name, + node: variableParent.node, + } } let callParent = getFirstNodeParentWithType({ allowedTypes: [TSESTree.AST_NODE_TYPES.CallExpression], onlyFirstParent, node, }) if (callParent) { return { - name: sourceCode.getText(callParent.callee), + name: getCalleeName(callParent.callee) ?? sourceCode.getText(callParent.callee), type: 'CallExpression', node: callParent, } } return null } + +function getCalleeName(expr: TSESTree.Expression): string | null { + if (expr.type === 'Identifier') return expr.name + if ( + expr.type === 'MemberExpression' && + !expr.computed && + expr.property.type === 'Identifier' + ) { + return expr.property.name + } + return null +}
66-84
: Default options are consistent with documentation — no action required.customGroups: [], objectDeclarations: true, and the other defaults in rules/sort-objects.ts are reflected in docs/examples (docs/content/rules/sort-objects.mdx) and tests.
425-431
: No change required — buildUseConfigurationIfJsonSchema already includes allNamesMatchPattern.
buildUseConfigurationIfJsonSchema (utils/common-json-schemas.ts) defines allNamesMatchPattern: regexJsonSchema in its properties, so the additionalProperties in rules/sort-objects.ts do not need to repeat it.Likely an incorrect or invalid review comment.
rules/sort-objects/types.ts (4)
32-37
: Verify new conditional option is wired end‑to‑enddeclarationCommentMatchesPattern (rules/sort-objects/types.ts) was added — confirm:
- it's declared in the rule's meta.schema,
- it's parsed/merged during option resolution (option normalizer / useConfigurationIf),
- tests exist for positive and negative cases.
Run to help locate usages:
rg -n "declarationCommentMatchesPattern|useConfigurationIf" -C3 --hidden -g '!/dist/'
56-56
: Move to array-based customGroups acknowledged.Type switch to
CustomGroupsOption<SingleCustomGroup>
aligns with the new shared option model. Verify older shapes aren’t still accepted anywhere (to avoid silent config drift).
238-238
: Group union updated — double‑check for lingering multiline group strings.With
MultilineGroup
removed, audit tests/docs for tokens likemultiline-property
etc., and ensure schema forgroups
can’t accept them.
100-104
: Confirm intent: remove legacyignorePattern
or keep and documentDocs and commits mark
ignorePattern
as deprecated/dropped, yet it still appears in code and tests (rules/sort-objects/types.ts — ~line 104; rules/sort-objects.ts — schema/uses at ~lines 77/128/445; utils/get-settings.ts; test/rules/sort-objects.test.ts; docs/content/rules/sort-object-types.mdx).Action — pick one:
- Remove: delete
ignorePattern
from types, implementation, JSON schema and tests; add a migration note in docs/changelog.- Keep: remove the DEPRECATED marker from docs and add an explicit migration/compatibility note explaining why it remains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
index.ts (2)
75-98
: Make rules map immutable and type-checked.Use const and satisfies for safer types and to prevent accidental reassignment.
Apply:
-export let rules = { +export const rules = { 'sort-variable-declarations': sortVariableDeclarations, 'sort-intersection-types': sortIntersectionTypes, 'sort-import-attributes': sortImportAttributes, 'sort-export-attributes': sortExportAttributes, 'sort-heritage-clauses': sortHeritageClauses, 'sort-array-includes': sortArrayIncludes, 'sort-named-imports': sortNamedImports, 'sort-named-exports': sortNamedExports, 'sort-object-types': sortObjectTypes, 'sort-union-types': sortUnionTypes, 'sort-switch-case': sortSwitchCase, 'sort-decorators': sortDecorators, 'sort-interfaces': sortInterfaces, 'sort-jsx-props': sortJsxProps, 'sort-modules': sortModules, 'sort-classes': sortClasses, 'sort-imports': sortImports, 'sort-exports': sortExports, 'sort-objects': sortObjects, 'sort-enums': sortEnums, 'sort-sets': sortSets, 'sort-maps': sortMaps, -} +} satisfies Record<string, Rule.RuleModule>Optional: freeze to guard against mutation at runtime:
Object.freeze(rules)
105-105
: Prefer “satisfies” over double type assertion for plugin; simplify getRules usage.Avoid
as unknown as
and take advantage ofsatisfies
. Also, reference the localrules
map to remove the non-null assertion.Outside this hunk, consider:
const plugin = { meta: { version: packageVersion, name: packageName }, rules, } satisfies ESLint.Plugin // And in getRules: function getRules(options: BaseOptions): Linter.RulesRecord { return Object.fromEntries( Object.keys(rules).map(ruleName => [ `${pluginName}/${ruleName}`, ['error', options], ]), ) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
index.ts
(4 hunks)
🔇 Additional comments (3)
index.ts (3)
31-32
: PluginConfig interface updated with new rules — LGTM.
170-170
: Default export exposing configs — LGTM.
6-7
: New rule modules verified — default exports, tests, and docs are in place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (9)
package.json (1)
3-3
: Bump the package version for the v5.0.0 release.This release PR still publishes version 4.15.0. The release automation (changelogen tag, git tag, changelog text) and consumers will all misidentify the release unless package.json is set to 5.0.0.
docs/content/rules/sort-array-includes.mdx (1)
491-492
: Update Test source link to includerules/
Replace the test link so it points totest/rules/sort-array-includes.test.ts
:- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-array-includes.test.ts) + [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-array-includes.test.ts)docs/content/rules/sort-imports.mdx (1)
724-726
: Fix outdated “Test source” link path.Tests were migrated under test/rules; update the link.
Apply:
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-imports.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-imports.test.ts)test/rules/sort-jsx-props.test.ts (1)
13-22
: Set parser on languageOptions, not inside parserOptions.ESLint v9-style config expects
languageOptions.parser
. Current placement can fall back to Espree.Apply:
- languageOptions: { - parserOptions: { + languageOptions: { + parser: typescriptParser, + parserOptions: { tsconfigRootDir: path.join(import.meta.dirname, '../fixtures'), extraFileExtensions: ['.svelte', '.astro', '.vue'], ecmaFeatures: { jsx: true, }, project: './tsconfig.json', - parser: typescriptParser, }, },rules/sort-imports.ts (1)
356-371
: Enable spacing diagnostics for imports.Pass a
newlinesBetweenValueGetter
toreportAllErrors
so missed/extra blank lines are detected.Apply:
reportAllErrors<MessageId>({ @@ - sourceCode, - options, + sourceCode, + options, context, nodes, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), })Add import:
@@ import { complete } from '../utils/complete' +import { getLinesBetween } from '../utils/get-lines-between'
docs/content/rules/sort-interfaces.mdx (2)
365-366
: *Invalid regex example (‘Metadata$’)Leading “*” is not a valid JS regex. Use a proper pattern.
Apply:
- declarationMatchesPattern: '*Metadata$', + declarationMatchesPattern: '.*Metadata$',
753-755
: Fix test source link path
Update the Test source URL to reflect its new location under test/rules:- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-interfaces.test.ts) + [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-interfaces.test.ts)docs/content/rules/sort-object-types.mdx (2)
341-343
: *Invalid regex example (‘Metadata$’)Use a valid pattern.
Apply:
- declarationMatchesPattern: '*Metadata$', + declarationMatchesPattern: '.*Metadata$',
731-733
: Fix “Test source” link path
Update link to includerules/
directory:- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-object-types.test.ts) + [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-object-types.test.ts)
🧹 Nitpick comments (19)
docs/content/rules/sort-array-includes.mdx (2)
248-258
: Include 'always' and 'never' in newlinesBetween docsThe shared NewlinesBetweenOption supports 'always' and 'never'. Reflect that here for consistency.
Apply:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `number | 'ignore' | 'always' | 'never'`</sub> @@ -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `number` — Require exactly this number of blank lines between groups, and forbid newlines inside groups.As per common options.
4-4
: Fix typo: “includes” methodUse the correct method name in the short description.
-shortDescription: Enforce sorted arrays before include method +shortDescription: Enforce sorted arrays before includes methodrules/sort-export-attributes.ts (1)
203-212
: Deduplicate attribute name helper.getAttributeName likely duplicates logic with sort-import-attributes. Consider extracting to utils to keep behavior consistent.
rules/sort-object-types/types.ts (1)
161-176
: Remove unused “multiline” selector mapping.AllowedModifiersPerSelector includes a “multiline” selector key, but Selector doesn’t include 'multiline'. This mapping is unreachable and may confuse readers. Recommend removing that key.
rules/sort-named-exports/types.ts (1)
94-95
: Update JSDoc to reflect alias (no longer “Extended”)The node type is now a direct alias; the “Extended” wording is misleading.
-/** Extended sorting node for named export specifiers. */ +/** Sorting node for named export specifiers. */ export type SortNamedExportsSortingNode = SortingNode<TSESTree.ExportSpecifier>test/rules/sort-export-attributes.test.ts (2)
821-829
: Avoid heavy alphabet generation in testsAlphabet.generateRecommendedAlphabet().sortByLocaleCompare('en-US') builds and sorts ~131k code points; it can slow the suite. Cache once per file (const) or move to a shared test util computed once per run.
- let alphabet = Alphabet.generateRecommendedAlphabet() + const alphabet = Alphabet.generateRecommendedAlphabet() .sortByLocaleCompare('en-US') .getCharacters()
958-973
: Stronger AST guard when mutating attributesBe explicit about ExportNamedDeclaration to avoid accidental matches and tighten the type guard.
- function removeLiteralValue(program: TSESTree.Program): void { - for (let statement of program.body) { - if (!('attributes' in statement)) { - continue - } + function removeLiteralValue(program: TSESTree.Program): void { + for (let statement of program.body) { + if (statement.type !== 'ExportNamedDeclaration' || !statement.attributes) { + continue + }test/rules/sort-named-exports.test.ts (1)
4127-4136
: Avoid heavy alphabet generation per runSame perf note as other files: compute once (const) or share via a test util to reduce repeated ~131k sort cost.
- let alphabet = Alphabet.generateRecommendedAlphabet() + const alphabet = Alphabet.generateRecommendedAlphabet() .sortByLocaleCompare('en-US') .getCharacters()test/rules/sort-import-attributes.test.ts (1)
821-829
: Avoid heavy alphabet generation in testsCache or share the computed alphabet to speed up the suite; also prefer const.
- let alphabet = Alphabet.generateRecommendedAlphabet() + const alphabet = Alphabet.generateRecommendedAlphabet() .sortByLocaleCompare('en-US') .getCharacters()index.ts (3)
75-99
: Make rules immutable and type-checkedPrefer const + satisfies for safer public API and better DX.
-export let rules = { +export const rules = { 'sort-variable-declarations': sortVariableDeclarations, 'sort-intersection-types': sortIntersectionTypes, 'sort-import-attributes': sortImportAttributes, 'sort-export-attributes': sortExportAttributes, 'sort-heritage-clauses': sortHeritageClauses, 'sort-array-includes': sortArrayIncludes, 'sort-named-imports': sortNamedImports, 'sort-named-exports': sortNamedExports, 'sort-object-types': sortObjectTypes, 'sort-union-types': sortUnionTypes, 'sort-switch-case': sortSwitchCase, 'sort-decorators': sortDecorators, 'sort-interfaces': sortInterfaces, 'sort-jsx-props': sortJsxProps, 'sort-modules': sortModules, 'sort-classes': sortClasses, 'sort-imports': sortImports, 'sort-exports': sortExports, 'sort-objects': sortObjects, 'sort-enums': sortEnums, 'sort-sets': sortSets, 'sort-maps': sortMaps, -} +} satisfies PluginConfig['rules']
100-106
: Type plugin directly; avoid double assertionUse const and explicit type instead of “as unknown as”.
-let plugin = { +const plugin: ESLint.Plugin = { meta: { version: packageVersion, name: packageName, }, - rules, -} as unknown as ESLint.Plugin + rules, +}
108-115
: Remove non-null assertion by using rules map directlyNo need to go through plugin.rules!.
function getRules(options: BaseOptions): Linter.RulesRecord { return Object.fromEntries( - Object.keys(plugin.rules!).map(ruleName => [ + Object.keys(rules).map(ruleName => [ `${pluginName}/${ruleName}`, ['error', options], ]), ) }rules/sort-import-attributes.ts (1)
45-58
: Type consistency nit: prefer Options[number] over Options[0].Matches usage elsewhere (e.g., other rules) and is semantically clearer.
Apply:
-let defaultOptions: Required<Options[0]> = { +let defaultOptions: Required<Options[number]> = {test/rules/sort-imports.test.ts (2)
1462-1475
: Reduce repeated inline customGroups definitions in tests.The same patterns for a/b/c and larger suites are duplicated across many cases. Extracting tiny helpers will cut noise and ease future API shifts.
Example helper (place near top of file):
function cg(...defs: Array<{ name: string; pattern: string | string[] | {pattern:string;flags?:string} }>) { return defs.map(d => ({ groupName: d.name, elementNamePattern: d.pattern })); }Then, in tests:
- customGroups: [ - { groupName: 'a', elementNamePattern: 'a' }, - { groupName: 'b', elementNamePattern: 'b' }, - ] + customGroups: cg({ name: 'a', pattern: 'a' }, { name: 'b', pattern: 'b' })Also applies to: 1534-1551, 1613-1660, 5105-5118, 5176-5194, 5256-5269, 5290-5303, 7908-7917, 8762-8775, 8834-8851, 8914-8926, 8948-8960, 11094-11100, 11263-11308
2395-2395
: Restore spies after tsconfig-based mocks to avoid cross-test leakage.Several cases mock readClosestTsConfigByPath; ensure they’re restored, not just reset, to prevent overlapping spies in later tests.
Recommended:
- Prefer vi.restoreAllMocks() in after/afterEach when using vi.spyOn in before/beforeEach.
- Alternatively, add a suite-level afterEach(() => vi.restoreAllMocks()).
Example:
afterEach(() => { vi.restoreAllMocks() })If you want, I can sweep the file and open a patch to add restore hooks to the few cases that set up tsconfig mocks without a corresponding teardown.
Also applies to: 6057-6057, 9742-9742, 11618-11618, 11642-11642, 11666-11666, 11696-11696
docs/content/rules/sort-interfaces.mdx (1)
289-297
: Fix newlinesBetween type and bullets to match runtime APITests and types accept 'always' | 'never' in addition to number | 'ignore'. Please update the docs to prevent confusion.
Apply:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `number | 'ignore' | 'always' | 'never'`</sub> -Specifies how to handle newlines between groups. +Specifies how to handle newlines between groups. -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'always'` — Always require at least one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `0` — No newlines are allowed. +- Any other number — Enforce this exact number of blank lines between groups, and forbid newlines inside groups.As per common-options NewlinesBetweenOption. Based on learnings
docs/content/rules/sort-object-types.mdx (2)
264-272
: Fix newlinesBetween type and bullets to match runtime/tested APIDocs should list 'always' and 'never' as accepted values.
Apply:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `number | 'ignore' | 'always' | 'never'`</sub> -Specifies how to handle newlines between groups. +Specifies how to handle newlines between groups. -- `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'ignore'` — Do not report errors related to newlines. +- `'always'` — Always require at least one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `0` — No newlines are allowed. +- Any other number — Enforce this exact number of blank lines between groups, and forbid newlines inside groups.As per common-options NewlinesBetweenOption. Based on learnings
671-678
: Remove deprecated ignorePattern from usage examplesThe default config blocks still show ignorePattern, which is deprecated and removed elsewhere. Please drop it to avoid copy-paste confusion.
Apply:
- ignorePattern: [],
in both Flat and Legacy config snippets.
Also applies to: 704-711
rules/sort-decorators/types.ts (1)
39-41
: Consider freezing the JSON schema objectMinor: mark schema as readonly to avoid accidental mutation.
Apply:
-export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { - elementNamePattern: regexJsonSchema, -} +export const singleCustomGroupJsonSchema: Readonly<Record<string, JSONSchema4>> = { + elementNamePattern: regexJsonSchema, +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (67)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-export-attributes.mdx
(1 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(5 hunks)docs/content/rules/sort-import-attributes.mdx
(1 hunks)docs/content/rules/sort-imports.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(4 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)docs/public/llms.txt
(1 hunks)index.ts
(4 hunks)package.json
(4 hunks)readme.md
(1 hunks)rules/sort-array-includes.ts
(5 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-classes.ts
(1 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-enums.ts
(5 hunks)rules/sort-export-attributes.ts
(1 hunks)rules/sort-export-attributes/types.ts
(1 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-import-attributes/types.ts
(1 hunks)rules/sort-imports.ts
(6 hunks)rules/sort-imports/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(1 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-maps.ts
(3 hunks)rules/sort-modules.ts
(2 hunks)rules/sort-named-exports.ts
(2 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(2 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(9 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(3 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-objects/types.ts
(5 hunks)rules/sort-switch-case.ts
(2 hunks)rules/sort-union-types.ts
(1 hunks)rules/sort-variable-declarations.ts
(1 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(2 hunks)test/rules/sort-enums.test.ts
(6 hunks)test/rules/sort-export-attributes.test.ts
(1 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(5 hunks)test/rules/sort-import-attributes.test.ts
(1 hunks)test/rules/sort-imports.test.ts
(25 hunks)test/rules/sort-interfaces.test.ts
(16 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(19 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(1 hunks)
💤 Files with no reviewable changes (6)
- rules/sort-array-includes/types.ts
- docs/content/rules/sort-exports.mdx
- docs/content/rules/sort-named-exports.mdx
- docs/content/rules/sort-named-imports.mdx
- rules/sort-exports/types.ts
- test/rules/sort-exports.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/content/rules/sort-import-attributes.mdx
🚧 Files skipped from review as they are similar to previous changes (20)
- test/rules/sort-enums.test.ts
- docs/public/llms.txt
- rules/sort-union-types.ts
- rules/sort-modules.ts
- docs/content/rules/sort-sets.mdx
- rules/sort-interfaces.ts
- rules/sort-variable-declarations.ts
- rules/sort-switch-case.ts
- rules/sort-export-attributes/types.ts
- rules/sort-maps.ts
- docs/content/rules/sort-export-attributes.mdx
- rules/sort-classes.ts
- docs/content/rules/sort-intersection-types.mdx
- docs/content/rules/sort-jsx-props.mdx
- readme.md
- rules/sort-imports/types.ts
- rules/sort-import-attributes/types.ts
- test/rules/sort-named-imports.test.ts
- rules/sort-enums.ts
- docs/content/rules/sort-objects.mdx
🧰 Additional context used
🧬 Code graph analysis (25)
test/rules/sort-object-types/get-custom-groups-compare-options.test.ts (1)
rules/sort-object-types/types.ts (1)
Options
(28-106)
rules/sort-decorators/types.ts (3)
types/common-options.ts (6)
CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(477-477)types/sorting-node.ts (1)
SortingNode
(18-102)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)
rules/sort-array-includes.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (2)
Options
(24-68)Selector
(100-100)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-exports.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-exports/types.ts (1)
Options
(25-57)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-named-exports/types.ts (1)
types/sorting-node.ts (1)
SortingNode
(18-102)
rules/sort-named-imports.ts (4)
rules/sort-named-imports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-object-types.ts (4)
rules/sort-object-types/types.ts (1)
Options
(28-106)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-object-types/types.ts (2)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-objects/types.ts (1)
types/common-options.ts (2)
RegexOption
(477-477)CustomGroupsOption
(103-140)
rules/sort-named-exports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-exports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-heritage-clauses.ts (11)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-jsx-props.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-jsx-props/types.ts (1)
Options
(24-65)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
rules/sort-object-types/get-custom-groups-compare-options.ts (1)
rules/sort-object-types/types.ts (1)
Options
(28-106)
rules/sort-decorators.ts (6)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-heritage-clauses/types.ts (2)
types/common-options.ts (6)
CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(477-477)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-named-exports/types.ts (3)
SingleCustomGroup
(74-92)Selector
(109-109)allSelectors
(155-155)
rules/sort-intersection-types.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-union-types/types.ts (1)
Options
(22-54)
rules/sort-import-attributes.ts (20)
rules/sort-import-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-named-imports/types.ts (1)
types/sorting-node.ts (1)
SortingNode
(18-102)
test/rules/sort-import-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-export-attributes.ts (18)
rules/sort-export-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
test/rules/sort-export-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-imports.ts (7)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
test/rules/sort-imports.test.ts (1)
rules/sort-imports/types.ts (1)
Options
(29-141)
rules/sort-objects.ts (6)
rules/sort-objects/types.ts (1)
Options
(25-114)utils/common-json-schemas.ts (2)
regexJsonSchema
(219-228)buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
let nodes = formattedMembers.flat() | ||
reportAllErrors<MessageIds>({ | ||
sortNodesExcludingEslintDisabled, | ||
availableMessageIds, | ||
sourceCode, | ||
options, | ||
context, | ||
nodes, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enable spacing diagnostics: pass newlinesBetweenValueGetter.
Many tests assert spacing messages; without this getter, they’ll fail.
Apply:
+import { getLinesBetween } from '../utils/get-lines-between'
@@
let nodes = formattedMembers.flat()
reportAllErrors<MessageIds>({
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
sortNodesExcludingEslintDisabled,
availableMessageIds,
sourceCode,
options,
context,
nodes,
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
let nodes = formattedMembers.flat() | |
reportAllErrors<MessageIds>({ | |
sortNodesExcludingEslintDisabled, | |
availableMessageIds, | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) | |
// Add at the top of rules/sort-array-includes.ts | |
import { getLinesBetween } from '../utils/get-lines-between' | |
// … | |
let nodes = formattedMembers.flat() | |
reportAllErrors<MessageIds>({ | |
newlinesBetweenValueGetter: (left, right) => | |
getLinesBetween(sourceCode, left, right), | |
sortNodesExcludingEslintDisabled, | |
availableMessageIds, | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) |
🤖 Prompt for AI Agents
In rules/sort-array-includes.ts around lines 259 to 267, the call to
reportAllErrors is missing the newlinesBetweenValueGetter required for spacing
diagnostics; update the object passed to reportAllErrors to include
newlinesBetweenValueGetter (the existing function/value in this module) so
spacing messages are produced — e.g. add newlinesBetweenValueGetter:
newlinesBetweenValueGetter to the options passed to reportAllErrors.
it('sorts import attributes', async () => { | ||
await valid({ | ||
code: dedent` | ||
export { data } from 'module' with { a: 'a', b: 'b', c: 'c' } | ||
`, | ||
options: [options], | ||
}) | ||
|
||
await invalid({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix test titles: “import” → “export”
These cases exercise export attributes; the title is misleading.
- it('sorts import attributes', async () => {
+ it('sorts export attributes', async () => {
Consider updating similar titles throughout this file.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
it('sorts import attributes', async () => { | |
await valid({ | |
code: dedent` | |
export { data } from 'module' with { a: 'a', b: 'b', c: 'c' } | |
`, | |
options: [options], | |
}) | |
await invalid({ | |
it('sorts export attributes', async () => { | |
await valid({ | |
code: dedent` | |
export { data } from 'module' with { a: 'a', b: 'b', c: 'c' } | |
`, | |
options: [options], | |
}) | |
await invalid({ |
🤖 Prompt for AI Agents
In test/rules/sort-export-attributes.test.ts around lines 25 to 33, the test
title "sorts import attributes" is incorrect for cases that exercise export
attributes; update the string to "sorts export attributes". Also scan the rest
of this file for any other test titles that say "import" but test
export-attribute behavior and rename them similarly to "export" to keep titles
accurate and consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
docs/content/rules/sort-objects.mdx
(4 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-objects/types.ts
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
rules/sort-objects.ts (5)
rules/sort-objects/types.ts (1)
Options
(25-120)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
rules/sort-objects/types.ts (1)
types/common-options.ts (2)
RegexOption
(477-477)CustomGroupsOption
(103-140)
🔇 Additional comments (2)
docs/content/rules/sort-objects.mdx (1)
345-362
: Anchor the RGB pattern correctly.
'^r|g|b$'
still reads as “starts with r” OR “g” OR “ends with b”, so configs copied from here misbehave. Please wrap the alternation in a non-capturing group.- allNamesMatchPattern: '^r|g|b$', + allNamesMatchPattern: '^(?:r|g|b)$',rules/sort-objects.ts (1)
561-590
: Restore the parent kind discrimination ingetObjectParent
.When the object literal sits under a
Property
, we still fabricate{ type: 'VariableDeclarator' }
. As a resultdeclarationMatchesPattern
/declarationCommentMatchesPattern
treat nested properties as top-level declarations, so configs meant for real variable declarators unexpectedly match (e.g.{ config: { … } }
triggers a^config$
declaration filter). That is a regression from the old object-map logic and breaks opt-in filtering. Please return the actual parent kind.-function getObjectParent({ +function getObjectParent({ onlyFirstParent, sourceCode, node, }: { node: TSESTree.ObjectExpression | TSESTree.ObjectPattern sourceCode: TSESLint.SourceCode onlyFirstParent: boolean }): - | { - node: TSESTree.VariableDeclarator | TSESTree.Property - type: 'VariableDeclarator' - name: string | null - } + | { + node: TSESTree.VariableDeclarator + type: 'VariableDeclarator' + name: string | null + } + | { + node: TSESTree.Property + type: 'Property' + name: string | null + } | { node: TSESTree.CallExpression type: 'CallExpression' name: string | null } | null { let variableParent = getVariableParent({ onlyFirstParent, node }) if (variableParent) { - return { - type: 'VariableDeclarator', - name: variableParent.name, - node: variableParent.node, - } + return variableParent.node.type === TSESTree.AST_NODE_TYPES.VariableDeclarator + ? { + type: 'VariableDeclarator', + name: variableParent.name, + node: variableParent.node, + } + : { + type: 'Property', + name: variableParent.name, + node: variableParent.node, + } }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/content/rules/sort-enums.mdx (1)
409-411
: Update Test source link to the new path.The file lives under test/rules now.
-- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-enums.test.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/rules/sort-enums.test.ts)
🧹 Nitpick comments (5)
rules/sort-enums.ts (3)
57-71
: Use const for immutable defaults.defaultOptions is never reassigned; prefer const.
-let defaultOptions: Required<Options[number]> = { +const defaultOptions: Required<Options[number]> = {
110-118
: Capture dependencies from computed enum member access (Enum['A']).Currently only Identifier properties are collected. Add support for computed string-literal properties to avoid missing intra-enum edges.
- if ( - node.type === 'MemberExpression' && - node.object.type === 'Identifier' && - node.object.name === enumName && - node.property.type === 'Identifier' - ) { - dependencies.push(node.property.name) + if ( + node.type === 'MemberExpression' && + node.object.type === 'Identifier' && + node.object.name === enumName + ) { + if (!node.computed && node.property.type === 'Identifier') { + dependencies.push(node.property.name) + } else if (node.computed && node.property.type === 'Literal') { + if (typeof node.property.value !== 'undefined' && node.property.value !== null) { + dependencies.push(String(node.property.value)) + } + } } else if (node.type === 'Identifier') { dependencies.push(node.name) }
408-426
: Confirm intent: overriding type to 'natural' when sorting numeric enums by value.When isNumericEnum and sortByValue !== 'never', type is forced to 'natural', overriding user-specified 'type' (including 'unsorted'). If intended, consider an explicit note in docs and a test for type: 'unsorted' + ifNumericEnum.
Would you like me to add a test case covering:
- type: 'unsorted', sortByValue: 'ifNumericEnum' → numeric sort by value wins?
test/rules/sort-enums.test.ts (2)
1575-1591
: Great coverage for sortByValue semantics; consider adding an 'unsorted' type case.Add a case: type 'unsorted' + sortByValue 'ifNumericEnum' to assert value-based ordering still applies.
I can draft that test if helpful.
Also applies to: 3009-3050
4999-5005
: Minor consistency nit: test descriptions vs. options.The description says “sorts numeric enums by value when sortByValue is enabled” but uses 'always' (explicit). Consider a companion case for 'ifNumericEnum' in the same block for symmetry.
Also applies to: 5043-5049
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/content/rules/sort-enums.mdx
(3 hunks)rules/sort-enums.ts
(9 hunks)rules/sort-enums/types.ts
(1 hunks)test/rules/sort-enums.test.ts
(19 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
rules/sort-enums.ts (5)
rules/sort-enums/types.ts (1)
Options
(20-60)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/compare.ts (1)
NodeValueGetterFunction
(19-19)utils/unreachable-case-error.ts (1)
UnreachableCaseError
(31-43)types/common-options.ts (1)
TypeOption
(158-187)
🔇 Additional comments (8)
rules/sort-enums.ts (4)
338-365
: Node value getter logic looks solid and exhaustiveness is enforced.The switch correctly gates value-based sorting and uses UnreachableCaseError for safety. LGTM.
263-271
: Schema updates align with new customGroups array DSL and sortByValue enum.The JSON schema matches the new API surface. LGTM.
299-309
: Numeric expression evaluation: graceful null on unknowns and safe ops.Early null checks and handled operators are appropriate; defaults return null. LGTM.
Also applies to: 331-335, 367-385, 391-405
144-148
: Normalize enum member names to string (prevents dependency/group mismatches).member.id.value can be non-string for literal names. Convert at the source so elementName, dependencyNames, and custom-group matching stay string-typed and consistent.
- let name = - member.id.type === 'Literal' - ? member.id.value - : sourceCode.getText(member.id) + const name = + member.id.type === 'Literal' + ? String(member.id.value) + : sourceCode.getText(member.id)Also applies to: 175-180
test/rules/sort-enums.test.ts (4)
66-74
: Switch to string-literal enum keys: looks good.Test updates reflect string-literal member names and align with rule behavior. LGTM.
Also applies to: 90-104, 1647-1651, 1667-1680, 3206-3239
4923-4945
: Potential duplicate enum member name ('m').Two members named 'm' may be parser-accepted but are illegal in TS. If the parser allows it, fine; otherwise this test could fail on some setups.
Would you like me to rewrite with unique keys while preserving the numeric-expression coverage?
5280-5313
: Disable-comment scenarios: strong coverage.Good validation of interaction between rule fixes and eslint-disable lines/blocks.
Also applies to: 5710-5791, 5907-5940
5316-5347
: Partition vs. dependency precedence test is valuable.Confirms dependencies override partitions. Nicely scoped.
When this setting is `true`, numeric enums will have their values sorted numerically regardless of the `type` setting. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix wording: sortByValue is not boolean.
“When this setting is true” is outdated. Clarify behavior for 'always' and 'ifNumericEnum'.
-When this setting is `true`, numeric enums will have their values sorted numerically regardless of the `type` setting.
+When set to "always", members are sorted by their values. When set to "ifNumericEnum", members are sorted by their values only if the enum is numeric; otherwise names are used, regardless of the `type` setting.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
When this setting is `true`, numeric enums will have their values sorted numerically regardless of the `type` setting. | |
When set to "always", members are sorted by their values. When set to "ifNumericEnum", members are sorted by their values only if the enum is numeric; otherwise names are used, regardless of the `type` setting. |
🤖 Prompt for AI Agents
In docs/content/rules/sort-enums.mdx around lines 181 to 182, update the
sentence that currently reads "When this setting is `true`, numeric enums will
have their values sorted numerically regardless of the `type` setting." because
sortByValue is not boolean; replace it with wording that explains the two valid
options, e.g. state that when sortByValue is "always" enum values are always
sorted numerically, and when it's "ifNumericEnum" numeric enums are sorted
numerically but non-numeric enums are unaffected, making the behavior with
respect to the `type` setting explicit.
rules/sort-enums/types.ts
Outdated
/** | ||
* Whether to sort enum members by their values instead of names. When true, | ||
* compares enum values; when false, compares enum member names. | ||
* | ||
* @default ifNumericEnum | ||
*/ | ||
sortByValue: 'ifNumericEnum' | 'always' | 'never' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the JSDoc to reflect the new string-valued option.
The description still talks about a boolean toggle (“When true/false”), but sortByValue
now exposes 'ifNumericEnum' | 'always' | 'never'
. The generated docs (and consumers reading the types) will be wrong unless we document what each literal means and when to use it. Please update the block accordingly.
- /**
- * Whether to sort enum members by their values instead of names. When true,
- * compares enum values; when false, compares enum member names.
- *
- * @default ifNumericEnum
- */
- sortByValue: 'ifNumericEnum' | 'always' | 'never'
+ /**
+ * Controls when enum members should be ordered by their values instead of names.
+ * - `'always'` compares enum member values for every enum.
+ * - `'never'` keeps name-based ordering regardless of values.
+ * - `'ifNumericEnum'` sorts by value only when every member has a numeric initializer.
+ *
+ * @default ifNumericEnum
+ */
+ sortByValue: 'ifNumericEnum' | 'always' | 'never'
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
/** | |
* Whether to sort enum members by their values instead of names. When true, | |
* compares enum values; when false, compares enum member names. | |
* | |
* @default ifNumericEnum | |
*/ | |
sortByValue: 'ifNumericEnum' | 'always' | 'never' | |
/** | |
* Controls when enum members should be ordered by their values instead of names. | |
* - `'always'` compares enum member values for every enum. | |
* - `'never'` keeps name-based ordering regardless of values. | |
* - `'ifNumericEnum'` sorts by value only when every member has a numeric initializer. | |
* | |
* @default ifNumericEnum | |
*/ | |
sortByValue: 'ifNumericEnum' | 'always' | 'never' |
🤖 Prompt for AI Agents
In rules/sort-enums/types.ts around lines 28 to 35, the JSDoc still describes a
boolean toggle but the type is now a string union; update the comment to remove
"When true/false" language and instead document each allowed literal
('ifNumericEnum' | 'always' | 'never') with a one-line explanation for each
(e.g., 'ifNumericEnum' = sort by value only for numeric enums, 'always' = always
sort by value, 'never' = never sort by value), and include the default behavior
(i.e., @default ifNumericEnum) so generated docs and type consumers correctly
understand the new options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
rules/sort-objects.ts (1)
27-394
: Spacing diagnostics missingThis refactor drops the
newlinesBetweenValueGetter
you previously had wired intoreportAllErrors
, so the rule no longer reports newline/spacing violations. Restore it (and importgetLinesBetween
) to keep spacing enforcement alive.-import { - filterOptionsByDeclarationCommentMatches -} from '../utils/filter-options-by-declaration-comment-matches' +import { + filterOptionsByDeclarationCommentMatches +} from '../utils/filter-options-by-declaration-comment-matches' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenObjectMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenObjectMembers', unexpectedDependencyOrder: 'unexpectedObjectsDependencyOrder', unexpectedGroupOrder: 'unexpectedObjectsGroupOrder', unexpectedOrder: 'unexpectedObjectsOrder', }, sortNodesExcludingEslintDisabled, sourceCode, options, context, - nodes, + nodes, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), })test/rules/sort-array-includes.test.ts (3)
1183-1196
: Fix spread element quoted as a string ('...foo').'...foo' is a string literal; should be a spread element to match selector 'spread'. Update both output and code.
Apply:
@@ - [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value) @@ - [ - 'a', - '...foo', - 'cFoo', - ].includes(value) + [ + 'a', + ...foo, + 'cFoo', + ].includes(value)Also applies to: 1190-1196
2979-2993
: Same issue: spread element quoted as string in “natural/anyOf”.Replace string '...foo' with spread ...foo in output and code.
Apply:
@@ - [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value) @@ - [ - 'a', - '...foo', - 'cFoo', - ].includes(value) + [ + 'a', + ...foo, + 'cFoo', + ].includes(value)Also applies to: 2986-2993
4756-4768
: Same issue: spread element quoted as string in “line-length/anyOf”.Replace string '...foo' with spread ...foo.
Apply:
@@ - [ - '...foo', - 'cFoo', - 'a', - ].includes(value) + [ + ...foo, + 'cFoo', + 'a', + ].includes(value) @@ - [ - 'a', - '...foo', - 'cFoo', - ].includes(value) + [ + 'a', + ...foo, + 'cFoo', + ].includes(value)Also applies to: 4763-4768
rules/sort-object-types.ts (1)
115-129
: Missing TSInterfaceBody visitor for interface support.The rule currently only visits
TSTypeLiteral
nodes (type aliases). A past review comment suggested adding aTSInterfaceBody
visitor to also sort interface members, and was marked as addressed. However, noTSInterfaceBody
visitor is present in the current code.If interface support is intended, add the missing visitor:
TSTypeLiteral: node => sortObjectTypeElements<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenObjectTypeMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenObjectTypeMembers', unexpectedGroupOrder: 'unexpectedObjectTypesGroupOrder', unexpectedOrder: 'unexpectedObjectTypesOrder', }, parentNode: node.parent.type === 'TSTypeAliasDeclaration' ? node.parent : null, elements: node.members, context, }), + TSInterfaceBody: node => + sortObjectTypeElements<MessageId>({ + availableMessageIds: { + missedSpacingBetweenMembers: 'missedSpacingBetweenObjectTypeMembers', + extraSpacingBetweenMembers: 'extraSpacingBetweenObjectTypeMembers', + unexpectedGroupOrder: 'unexpectedObjectTypesGroupOrder', + unexpectedOrder: 'unexpectedObjectTypesOrder', + }, + parentNode: + node.parent?.type === 'TSInterfaceDeclaration' ? node.parent : null, + elements: node.body, + context, + }), }),
♻️ Duplicate comments (17)
rules/sort-named-imports/types.ts (1)
94-95
: Fix the node type in SortNamedImportsSortingNode.The type uses
TSESTree.ImportClause
but sorting nodes are built fromTSESTree.ImportSpecifier
(seerules/sort-named-imports.ts:136
wherenode: specifier
is assigned and specifier is filtered bytype === 'ImportSpecifier'
).Apply this fix:
-/** Extended sorting node for named import specifiers. */ -export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportClause> +/** Extended sorting node for named import specifiers. */ +export type SortNamedImportsSortingNode = SortingNode<TSESTree.ImportSpecifier>docs/content/rules/sort-decorators.mdx (3)
255-262
: Document the full newlinesBetween type union.The type annotation shows only
number | 'ignore'
, but the implementation and tests support'always'
and'never'
as well. Update the type annotation and bullet descriptions to include all valid values.Apply this diff:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'always' | 'never' | number | 'ignore'`</sub> <sub>default: `'ignore'`</sub> Specifies how to handle newlines between groups. - `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `number` — Require exactly this number of blank lines between groups; forbid blank lines inside groups.
352-359
: Correct CustomGroupDefinition type annotations.The
fallbackSort.type
should be a specific union (notstring
), andnewlinesInside
should accept'always' | 'never' | number
to match the implementation.Apply this diff:
interface CustomGroupDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
367-378
: Correct CustomGroupAnyOfDefinition type annotations.Same issues as
CustomGroupDefinition
:fallbackSort.type
should be a specific union, andnewlinesInside
should accept'always' | 'never' | number
.Apply this diff:
interface CustomGroupAnyOfDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }docs/content/rules/sort-heritage-clauses.mdx (5)
152-159
: Fix terminology and optional flags in RegExpPattern.The documentation incorrectly references "class decorators" (should be "heritage clauses"), and
flags
should be optional in theRegExpPattern
type definition to match the actual interface.Apply this diff:
-Enables the use of comments to separate class decorators into logical groups. +Enables the use of comments to separate heritage clauses into logical groups. - `true` — All comments will be treated as delimiters, creating partitions. - `false` — Comments will not be used as delimiters. -- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. +- `RegExpPattern = string | { pattern: string; flags?: string }` — A regexp pattern to specify which comments should act as delimiters. - `RegExpPattern[]` — A list of regexp patterns to specify which comments should act as delimiters. - `{ block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` — Specify which block and line comments should act as delimiters.
168-176
: Document full newlinesBetween type union.The type annotation shows only
number | 'ignore'
, but should include'always'
and'never'
to match the implementation.Apply this diff:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'always' | 'never' | number | 'ignore'`</sub> <sub>default: `'ignore'`</sub> Specifies how to handle newlines between groups. - `'ignore'` — Do not report errors related to newlines. -- `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. +- `number` — Require exactly this number of blank lines between groups; forbid blank lines inside groups.
265-273
: Correct CustomGroupDefinition type annotations.Include
'custom'
in thetype
union, use a specific union forfallbackSort.type
(notstring
), and expandnewlinesInside
to accept'always' | 'never' | number
.Apply this diff:
interface CustomGroupDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
280-291
: Correct CustomGroupAnyOfDefinition type annotations.Same issues as
CustomGroupDefinition
: include'custom'
intype
, use a specific union forfallbackSort.type
, and expandnewlinesInside
.Apply this diff:
interface CustomGroupAnyOfDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }
295-302
: Document the 'selector' attribute.The
CustomGroupAnyOfDefinition
interface includes aselector?
field in theanyOf
items, but it's not documented in the Attributes section.Apply this diff:
#### Attributes - `groupName` — The group's name, which needs to be put in the [`groups`](#groups) option. +- `selector` — (AnyOf only) AST selector to narrow matching elements for this group item. - `elementNamePattern` — If entered, will check that the name of the element matches the pattern entered. - `type` — Overrides the [`type`](#type) option for that custom group. `unsorted` will not sort the group. - `order` — Overrides the [`order`](#order) option for that custom group. - `fallbackSort` — Overrides the [`fallbackSort`](#fallbacksort) option for that custom group. - `newlinesInside` — Enforces a specific newline behavior between elements of the group.
rules/sort-heritage-clauses.ts (1)
193-205
: Still missingnewlinesBetweenValueGetter
.We now emit spacing message IDs but the
reportAllErrors
call still omitsnewlinesBetweenValueGetter
. Without it, spacing violations are never detected, so the new messages will never fire. Please wire it back in and importgetLinesBetween
.import { reportAllErrors } from '../utils/report-all-errors' +import { getLinesBetween } from '../utils/get-lines-between' @@ - reportAllErrors<MessageId>({ + reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', unexpectedOrder: 'unexpectedHeritageClausesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, })rules/sort-array-includes.ts (1)
33-267
: Spacing diagnostics still disabled
reportAllErrors
can’t emit newline/spacing violations without anewlinesBetweenValueGetter
. That omission was raised earlier and remains unresolved, so spacing regressions will slip past linting. Please wire it back in.@@ -import { - filterOptionsByAllNamesMatch -} from '../utils/filter-options-by-all-names-match' +import { + filterOptionsByAllNamesMatch +} from '../utils/filter-options-by-all-names-match' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, availableMessageIds, sourceCode, options, context, - nodes, + nodes, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), })test/rules/sort-imports.test.ts (1)
4311-4316
: Fix ESLint no-unsafe-call on dedent (repeat of prior note)Add a one-line disable before the tagged template uses here to silence @typescript-eslint/no-unsafe-call in this test file.
Apply:
- code: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent` ... - output: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + output: dedent` ... - code: dedent` + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + code: dedent`(Longer‑term: consider ts-dedent or dedent(String.raw
...
) in tests.)Also applies to: 4349-4355, 4361-4367
rules/sort-import-attributes.ts (1)
149-162
: MissingnewlinesBetweenValueGetter
inreportAllErrors
call.The
reportAllErrors
call is missing thenewlinesBetweenValueGetter
parameter, which prevents spacing diagnostics (missedSpacingBetweenImportAttributes
andextraSpacingBetweenImportAttributes
) from working correctly.Add the missing parameter:
+import { getLinesBetween } from '../utils/get-lines-between' + // ... existing code ... reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', unexpectedOrder: 'unexpectedImportAttributesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, })rules/sort-jsx-props.ts (1)
189-203
: Enable spacing diagnostics: pass newlinesBetweenValueGetter.Without it, missed/extra newline errors won’t be reported for JSX props.
Apply:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenJSXPropsMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenJSXPropsMembers', unexpectedGroupOrder: 'unexpectedJSXPropsGroupOrder', unexpectedOrder: 'unexpectedJSXPropsOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(currentNodes), nodes: currentNodes, sourceCode, options, context, })rules/sort-jsx-props/types.ts (1)
100-105
: Selector narrowed to 'prop': update stale JSDoc and clarify usage.Selector is only 'prop'. Use modifiers ('shorthand' | 'multiline') for specificity.
Apply:
@@ - /** - * The selector type for this group. Can be 'prop' for regular props, - * 'multiline' for multi-line props, or 'shorthand' for shorthand props. - */ + /** + * The selector type for this group. Allowed: 'prop' only. + * Use modifiers ('shorthand' | 'multiline') to target those cases. + */ selector?: Selector @@ -/** - * Union type of all available JSX prop selectors. Used to categorize different - * types of JSX props. - */ +/** + * Selector for JSX props. Only "prop" is supported; specificity is via modifiers. + */ export type Selector = PropertySelector @@ -/** - * Complete list of available JSX prop selectors. Used for validation and JSON - * schema generation. - */ +/** Supported JSX prop selectors for validation and schema generation. */ export let allSelectors: Selector[] = ['prop']Also applies to: 113-118, 146-153
rules/sort-object-types.ts (2)
328-336
: Pass newlinesBetweenValueGetter to enable spacing diagnostics.Without
newlinesBetweenValueGetter
,reportAllErrors
cannot compute missed/extra blank-line errors whenoptions.newlinesBetween
is set.Apply this diff:
reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })Add the missing import at the top of the file:
+import { getLinesBetween } from '../utils/get-lines-between'
234-238
: Don't assign optional/required modifiers to index signatures.Index signatures don't support optionality; adding 'required' causes misleading predefined groups (e.g.,
required-index-signature
).Apply:
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }
🧹 Nitpick comments (4)
test/rules/sort-enums.test.ts (3)
66-107
: Test name may be misleading after key type change.The test is named "sorts enum members with number keys" but now uses string-literal keys (
'1'
,'12'
,'2'
,'8'
) instead of numeric keys. This tests alphabetical sorting of string keys that contain numeric characters, not numeric key sorting.Consider either:
- Renaming to "sorts enum members with string number keys" or "sorts enum members with numeric string keys"
- Or if the intent is to test actual numeric keys, reverting to numeric keys:
1
,12
,2
,8
The expected alphabetical order
'1', '12', '2', '8'
is correct for string sorting (where '12' comes before '2' because '1' < '2'), but may be counterintuitive for readers expecting numeric ordering.
1625-1666
: Test name may be misleading after key type change.Same concern as the alphabetical test: the test is named "sorts enum members with number keys" but uses string-literal keys (
'1'
,'2'
,'8'
,'12'
).Consider renaming for clarity, or using actual numeric keys if that's the intent.
The expected natural sort order
'1', '2', '8', '12'
is correct (natural sort correctly handles numeric strings), but the test name should reflect that these are string keys.
3184-3225
: Test name may be misleading after key type change.Same concern as previous tests: the test is named "sorts enum members with number keys" but uses string-literal keys (
'12'
,'1'
,'2'
,'8'
).Consider renaming for clarity, or using actual numeric keys if that's the intent.
The expected line-length order is correct (
'12'
has 4 characters including quotes, while others have 3).test/rules/sort-imports.test.ts (1)
2431-2437
: Reset spies after tsconfig stubs to avoid cross-test leakageAdd after: vi.resetAllMocks() in these tests that vi.spyOn readClosestTsConfigByPath to keep tests isolated.
Apply:
before: () => { mockReadClosestTsConfigByPathWith({ paths: { $path: ['./path'], }, }) }, + after: () => { + vi.resetAllMocks() + },(Apply similarly in the other two tests shown in the selected ranges.)
Also applies to: 6082-6088, 9767-9773
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
,!pnpm-lock.yaml
📒 Files selected for processing (67)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-export-attributes.mdx
(1 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(5 hunks)docs/content/rules/sort-import-attributes.mdx
(1 hunks)docs/content/rules/sort-imports.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(4 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)docs/public/llms.txt
(1 hunks)index.ts
(4 hunks)package.json
(4 hunks)readme.md
(1 hunks)rules/sort-array-includes.ts
(5 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-classes.ts
(1 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-enums.ts
(5 hunks)rules/sort-export-attributes.ts
(1 hunks)rules/sort-export-attributes/types.ts
(1 hunks)rules/sort-exports.ts
(2 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-import-attributes/types.ts
(1 hunks)rules/sort-imports.ts
(6 hunks)rules/sort-imports/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(1 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-maps.ts
(3 hunks)rules/sort-modules.ts
(2 hunks)rules/sort-named-exports.ts
(2 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(2 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(9 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(3 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-objects/types.ts
(5 hunks)rules/sort-switch-case.ts
(2 hunks)rules/sort-union-types.ts
(1 hunks)rules/sort-variable-declarations.ts
(1 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(2 hunks)test/rules/sort-enums.test.ts
(6 hunks)test/rules/sort-export-attributes.test.ts
(1 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(5 hunks)test/rules/sort-import-attributes.test.ts
(1 hunks)test/rules/sort-imports.test.ts
(25 hunks)test/rules/sort-interfaces.test.ts
(16 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(19 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(1 hunks)
💤 Files with no reviewable changes (6)
- docs/content/rules/sort-named-exports.mdx
- test/rules/sort-exports.test.ts
- rules/sort-array-includes/types.ts
- rules/sort-exports/types.ts
- docs/content/rules/sort-exports.mdx
- docs/content/rules/sort-named-imports.mdx
🚧 Files skipped from review as they are similar to previous changes (20)
- rules/sort-named-exports/types.ts
- rules/sort-classes.ts
- rules/sort-variable-declarations.ts
- rules/sort-maps.ts
- rules/sort-object-types/get-custom-groups-compare-options.ts
- readme.md
- test/rules/sort-import-attributes.test.ts
- docs/content/rules/sort-array-includes.mdx
- rules/sort-import-attributes/types.ts
- docs/content/rules/sort-import-attributes.mdx
- test/rules/sort-named-exports.test.ts
- rules/sort-decorators/types.ts
- rules/sort-export-attributes/types.ts
- test/rules/sort-export-attributes.test.ts
- test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
- rules/sort-modules.ts
- docs/content/rules/sort-object-types.mdx
- rules/sort-switch-case.ts
- docs/content/rules/sort-objects.mdx
- docs/content/rules/sort-export-attributes.mdx
🧰 Additional context used
🧬 Code graph analysis (23)
rules/sort-union-types.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-union-types/types.ts (1)
Options
(22-54)
rules/sort-intersection-types.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-union-types/types.ts (1)
Options
(22-54)
rules/sort-imports/types.ts (1)
types/common-options.ts (1)
CustomGroupsOption
(103-140)
rules/sort-object-types/types.ts (3)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)rules/sort-objects/types.ts (1)
SingleCustomGroup
(128-144)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-named-exports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-exports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-decorators.ts (6)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-array-includes.ts (5)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (2)
Options
(24-68)Selector
(100-100)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-objects/types.ts (1)
types/common-options.ts (2)
RegexOption
(477-477)CustomGroupsOption
(103-140)
rules/sort-object-types.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-106)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-heritage-clauses/types.ts (2)
types/common-options.ts (6)
CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(477-477)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)
rules/sort-import-attributes.ts (19)
rules/sort-import-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-objects.ts (5)
rules/sort-objects/types.ts (1)
Options
(25-120)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-named-exports/types.ts (3)
SingleCustomGroup
(74-92)Selector
(109-109)allSelectors
(155-155)
rules/sort-heritage-clauses.ts (10)
utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-named-imports/types.ts (1)
types/sorting-node.ts (1)
SortingNode
(18-102)
rules/sort-export-attributes.ts (22)
rules/sort-imports.ts (1)
MessageId
(59-65)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-export-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-36)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
test/rules/sort-imports.test.ts (1)
rules/sort-imports/types.ts (1)
Options
(29-141)
rules/sort-jsx-props.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-jsx-props/types.ts (1)
Options
(24-65)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
rules/sort-exports.ts (5)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-exports/types.ts (1)
Options
(25-57)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-interfaces.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-objects/types.ts (1)
Options
(25-120)
rules/sort-enums.ts (2)
rules/sort-enums/types.ts (1)
Options
(20-68)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)
rules/sort-imports.ts (7)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)rules/sort-imports/validate-side-effects-configuration.ts (1)
validateSideEffectsConfiguration
(19-48)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
rules/sort-named-imports.ts (4)
rules/sort-named-imports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
import { | ||
buildCustomGroupsArrayJsonSchema, | ||
partitionByCommentJsonSchema, | ||
partitionByNewLineJsonSchema, | ||
newlinesBetweenJsonSchema, | ||
commonJsonSchemas, | ||
groupsJsonSchema, | ||
} from '../utils/common-json-schemas' | ||
import { | ||
MISSED_SPACING_ERROR, | ||
EXTRA_SPACING_ERROR, | ||
GROUP_ORDER_ERROR, | ||
ORDER_ERROR, | ||
} from '../utils/report-errors' | ||
import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration' | ||
import { buildGetCustomGroupOverriddenOptionsFunction } from '../utils/get-custom-groups-compare-options' | ||
import { validateGeneratedGroupsConfiguration } from '../utils/validate-generated-groups-configuration' | ||
import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration' | ||
import { singleCustomGroupJsonSchema } from './sort-export-attributes/types' | ||
import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines' | ||
import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled' | ||
import { doesCustomGroupMatch } from '../utils/does-custom-group-match' | ||
import { sortNodesByGroups } from '../utils/sort-nodes-by-groups' | ||
import { createEslintRule } from '../utils/create-eslint-rule' | ||
import { reportAllErrors } from '../utils/report-all-errors' | ||
import { shouldPartition } from '../utils/should-partition' | ||
import { computeGroup } from '../utils/compute-group' | ||
import { rangeToDiff } from '../utils/range-to-diff' | ||
import { getSettings } from '../utils/get-settings' | ||
import { isSortable } from '../utils/is-sortable' | ||
import { complete } from '../utils/complete' | ||
|
||
type MessageId = | ||
| 'missedSpacingBetweenExportAttributes' | ||
| 'unexpectedExportAttributesGroupOrder' | ||
| 'extraSpacingBetweenExportAttributes' | ||
| 'unexpectedExportAttributesOrder' | ||
|
||
let defaultOptions: Required<Options[0]> = { | ||
fallbackSort: { type: 'unsorted' }, | ||
specialCharacters: 'keep', | ||
partitionByComment: false, | ||
partitionByNewLine: false, | ||
newlinesBetween: 'ignore', | ||
type: 'alphabetical', | ||
ignoreCase: true, | ||
customGroups: [], | ||
locales: 'en-US', | ||
alphabet: '', | ||
order: 'asc', | ||
groups: [], | ||
} | ||
|
||
export default createEslintRule<Options, MessageId>({ | ||
create: context => ({ | ||
ExportNamedDeclaration: node => { | ||
let attributes: TSESTree.ImportAttribute[] | undefined = node.attributes | ||
if (!isSortable(attributes)) { | ||
return | ||
} | ||
|
||
let { sourceCode, id } = context | ||
let settings = getSettings(context.settings) | ||
let options = complete(context.options.at(0), settings, defaultOptions) | ||
validateCustomSortConfiguration(options) | ||
validateGeneratedGroupsConfiguration({ | ||
selectors: [], | ||
modifiers: [], | ||
options, | ||
}) | ||
validateNewlinesAndPartitionConfiguration(options) | ||
|
||
let eslintDisabledLines = getEslintDisabledLines({ | ||
ruleName: id, | ||
sourceCode, | ||
}) | ||
|
||
let formattedMembers: SortingNode<TSESTree.ImportAttribute>[][] = [[]] | ||
for (let attribute of attributes) { | ||
let name = getAttributeName(attribute, sourceCode) | ||
|
||
let group = computeGroup({ | ||
customGroupMatcher: customGroup => | ||
doesCustomGroupMatch({ | ||
elementName: name, | ||
selectors: [], | ||
modifiers: [], | ||
customGroup, | ||
}), | ||
predefinedGroups: [], | ||
options, | ||
}) | ||
|
||
let sortingNode: Omit< | ||
SortingNode<TSESTree.ImportAttribute>, | ||
'partitionId' | ||
> = { | ||
isEslintDisabled: isNodeEslintDisabled( | ||
attribute, | ||
eslintDisabledLines, | ||
), | ||
size: rangeToDiff(attribute, sourceCode), | ||
node: attribute, | ||
group, | ||
name, | ||
} | ||
|
||
let lastSortingNode = formattedMembers.at(-1)?.at(-1) | ||
if ( | ||
shouldPartition({ | ||
lastSortingNode, | ||
sortingNode, | ||
sourceCode, | ||
options, | ||
}) | ||
) { | ||
formattedMembers.push([]) | ||
} | ||
|
||
formattedMembers.at(-1)!.push({ | ||
...sortingNode, | ||
partitionId: formattedMembers.length, | ||
}) | ||
} | ||
|
||
for (let nodes of formattedMembers) { | ||
function createSortNodesExcludingEslintDisabled( | ||
sortingNodes: SortingNode<TSESTree.ImportAttribute>[], | ||
) { | ||
return function ( | ||
ignoreEslintDisabledNodes: boolean, | ||
): SortingNode<TSESTree.ImportAttribute>[] { | ||
return sortNodesByGroups({ | ||
getOptionsByGroupIndex: | ||
buildGetCustomGroupOverriddenOptionsFunction(options), | ||
ignoreEslintDisabledNodes, | ||
groups: options.groups, | ||
nodes: sortingNodes, | ||
}) | ||
} | ||
} | ||
|
||
reportAllErrors<MessageId>({ | ||
availableMessageIds: { | ||
missedSpacingBetweenMembers: 'missedSpacingBetweenExportAttributes', | ||
extraSpacingBetweenMembers: 'extraSpacingBetweenExportAttributes', | ||
unexpectedGroupOrder: 'unexpectedExportAttributesGroupOrder', | ||
unexpectedOrder: 'unexpectedExportAttributesOrder', | ||
}, | ||
sortNodesExcludingEslintDisabled: | ||
createSortNodesExcludingEslintDisabled(nodes), | ||
sourceCode, | ||
options, | ||
context, | ||
nodes, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hook up newline distance calculator
Spacing/newline diagnostics never fire because reportAllErrors
receives no newlinesBetweenValueGetter
. Provide it (and import getLinesBetween
) so the rule can emit the promised spacing errors.
@@
-import { sortNodesByGroups } from '../utils/sort-nodes-by-groups'
+import { sortNodesByGroups } from '../utils/sort-nodes-by-groups'
+import { getLinesBetween } from '../utils/get-lines-between'
@@
reportAllErrors<MessageId>({
availableMessageIds: {
missedSpacingBetweenMembers: 'missedSpacingBetweenExportAttributes',
extraSpacingBetweenMembers: 'extraSpacingBetweenExportAttributes',
unexpectedGroupOrder: 'unexpectedExportAttributesGroupOrder',
unexpectedOrder: 'unexpectedExportAttributesOrder',
},
sortNodesExcludingEslintDisabled:
createSortNodesExcludingEslintDisabled(nodes),
sourceCode,
options,
context,
- nodes,
+ nodes,
+ newlinesBetweenValueGetter: (left, right) =>
+ getLinesBetween(sourceCode, left, right),
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { | |
buildCustomGroupsArrayJsonSchema, | |
partitionByCommentJsonSchema, | |
partitionByNewLineJsonSchema, | |
newlinesBetweenJsonSchema, | |
commonJsonSchemas, | |
groupsJsonSchema, | |
} from '../utils/common-json-schemas' | |
import { | |
MISSED_SPACING_ERROR, | |
EXTRA_SPACING_ERROR, | |
GROUP_ORDER_ERROR, | |
ORDER_ERROR, | |
} from '../utils/report-errors' | |
import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration' | |
import { buildGetCustomGroupOverriddenOptionsFunction } from '../utils/get-custom-groups-compare-options' | |
import { validateGeneratedGroupsConfiguration } from '../utils/validate-generated-groups-configuration' | |
import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration' | |
import { singleCustomGroupJsonSchema } from './sort-export-attributes/types' | |
import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines' | |
import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled' | |
import { doesCustomGroupMatch } from '../utils/does-custom-group-match' | |
import { sortNodesByGroups } from '../utils/sort-nodes-by-groups' | |
import { createEslintRule } from '../utils/create-eslint-rule' | |
import { reportAllErrors } from '../utils/report-all-errors' | |
import { shouldPartition } from '../utils/should-partition' | |
import { computeGroup } from '../utils/compute-group' | |
import { rangeToDiff } from '../utils/range-to-diff' | |
import { getSettings } from '../utils/get-settings' | |
import { isSortable } from '../utils/is-sortable' | |
import { complete } from '../utils/complete' | |
type MessageId = | |
| 'missedSpacingBetweenExportAttributes' | |
| 'unexpectedExportAttributesGroupOrder' | |
| 'extraSpacingBetweenExportAttributes' | |
| 'unexpectedExportAttributesOrder' | |
let defaultOptions: Required<Options[0]> = { | |
fallbackSort: { type: 'unsorted' }, | |
specialCharacters: 'keep', | |
partitionByComment: false, | |
partitionByNewLine: false, | |
newlinesBetween: 'ignore', | |
type: 'alphabetical', | |
ignoreCase: true, | |
customGroups: [], | |
locales: 'en-US', | |
alphabet: '', | |
order: 'asc', | |
groups: [], | |
} | |
export default createEslintRule<Options, MessageId>({ | |
create: context => ({ | |
ExportNamedDeclaration: node => { | |
let attributes: TSESTree.ImportAttribute[] | undefined = node.attributes | |
if (!isSortable(attributes)) { | |
return | |
} | |
let { sourceCode, id } = context | |
let settings = getSettings(context.settings) | |
let options = complete(context.options.at(0), settings, defaultOptions) | |
validateCustomSortConfiguration(options) | |
validateGeneratedGroupsConfiguration({ | |
selectors: [], | |
modifiers: [], | |
options, | |
}) | |
validateNewlinesAndPartitionConfiguration(options) | |
let eslintDisabledLines = getEslintDisabledLines({ | |
ruleName: id, | |
sourceCode, | |
}) | |
let formattedMembers: SortingNode<TSESTree.ImportAttribute>[][] = [[]] | |
for (let attribute of attributes) { | |
let name = getAttributeName(attribute, sourceCode) | |
let group = computeGroup({ | |
customGroupMatcher: customGroup => | |
doesCustomGroupMatch({ | |
elementName: name, | |
selectors: [], | |
modifiers: [], | |
customGroup, | |
}), | |
predefinedGroups: [], | |
options, | |
}) | |
let sortingNode: Omit< | |
SortingNode<TSESTree.ImportAttribute>, | |
'partitionId' | |
> = { | |
isEslintDisabled: isNodeEslintDisabled( | |
attribute, | |
eslintDisabledLines, | |
), | |
size: rangeToDiff(attribute, sourceCode), | |
node: attribute, | |
group, | |
name, | |
} | |
let lastSortingNode = formattedMembers.at(-1)?.at(-1) | |
if ( | |
shouldPartition({ | |
lastSortingNode, | |
sortingNode, | |
sourceCode, | |
options, | |
}) | |
) { | |
formattedMembers.push([]) | |
} | |
formattedMembers.at(-1)!.push({ | |
...sortingNode, | |
partitionId: formattedMembers.length, | |
}) | |
} | |
for (let nodes of formattedMembers) { | |
function createSortNodesExcludingEslintDisabled( | |
sortingNodes: SortingNode<TSESTree.ImportAttribute>[], | |
) { | |
return function ( | |
ignoreEslintDisabledNodes: boolean, | |
): SortingNode<TSESTree.ImportAttribute>[] { | |
return sortNodesByGroups({ | |
getOptionsByGroupIndex: | |
buildGetCustomGroupOverriddenOptionsFunction(options), | |
ignoreEslintDisabledNodes, | |
groups: options.groups, | |
nodes: sortingNodes, | |
}) | |
} | |
} | |
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenExportAttributes', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenExportAttributes', | |
unexpectedGroupOrder: 'unexpectedExportAttributesGroupOrder', | |
unexpectedOrder: 'unexpectedExportAttributesOrder', | |
}, | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
context, | |
nodes, | |
}) | |
// Add alongside the existing import of sortNodesByGroups | |
import { sortNodesByGroups } from '../utils/sort-nodes-by-groups' | |
import { getLinesBetween } from '../utils/get-lines-between' | |
… | |
// Inside the loop, update the call to reportAllErrors to pass the new helper: | |
reportAllErrors<MessageId>({ | |
availableMessageIds: { | |
missedSpacingBetweenMembers: 'missedSpacingBetweenExportAttributes', | |
extraSpacingBetweenMembers: 'extraSpacingBetweenExportAttributes', | |
unexpectedGroupOrder: 'unexpectedExportAttributesGroupOrder', | |
unexpectedOrder: 'unexpectedExportAttributesOrder', | |
}, | |
sortNodesExcludingEslintDisabled: | |
createSortNodesExcludingEslintDisabled(nodes), | |
sourceCode, | |
options, | |
context, | |
nodes, | |
newlinesBetweenValueGetter: (left, right) => | |
getLinesBetween(sourceCode, left, right), | |
}) |
🤖 Prompt for AI Agents
In rules/sort-export-attributes.ts around lines 7 to 162, the rule never
supplies a newlinesBetweenValueGetter so spacing/newline diagnostics never fire;
import getLinesBetween from '../utils/get-lines-between' at the top of the file
and pass newlinesBetweenValueGetter: getLinesBetween in the reportAllErrors call
where the options, sourceCode, context, and nodes are passed so the rule can
compute newline distances and emit spacing errors.
parentNode: | ||
| TSESTree.TSTypeAliasDeclaration | ||
| TSESTree.TSInterfaceDeclaration | ||
| null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature includes TSInterfaceDeclaration but no caller provides it.
The parentNode
parameter accepts TSInterfaceDeclaration
, but no visitor currently calls sortObjectTypeElements
with an interface parent. This is consistent with the missing TSInterfaceBody
visitor noted above.
If interface support is not needed, remove TSInterfaceDeclaration
from the union:
parentNode:
| TSESTree.TSTypeAliasDeclaration
- | TSESTree.TSInterfaceDeclaration
| null
Otherwise, add the missing TSInterfaceBody
visitor as noted in the previous comment.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
parentNode: | |
| TSESTree.TSTypeAliasDeclaration | |
| TSESTree.TSInterfaceDeclaration | |
| null | |
parentNode: | |
| TSESTree.TSTypeAliasDeclaration | |
| null |
🤖 Prompt for AI Agents
In rules/sort-object-types.ts around lines 163 to 166, the parentNode union
includes TSESTree.TSInterfaceDeclaration even though no visitor ever calls
sortObjectTypeElements with an interface parent; either remove
TSInterfaceDeclaration from the parentNode union if interface support is not
required, or implement the missing TSInterfaceBody visitor that calls
sortObjectTypeElements for interface bodies so interfaces are actually
handled—update the type union or add the visitor accordingly and ensure
tests/usage reflect the chosen approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
rules/sort-heritage-clauses.ts (1)
135-176
: Partition IDs are incorrect.Line 158 hardcodes
partitionId: 0
for all nodes, but the 2D structure suggests each partition should have unique IDs. Update the assignment to reflect the actual partition index.Apply this diff:
let sortingNode: SortingNode = { isEslintDisabled: isNodeEslintDisabled( heritageClause, eslintDisabledLines, ), size: rangeToDiff(heritageClause, sourceCode), node: heritageClause, - partitionId: 0, + partitionId: formattedMembers.length, group, name, }
♻️ Duplicate comments (11)
rules/sort-import-attributes.ts (1)
149-162
: Missing newlinesBetweenValueGetter parameter.The
reportAllErrors
call is still missing thenewlinesBetweenValueGetter
parameter, which prevents spacing diagnostics from working correctly. This was flagged in a previous review.Apply this diff to add the missing parameter:
+import { getLinesBetween } from '../utils/get-lines-between' + // ... in the reportAllErrors call: reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', unexpectedOrder: 'unexpectedImportAttributesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, })rules/sort-export-attributes.ts (1)
7-162
: Hook up newline distance calculatorSpacing/newline diagnostics never fire because
reportAllErrors
receives nonewlinesBetweenValueGetter
. Provide it (and importgetLinesBetween
) so the rule can emit the promised spacing errors.Apply this diff to import
getLinesBetween
at the top of the file:import { buildCustomGroupsArrayJsonSchema, partitionByCommentJsonSchema, partitionByNewLineJsonSchema, newlinesBetweenJsonSchema, commonJsonSchemas, groupsJsonSchema, } from '../utils/common-json-schemas' +import { getLinesBetween } from '../utils/get-lines-between'
Then apply this diff to pass
newlinesBetweenValueGetter
in thereportAllErrors
call:reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenExportAttributes', extraSpacingBetweenMembers: 'extraSpacingBetweenExportAttributes', unexpectedGroupOrder: 'unexpectedExportAttributesGroupOrder', unexpectedOrder: 'unexpectedExportAttributesOrder', }, sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), })rules/sort-array-includes.ts (2)
246-257
: Verify unknown group handling to prevent unintended reordering.Per a previous review comment, nodes with selectors not present in configured
groups
(e.g.,'spread'
) may be reordered unintentionally. Consider passingisNodeIgnored
tosortNodesByGroups
to keep unlisted selectors stable:isNodeIgnored: node => getGroupIndex(options.groups, node) === options.groups.length,This ensures that spreads and other unconfigured selectors remain in their original positions by default.
Run the following script to check if spreads are handled correctly in tests:
#!/bin/bash # Search for test cases involving spread elements rg -n --type=ts -A5 -B5 'SpreadElement|\.\.\..*\[' test/rules/sort-array-includes.test.ts
260-268
: Enable spacing diagnostics by passing newlinesBetweenValueGetter.Per a previous review comment, the
newlinesBetweenValueGetter
parameter is missing, which would cause spacing-related test assertions to fail. Add:+import { getLinesBetween } from '../utils/get-lines-between' let nodes = formattedMembers.flat() reportAllErrors<MessageIds>({ + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled, availableMessageIds, sourceCode, options, context, nodes, })Verify that spacing tests are passing:
#!/bin/bash # Run tests for sort-array-includes npm test -- sort-array-includesrules/sort-objects.ts (2)
553-594
: Address type safety: don't conflate Property with VariableDeclarator.The return type declares
type: 'VariableDeclarator'
but thenode
field can be eitherTSESTree.VariableDeclarator | TSESTree.Property
(line 563). This makesdeclarationMatchesPattern
matching fire incorrectly for nested object literals, as noted in a previous review.Separate the union so
Property
parents have their own discriminant:function getObjectParent({ onlyFirstParent, sourceCode, node, }: { node: TSESTree.ObjectExpression | TSESTree.ObjectPattern sourceCode: TSESLint.SourceCode onlyFirstParent: boolean }): | { - node: TSESTree.VariableDeclarator | TSESTree.Property + node: TSESTree.VariableDeclarator type: 'VariableDeclarator' name: string | null } + | { + node: TSESTree.Property + type: 'Property' + name: string | null + } | { node: TSESTree.CallExpression type: 'CallExpression' name: string | null } | null { let variableParent = getVariableParent({ onlyFirstParent, node }) if (variableParent) { - return { - type: 'VariableDeclarator', - name: variableParent.name, - node: variableParent.node, - } + if ( + variableParent.node.type === TSESTree.AST_NODE_TYPES.VariableDeclarator + ) { + return { + type: 'VariableDeclarator', + name: variableParent.name, + node: variableParent.node, + } + } + return { + type: 'Property', + name: variableParent.name, + node: variableParent.node, + } }Then update
computeMatchedContextOptions
to checkobjectParent.type === 'VariableDeclarator'
rather than!== 'CallExpression'
.
586-592
: Normalize callee text to reduce false positives in callingFunctionNamePattern matching.Using
sourceCode.getText(callParent.callee)
can return arbitrary wrapped expressions (e.g.,(0, foo.bar)
). Extract a stable identifier name instead:function getCalleeName(expr: TSESTree.Expression): string | null { if (expr.type === 'Identifier') return expr.name if ( expr.type === 'MemberExpression' && !expr.computed && expr.property.type === 'Identifier' ) { return expr.property.name // or `${obj}.${prop}` if desired } return null }Then use:
if (callParent) { + let calleeName = getCalleeName(callParent.callee) ?? sourceCode.getText(callParent.callee) return { - name: sourceCode.getText(callParent.callee), + name: calleeName, type: 'CallExpression', node: callParent, } }rules/sort-jsx-props.ts (1)
189-202
: Enable spacing diagnostics (missed/extra blank lines).Per previous review feedback, pass
newlinesBetweenValueGetter
soreportAllErrors
can evaluatenewlinesBetween
for JSX props.Apply this diff:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenJSXPropsMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenJSXPropsMembers', unexpectedGroupOrder: 'unexpectedJSXPropsGroupOrder', unexpectedOrder: 'unexpectedJSXPropsOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(currentNodes), nodes: currentNodes, sourceCode, options, context, })rules/sort-heritage-clauses.ts (1)
193-206
: Provide newlinesBetweenValueGetter to report spacing errors.Per previous review feedback, pass
newlinesBetweenValueGetter
soreportAllErrors
can compute missed/extra blank-line errors.Apply this diff:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', unexpectedOrder: 'unexpectedHeritageClausesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context, nodes, })rules/sort-object-types.ts (3)
329-337
: Pass newlinesBetweenValueGetter to enable spacing diagnostics.Per previous review feedback, pass
newlinesBetweenValueGetter
soreportAllErrors
can compute missed/extra blank-line errors whenoptions.newlinesBetween
is set.Apply this diff:
+import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), availableMessageIds, sourceCode, options, context, nodes, })
115-130
: Add TSInterfaceBody visitor to include interfaces.Per previous review feedback, add a
TSInterfaceBody
visitor that callssortObjectTypeElements
withparentNode
set whennode.parent.type === 'TSInterfaceDeclaration'
andelements: node.body
.Apply this diff:
export default createEslintRule<Options, MessageId>({ create: context => ({ TSTypeLiteral: node => sortObjectTypeElements<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenObjectTypeMembers', extraSpacingBetweenMembers: 'extraSpacingBetweenObjectTypeMembers', unexpectedGroupOrder: 'unexpectedObjectTypesGroupOrder', unexpectedOrder: 'unexpectedObjectTypesOrder', }, parentNode: node.parent.type === 'TSTypeAliasDeclaration' ? node.parent : null, elements: node.members, context, }), + TSInterfaceBody: node => + sortObjectTypeElements<MessageId>({ + availableMessageIds: { + missedSpacingBetweenMembers: 'missedSpacingBetweenObjectTypeMembers', + extraSpacingBetweenMembers: 'extraSpacingBetweenObjectTypeMembers', + unexpectedGroupOrder: 'unexpectedObjectTypesGroupOrder', + unexpectedOrder: 'unexpectedObjectTypesOrder', + }, + parentNode: + node.parent && node.parent.type === 'TSInterfaceDeclaration' + ? node.parent + : null, + elements: node.body, + context, + }), }),
235-239
: Don't assign optional/required modifiers to index signatures.Per previous review feedback, index signatures don't support optionality; adding 'required' causes misleading predefined groups.
Apply this diff:
- if (isMemberOptional(typeElement)) { - modifiers.push('optional') - } else { - modifiers.push('required') - } + if (typeElement.type !== 'TSIndexSignature') { + if (isMemberOptional(typeElement)) { + modifiers.push('optional') + } else { + modifiers.push('required') + } + }
🧹 Nitpick comments (1)
rules/sort-export-attributes.ts (1)
204-213
: LGTM with a minor observationThe helper correctly extracts attribute names. The fallback to
sourceCode.getText(attribute)
is defensive and safe.For slightly better type safety, consider extracting the literal value directly when
key.type === 'Literal'
:function getAttributeName( attribute: TSESTree.ImportAttribute, sourceCode: TSESLint.SourceCode, ): string { let { key } = attribute if (key.type === 'Identifier') { return key.name } - return key.value?.toString() ?? sourceCode.getText(attribute) + if (key.type === 'Literal' && typeof key.value === 'string') { + return key.value + } + return sourceCode.getText(attribute) }This avoids calling
toString()
on non-string literal values and more clearly handles the expected string case.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
,!pnpm-lock.yaml
📒 Files selected for processing (24)
eslint.config.ts
(1 hunks)package.json
(4 hunks)rules/sort-array-includes.ts
(6 hunks)rules/sort-classes.ts
(2 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-enums.ts
(6 hunks)rules/sort-export-attributes.ts
(1 hunks)rules/sort-exports.ts
(3 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-imports.ts
(7 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(2 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-maps.ts
(4 hunks)rules/sort-modules.ts
(3 hunks)rules/sort-named-exports.ts
(3 hunks)rules/sort-named-imports.ts
(3 hunks)rules/sort-object-types.ts
(10 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-sets.ts
(1 hunks)rules/sort-switch-case.ts
(3 hunks)rules/sort-union-types.ts
(2 hunks)rules/sort-variable-declarations.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- rules/sort-classes.ts
- package.json
- rules/sort-enums.ts
- rules/sort-union-types.ts
- rules/sort-modules.ts
🧰 Additional context used
🧬 Code graph analysis (18)
rules/sort-intersection-types.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-106)rules/sort-union-types/types.ts (1)
Options
(22-54)
rules/sort-variable-declarations.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-variable-declarations/types.ts (1)
Options
(23-55)
rules/sort-exports.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-exports/types.ts (1)
Options
(25-57)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-sets.ts (1)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)
rules/sort-named-imports.ts (4)
rules/sort-named-imports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-maps.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-maps/types.ts (1)
Options
(20-64)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)
rules/sort-switch-case.ts (1)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)
rules/sort-interfaces.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types.ts (1)
sortObjectTypeElements
(152-338)
rules/sort-named-exports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-exports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-imports.ts (5)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
rules/sort-array-includes.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (2)
Options
(24-68)Selector
(100-100)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-export-attributes.ts (19)
utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-45)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-objects.ts (6)
rules/sort-objects/types.ts (1)
Options
(25-120)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
rules/sort-import-attributes.ts (19)
utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-45)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (5)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
rules/sort-heritage-clauses.ts (10)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-decorators.ts (7)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-object-types.ts (4)
rules/sort-object-types/types.ts (1)
Options
(28-106)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-jsx-props.ts (4)
rules/sort-jsx-props/types.ts (1)
Options
(24-65)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
🔇 Additional comments (46)
rules/sort-sets.ts (1)
59-59
: No changes needed for defaultOptions duplication
The placement ofdefaultOptions
in both themeta
object and at the top level aligns with the established pattern across other rules and thecreateEslintRule
helper signature.rules/sort-intersection-types.ts (2)
20-20
: LGTM: Typing refinement aligns with array-based options standard.The change from
Options[0]
toOptions[number]
correctly represents thatdefaultOptions
should match any element of theOptions
array type, not just the first element. This is consistent with similar changes across other rules in this PR.
48-48
: LGTM: Public exposure of defaultOptions via metadata.Adding
defaultOptions
to the rule's meta object makes the default configuration publicly accessible through ESLint's metadata API, which is consistent with the standardization effort across all rules in this PR.rules/sort-import-attributes.ts (5)
1-43
: LGTM!The imports are well-organized, and the
MessageId
type definition correctly captures all four error scenarios for the rule (spacing, group order, and attribute order).
45-58
: LGTM!The default options are correctly typed and include all standard configuration fields consistent with other sorting rules in the plugin.
60-130
: LGTM!The rule correctly:
- Guards against non-sortable attributes using
isSortable
- Validates all configuration aspects (custom sort, groups, newlines/partitioning)
- Computes groups using the standard
computeGroup
utility- Implements partitioning logic consistent with other rules in the plugin
166-202
: LGTM!The rule metadata is well-structured:
- Schema correctly uses common JSON schemas for consistency
- Messages use standard error constants
- Documentation URL and description are appropriate
recommended: true
is suitable for a new sorting rule- Default options are properly declared
204-213
: LGTM!The
getAttributeName
helper correctly handles bothIdentifier
andLiteral
key types, with defensive fallback to the full source text.rules/sort-maps.ts (4)
25-25
: LGTM! Import aligns with the refactored utility.The import change from
getMatchingContextOptions
tofilterOptionsByAllNamesMatch
is consistent with the function call update at line 81 and reflects the broader migration to standardized context-matching utilities across rules.
46-46
: LGTM! Type change improves consistency.The change from
Required<Options[0]>
toRequired<Options[number]>
aligns with the pattern used across other rules (e.g.,sort-array-includes.ts
) and is more idiomatic for uniform array element types.
81-88
: LGTM! Function call correctly uses the refactored utility.The call to
filterOptionsByAllNamesMatch
properly provides the required parameters (nodeNames
andcontextOptions
). ThenodeNames
computation correctly filters out null and SpreadElement entries before mapping to names, and the return value is used consistently with the previous implementation.
235-235
: LGTM! Metadata addition improves rule introspection.Adding
defaultOptions
to the rule'smeta
object exposes the defaults for ESLint tooling and plugins (such as eslint-plugin-eslint-plugin) to introspect, improving compatibility and discoverability.Based on learnings
eslint.config.ts (1)
3-3
: LGTM! Import path simplified correctly.The import now references the main package export instead of a deep subpath, which aligns with accessing the config via the
configs
property on line 7.rules/sort-interfaces.ts (4)
20-20
: LGTM: Type annotation updated to array-based Options pattern.The change from
Required<Options[0]>
toRequired<Options[number]>
aligns with the PR-wide migration to array-based option definitions.
29-29
: LGTM: Array-based customGroups default aligns with new API.The default
customGroups: []
is consistent with the PR-wide shift from object-mapped to array-based custom group definitions.
50-50
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.
55-67
: LGTM: Handler signature updated correctly.The
TSInterfaceDeclaration
handler now properly forwardsparentNode
,elements
, andcontext
tosortObjectTypeElements
, matching the expected function signature shown inrules/sort-object-types.ts
.rules/sort-switch-case.ts (3)
30-30
: LGTM: Type annotation updated to array-based Options pattern.The change from
Required<Options[0]>
toRequired<Options[number]>
is consistent with the PR-wide migration to array-based option definitions.
213-236
: LGTM: Immutable sorting with toSorted.Replacing in-place
.sort()
with immutable.toSorted()
eliminates potential mutation bugs. This is safe given the PR's Node.js ≥20 requirement (ES2023 support).
289-289
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.rules/sort-variable-declarations.ts (2)
50-50
: LGTM: Type annotation updated to array-based Options pattern.The change from
Required<Options[0]>
toRequired<Options[number]>
is consistent with the PR-wide migration.
225-225
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.rules/sort-named-exports.ts (3)
54-68
: LGTM: defaultOptions migrated to groups-based model.The updated
defaultOptions
removes the deprecatedgroupKind
field and introducesgroups: []
as the default, aligning with the PR-wide migration to array-based grouping.
168-195
: LGTM: Sorting flow refactored to use groups-based model.The new
sortNodesExcludingEslintDisabled
function correctly delegates tosortNodesByGroups
with per-group options viabuildGetCustomGroupOverriddenOptionsFunction
. Centralized error reporting viareportAllErrors
is consistent with the pattern used in other rules (e.g.,sort-named-imports
,sort-exports
).
232-232
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.rules/sort-array-includes.ts (6)
32-32
: LGTM: New utility import for context matching.The
filterOptionsByAllNamesMatch
import is correctly used for context-based option filtering at lines 166-171.
56-58
: LGTM: Simplified to type alias without groupKind.Changing from an interface with a
groupKind
field to a simple type alias aligns with the PR-wide removal of the deprecatedgroupKind
property.
60-73
: LGTM: defaultOptions migrated to groups-based model with sensible default.The
groups: ['literal']
default ensures literal elements are sorted before spreads, which is a reasonable default behavior for array includes.
136-136
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.
166-171
: LGTM: Context matching updated to use filterOptionsByAllNamesMatch.The new context matching logic correctly filters options based on the
allNamesMatchPattern
configuration, consistent with the utility function's implementation.
197-198
: LGTM: Selector logic simplified.Direct determination of selector based on element type is clearer and aligns with the removal of the
groupKind
property.rules/sort-named-imports.ts (3)
54-68
: LGTM: defaultOptions migrated to groups-based model.The updated
defaultOptions
removes the deprecatedgroupKind
field and introducesgroups: []
as the default, aligning with the PR-wide migration.
165-192
: LGTM: Sorting flow refactored to use groups-based model.The new
sortNodesExcludingEslintDisabled
function correctly delegates tosortNodesByGroups
. This pattern is consistent with other rules in the PR. TheSortNamedImportsSortingNode
type issue noted in a previous review has been addressed.
229-229
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.rules/sort-exports.ts (4)
50-52
: LGTM: Simplified to type alias without groupKind.Changing from an interface with a
groupKind
field to a simple type alias aligns with the PR-wide removal of the deprecatedgroupKind
property.
54-67
: LGTM: defaultOptions migrated to groups-based model.The updated
defaultOptions
removes the deprecatedgroupKind
field and introduces array-based grouping, aligning with the PR-wide migration.
151-179
: LGTM: Sorting flow refactored to use groups-based model.The new
sortNodesExcludingEslintDisabled
function correctly delegates tosortNodesByGroups
with per-group options. Centralized error reporting viareportAllErrors
is consistent with the pattern used in other rules.
220-220
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.rules/sort-objects.ts (8)
27-27
: LGTM: New utility imports for enhanced context matching.The
filterOptionsByDeclarationCommentMatches
andfilterOptionsByAllNamesMatch
imports support the newdeclarationCommentMatchesPattern
andallNamesMatchPattern
configuration options inuseConfigurationIf
.Also applies to: 37-37
66-84
: LGTM: defaultOptions migrated to groups-based model.The updated
defaultOptions
introduces array-basedcustomGroups
and addsuseConfigurationIf: {}
, aligning with the PR-wide migration.
98-102
: LGTM: Context matching refactored to use computeMatchedContextOptions.The new
computeMatchedContextOptions
function centralizes context option filtering. The function implementation will be reviewed separately.
117-119
: LGTM: Simplified control flow for objectDeclarations check.The
else if
structure is clearer and maintains the same logic.
425-442
: LGTM: Schema updated for new configuration options.The schema correctly exposes new
useConfigurationIf
properties (declarationCommentMatchesPattern
,declarationMatchesPattern
) and uses array-basedcustomGroups
schema.
467-467
: LGTM: defaultOptions exposed in meta.Exposing
defaultOptions
in the rule's metadata is consistent with the pattern applied across multiple rules in this PR.
475-551
: LGTM: Centralized context matching with appropriate type guards.The
computeMatchedContextOptions
function correctly:
- Filters by
allNamesMatchPattern
anddeclarationCommentMatchesPattern
- Guards
callingFunctionNamePattern
matching withobjectParent.type === 'CallExpression'
check (lines 521)- Guards
declarationMatchesPattern
matching withobjectParent.type === 'VariableDeclarator'
check (line 537)These type guards address the concerns raised in previous reviews.
596-634
: LGTM: getVariableParent correctly extracts parent information.The function properly handles both
VariableDeclarator
andProperty
parent types, extracting the appropriate identifier name from each.
|
||
export default eslintConfig({ | ||
extends: eslintPlugin, | ||
extends: eslintPlugin.configs.recommended, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify the correct flat config property name.
Based on the retrieved learnings, eslint-plugin-eslint-plugin
v7.0.0 provides flat config exports as configs["flat/recommended"]
. Since this file uses flat config format (indicated by satisfies Promise<Linter.Config[]>
), verify that configs.recommended
is the correct property or if it should be configs["flat/recommended"]
.
Run the following script to verify the available config exports:
Based on learnings.
🏁 Script executed:
#!/bin/bash
# Description: Check the available config exports from eslint-plugin-eslint-plugin
# Check if package.json or documentation mentions the correct config export
rg -n "configs\[" --type=md --type=json -g '!**/node_modules/**' -C 3
# Check if there are any other files using this import pattern
rg -n "eslintPlugin\.configs" --type=ts --type=js -g '!**/node_modules/**' -C 2
# Examine package.json to understand exports
cat package.json | jq '.devDependencies["eslint-plugin-eslint-plugin"]'
Length of output: 306
Run the following script to confirm the correct flat config export names in the plugin’s README:
🏁 Script executed:
#!/bin/bash
npm view [email protected] readme | rg -n 'configs\[' -C2
npm view [email protected] readme | rg -n 'flat/recommended' -C2
Length of output: 234
Use the correct flat config key
In eslint.config.ts (line 7), replace
extends: eslintPlugin.configs.recommended,
with
extends: eslintPlugin.configs['rules-recommended'],
🤖 Prompt for AI Agents
In eslint.config.ts around line 7, the config uses the incorrect flat-config key
"extends: eslintPlugin.configs.recommended"; update this to use the correct flat
config key by replacing that entry with the 'rules-recommended' key from
eslintPlugin.configs (i.e., use eslintPlugin.configs['rules-recommended'] as the
extends value) so the plugin's recommended rules are applied correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
rules/sort-jsx-props/types.ts (1)
94-118
: Fix stale selector docs to match single'prop'
support.Comments still promise
'multiline'
/'shorthand'
selector values even though the schema andSelector
type now expose'prop'
only. Please align the JSDoc so consumers don’t configure unsupported selectors.docs/content/rules/sort-objects.mdx (1)
572-579
: Update the documentedcustomGroups
type.The snippet still advertises the deprecated object-map shape (
{ [groupName: string]: string | string[] }
), but the rule now expects an array of definition objects. Keeping this text will cause copy-paste configs to fail in v5.- type: `{ [groupName: string]: string | string[] }` + type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>`Also ensure the surrounding prose reflects the array-based structure (matching the example immediately below).
♻️ Duplicate comments (20)
docs/content/rules/sort-objects.mdx (2)
345-364
: Fix the RGB regex example again.
'^r|g|b$'
still expands to(^r)
org
or(b$)
, so it matches keys you didn’t intend. Please keep the grouped, anchored version that was previously applied.- allNamesMatchPattern: '^r|g|b$', + allNamesMatchPattern: '^(?:r|g|b)$',
399-405
: Replace the invalid declaration regex.
'*metadata$'
is not a valid regular expression (leading*
triggers “nothing to repeat”). Copying this snippet will throw at runtime. Please restore the'.*metadata$'
version.- declarationMatchesPattern: '*metadata$', + declarationMatchesPattern: '.*metadata$',rules/sort-objects.ts (1)
562-592
: Return the correct parent type for nested properties
getObjectParent
still reportstype: 'VariableDeclarator'
even when the nearest ancestor is aProperty
. That makesdeclarationMatchesPattern
/declarationCommentMatchesPattern
fire for nested object literals and breaks the intended guardrails we discussed earlier. Please preserve the real ancestor kind so only actual declarators run through those filters.}): - | { - node: TSESTree.VariableDeclarator | TSESTree.Property - type: 'VariableDeclarator' - name: string | null - } + | { + node: TSESTree.VariableDeclarator + type: 'VariableDeclarator' + name: string | null + } + | { + node: TSESTree.Property + type: 'Property' + name: string | null + } | { node: TSESTree.CallExpression type: 'CallExpression' name: string | null } @@ let variableParent = getVariableParent({ onlyFirstParent, node }) if (variableParent) { - return { - type: 'VariableDeclarator', - name: variableParent.name, - node: variableParent.node, - } + if ( + variableParent.node.type === TSESTree.AST_NODE_TYPES.VariableDeclarator + ) { + return { + type: 'VariableDeclarator', + name: variableParent.name, + node: variableParent.node, + } + } + + return { + type: 'Property', + name: variableParent.name, + node: variableParent.node, + } }rules/sort-import-attributes.ts (1)
7-162
: Wire newlinesBetweenValueGetter so spacing errors fireWithout a
newlinesBetweenValueGetter
,getNewlinesBetweenErrors
can’t compute spacing and the rule silently skipsmissedSpacingBetweenMembers
/extraSpacingBetweenMembers
, so the documented newline guarantees never apply. Please hook up the standard helper.import { buildCustomGroupsArrayJsonSchema, partitionByCommentJsonSchema, partitionByNewLineJsonSchema, newlinesBetweenJsonSchema, commonJsonSchemas, groupsJsonSchema, } from '../utils/common-json-schemas' +import { getLinesBetween } from '../utils/get-lines-between' @@ reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenImportAttributes', extraSpacingBetweenMembers: 'extraSpacingBetweenImportAttributes', unexpectedGroupOrder: 'unexpectedImportAttributesGroupOrder', unexpectedOrder: 'unexpectedImportAttributesOrder', }, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), sourceCode, options, context,index.ts (1)
133-166
: Use const + satisfies for configsReplace
export let configs = { ... }
withexport const configs = { ... } satisfies Record<string, Linter.Config | Linter.LegacyConfig>
to make the object immutable and statically validated.Apply this diff:
-export let configs = { +export const configs = { 'recommended-alphabetical-legacy': createLegacyConfig({ type: 'alphabetical', order: 'asc', }), 'recommended-line-length-legacy': createLegacyConfig({ type: 'line-length', order: 'desc', }), 'recommended-natural-legacy': createLegacyConfig({ type: 'natural', order: 'asc', }), 'recommended-custom-legacy': createLegacyConfig({ type: 'custom', order: 'asc', }), 'recommended-alphabetical': createConfig({ type: 'alphabetical', order: 'asc', }), 'recommended-line-length': createConfig({ type: 'line-length', order: 'desc', }), 'recommended-natural': createConfig({ type: 'natural', order: 'asc', }), 'recommended-custom': createConfig({ type: 'custom', order: 'asc', }), -} +} satisfies Record<string, Linter.Config | Linter.LegacyConfig>test/rules/sort-imports.test.ts (1)
4312-4378
:@typescript-eslint/no-unsafe-call
is still firing on thesededent
templatesThe lint failure called out earlier hasn’t been addressed—
dedent\
...`is still used without a suppression, so
@typescript-eslint/no-unsafe-callwill continue to break the build on these lines. Please either drop in the one-line disable comments before each
dedentinvocation or switch to a typed alternative (e.g.,
dedent(String.raw`...`)`) as previously suggested.rules/sort-object-types.ts (1)
329-337
: Restore spacing diagnostics by wiringnewlinesBetweenValueGetter
.
reportAllErrors
still isn’t told how to compute blank lines, so everynewlinesBetween
violation silently passes. Add the getter (and its import) so spacing errors fire again.-import { reportAllErrors } from '../utils/report-all-errors' +import { reportAllErrors } from '../utils/report-all-errors' +import { getLinesBetween } from '../utils/get-lines-between' … reportAllErrors<MessageIds>({ sortNodesExcludingEslintDisabled, availableMessageIds, sourceCode, options, context, + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), nodes, })test/rules/sort-export-attributes.test.ts (6)
25-25
: Fix test title: "import" → "export"This test exercises export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts import attributes', async () => { + it('sorts export attributes', async () => {
50-50
: Fix test title: "import" → "export"This test exercises multiline export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts multiline import attributes', async () => { + it('sorts multiline export attributes', async () => {
276-276
: Fix test title: "import" → "export"This test exercises export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts import attributes', async () => { + it('sorts export attributes', async () => {
301-301
: Fix test title: "import" → "export"This test exercises multiline export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts multiline import attributes', async () => { + it('sorts multiline export attributes', async () => {
551-551
: Fix test title: "import" → "export"This test exercises export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts import attributes', async () => { + it('sorts export attributes', async () => {
576-576
: Fix test title: "import" → "export"This test exercises multiline export attributes, but the title says "import attributes".
Apply this diff:
- it('sorts multiline import attributes', async () => { + it('sorts multiline export attributes', async () => {docs/content/rules/sort-heritage-clauses.mdx (3)
152-159
: Fix terminology: "decorators" → "heritage clauses"; make flags optionalThe description incorrectly references "class decorators" and the RegExpPattern examples require flags when they should be optional.
Apply this diff:
-Enables the use of comments to separate class decorators into logical groups. +Enables the use of comments to separate heritage clauses into logical groups. -- `RegExpPattern = string | { pattern: string; flags: string}` — A regexp pattern to specify which comments should act as delimiters. +- `RegExpPattern = string | { pattern: string; flags?: string}` — A regexp pattern to specify which comments should act as delimiters.
168-176
: Expand newlinesBetween type and document 'always'/'never'The documented type is incomplete and the bullets don't describe 'always' and 'never' options.
Apply this diff:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'ignore' | 'always' | 'never' | number`</sub> Specifies how to handle newlines between groups. - `'ignore'` — Do not report errors related to newlines. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. - `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- Any positive number — Enforce exactly this number of blank lines between groups; forbid blank lines inside groups.
265-273
: Add 'custom' to type union; expand newlinesInside typeCustomGroupDefinition is missing 'custom' in the type field and newlinesInside should accept 'always' | 'never' in addition to number.
Apply this diff:
interface CustomGroupDefinition { groupName: string - type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' + type?: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' order?: 'asc' | 'desc' fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }docs/content/rules/sort-decorators.mdx (3)
255-263
: Expand newlinesBetween type and document 'always'/'never'The type annotation and bullets are incomplete.
Apply this diff:
-<sub>type: `number | 'ignore'`</sub> +<sub>type: `'ignore' | 'always' | 'never' | number`</sub> Specifies how to handle newlines between groups. - `'ignore'` — Do not report errors related to newlines. +- `'always'` — Require exactly one blank line between groups. +- `'never'` — Disallow blank lines between groups. - `0` — No newlines are allowed. -- Any other number — Enforce this number of newlines between each group, and forbid newlines inside groups. +- Any positive number — Enforce exactly this number of blank lines between groups; forbid blank lines inside groups.
352-359
: Correct CustomGroupDefinition typingsfallbackSort.type should be a specific union, and newlinesInside should accept 'always' | 'never' | number.
Apply this diff:
interface CustomGroupDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }
367-378
: Correct CustomGroupAnyOfDefinition typingsSame typing issues as CustomGroupDefinition.
Apply this diff:
interface CustomGroupAnyOfDefinition { groupName: string type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted' order?: 'asc' | 'desc' - fallbackSort?: { type: string; order?: 'asc' | 'desc' } - newlinesInside?: number + fallbackSort?: { + type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted' + order?: 'asc' | 'desc' + } + newlinesInside?: 'always' | 'never' | number anyOf: Array<{ selector?: string elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[] }> }rules/sort-heritage-clauses.ts (1)
193-206
: Provide newlinesBetweenValueGetter to enable spacing error reportingThe
reportAllErrors
call includes spacing-related message IDs (missedSpacingBetweenMembers
,extraSpacingBetweenMembers
) but doesn't provide the requirednewlinesBetweenValueGetter
parameter. This will prevent spacing violations from being detected.Apply this diff:
+import { getLinesBetween } from '../utils/get-lines-between' reportAllErrors<MessageId>({ availableMessageIds: { missedSpacingBetweenMembers: 'missedSpacingBetweenHeritageClauses', extraSpacingBetweenMembers: 'extraSpacingBetweenHeritageClauses', unexpectedGroupOrder: 'unexpectedHeritageClausesGroupOrder', unexpectedOrder: 'unexpectedHeritageClausesOrder', }, sortNodesExcludingEslintDisabled: createSortNodesExcludingEslintDisabled(nodes), + newlinesBetweenValueGetter: (left, right) => + getLinesBetween(sourceCode, left, right), sourceCode, options, context, nodes, })
🧹 Nitpick comments (1)
docs/content/rules/sort-object-types.mdx (1)
351-369
: LGTM! Clear documentation with practical example.The new
declarationCommentMatchesPattern
option is well documented with a practical use case (marking types that shouldn't be sorted via comments). The example code is clear and demonstrates the feature effectively.Optional: Consider adding a brief distinction note.
While the current documentation is clear, you could optionally add a sentence explicitly distinguishing this from
declarationMatchesPattern
:+- `declarationCommentMatchesPattern` — A regexp pattern to specify which comments above the type declaration should match. Unlike `declarationMatchesPattern` which matches the declaration name itself, this matches the comment content. - `declarationCommentMatchesPattern` — A regexp pattern to specify which comments above the type declaration should match.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
,!pnpm-lock.yaml
📒 Files selected for processing (69)
docs/content/rules/sort-array-includes.mdx
(3 hunks)docs/content/rules/sort-decorators.mdx
(5 hunks)docs/content/rules/sort-export-attributes.mdx
(1 hunks)docs/content/rules/sort-exports.mdx
(0 hunks)docs/content/rules/sort-heritage-clauses.mdx
(5 hunks)docs/content/rules/sort-import-attributes.mdx
(1 hunks)docs/content/rules/sort-imports.mdx
(1 hunks)docs/content/rules/sort-interfaces.mdx
(3 hunks)docs/content/rules/sort-intersection-types.mdx
(1 hunks)docs/content/rules/sort-jsx-props.mdx
(3 hunks)docs/content/rules/sort-named-exports.mdx
(0 hunks)docs/content/rules/sort-named-imports.mdx
(0 hunks)docs/content/rules/sort-object-types.mdx
(3 hunks)docs/content/rules/sort-objects.mdx
(4 hunks)docs/content/rules/sort-sets.mdx
(3 hunks)docs/public/llms.txt
(1 hunks)eslint.config.ts
(1 hunks)index.ts
(4 hunks)package.json
(4 hunks)readme.md
(1 hunks)rules/sort-array-includes.ts
(6 hunks)rules/sort-array-includes/types.ts
(0 hunks)rules/sort-classes.ts
(2 hunks)rules/sort-decorators.ts
(6 hunks)rules/sort-decorators/types.ts
(1 hunks)rules/sort-enums.ts
(6 hunks)rules/sort-export-attributes.ts
(1 hunks)rules/sort-export-attributes/types.ts
(1 hunks)rules/sort-exports.ts
(3 hunks)rules/sort-exports/types.ts
(0 hunks)rules/sort-heritage-clauses.ts
(6 hunks)rules/sort-heritage-clauses/types.ts
(1 hunks)rules/sort-import-attributes.ts
(1 hunks)rules/sort-import-attributes/types.ts
(1 hunks)rules/sort-imports.ts
(7 hunks)rules/sort-imports/types.ts
(1 hunks)rules/sort-interfaces.ts
(2 hunks)rules/sort-intersection-types.ts
(2 hunks)rules/sort-jsx-props.ts
(6 hunks)rules/sort-jsx-props/types.ts
(4 hunks)rules/sort-maps.ts
(4 hunks)rules/sort-modules.ts
(3 hunks)rules/sort-named-exports.ts
(3 hunks)rules/sort-named-exports/types.ts
(1 hunks)rules/sort-named-imports.ts
(3 hunks)rules/sort-named-imports/types.ts
(1 hunks)rules/sort-object-types.ts
(10 hunks)rules/sort-object-types/get-custom-groups-compare-options.ts
(3 hunks)rules/sort-object-types/types.ts
(3 hunks)rules/sort-objects.ts
(11 hunks)rules/sort-objects/types.ts
(5 hunks)rules/sort-sets.ts
(1 hunks)rules/sort-switch-case.ts
(3 hunks)rules/sort-union-types.ts
(2 hunks)rules/sort-variable-declarations.ts
(2 hunks)test/rules/sort-array-includes.test.ts
(12 hunks)test/rules/sort-decorators.test.ts
(2 hunks)test/rules/sort-enums.test.ts
(6 hunks)test/rules/sort-export-attributes.test.ts
(1 hunks)test/rules/sort-exports.test.ts
(0 hunks)test/rules/sort-heritage-clauses.test.ts
(5 hunks)test/rules/sort-import-attributes.test.ts
(1 hunks)test/rules/sort-imports.test.ts
(25 hunks)test/rules/sort-interfaces.test.ts
(16 hunks)test/rules/sort-jsx-props.test.ts
(35 hunks)test/rules/sort-named-exports.test.ts
(6 hunks)test/rules/sort-named-imports.test.ts
(6 hunks)test/rules/sort-object-types.test.ts
(19 hunks)test/rules/sort-object-types/get-custom-groups-compare-options.test.ts
(1 hunks)
💤 Files with no reviewable changes (6)
- rules/sort-exports/types.ts
- rules/sort-array-includes/types.ts
- docs/content/rules/sort-named-imports.mdx
- docs/content/rules/sort-exports.mdx
- docs/content/rules/sort-named-exports.mdx
- test/rules/sort-exports.test.ts
🚧 Files skipped from review as they are similar to previous changes (21)
- docs/content/rules/sort-import-attributes.mdx
- rules/sort-intersection-types.ts
- rules/sort-named-imports/types.ts
- docs/content/rules/sort-intersection-types.mdx
- rules/sort-imports/types.ts
- rules/sort-enums.ts
- rules/sort-export-attributes.ts
- test/rules/sort-enums.test.ts
- docs/content/rules/sort-sets.mdx
- docs/content/rules/sort-imports.mdx
- rules/sort-named-exports/types.ts
- rules/sort-variable-declarations.ts
- rules/sort-heritage-clauses/types.ts
- rules/sort-objects/types.ts
- rules/sort-classes.ts
- readme.md
- rules/sort-import-attributes/types.ts
- eslint.config.ts
- rules/sort-union-types.ts
- rules/sort-export-attributes/types.ts
- rules/sort-sets.ts
🧰 Additional context used
🧬 Code graph analysis (23)
rules/sort-object-types/get-custom-groups-compare-options.ts (1)
rules/sort-object-types/types.ts (1)
Options
(28-106)
rules/sort-exports.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-exports/types.ts (1)
Options
(25-57)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-modules.ts (2)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-modules/types.ts (1)
SortModulesOptions
(25-59)
rules/sort-objects.ts (5)
rules/sort-objects/types.ts (1)
Options
(25-120)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)rules/sort-objects/get-first-node-parent-with-type.ts (1)
getFirstNodeParentWithType
(21-46)
rules/sort-heritage-clauses.ts (11)
rules/sort-heritage-clauses/types.ts (1)
Options
(14-22)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)partitionByCommentJsonSchema
(241-262)newlinesBetweenJsonSchema
(146-158)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-decorators/types.ts (3)
types/common-options.ts (6)
CustomGroupsOption
(103-140)PartitionByCommentOption
(288-303)NewlinesBetweenOption
(203-226)GroupsOptions
(445-451)CommonOptions
(23-73)RegexOption
(477-477)types/sorting-node.ts (1)
SortingNode
(18-102)utils/common-json-schemas.ts (1)
regexJsonSchema
(219-228)
rules/sort-object-types.ts (3)
utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/filter-options-by-declaration-comment-matches.ts (1)
filterOptionsByDeclarationCommentMatches
(14-39)utils/matches.ts (1)
matches
(39-60)
rules/sort-named-imports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-imports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-switch-case.ts (1)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)
rules/sort-interfaces.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-object-types/types.ts (1)
Options
(28-106)rules/sort-object-types.ts (1)
sortObjectTypeElements
(152-338)
rules/sort-decorators.ts (7)
rules/sort-decorators/types.ts (1)
Options
(16-29)utils/common-json-schemas.ts (4)
buildCustomGroupsArrayJsonSchema
(302-351)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)
rules/sort-jsx-props.ts (3)
utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/matches.ts (1)
matches
(39-60)
test/rules/sort-import-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-jsx-props/types.ts (2)
types/common-options.ts (1)
CustomGroupsOption
(103-140)rules/sort-named-exports/types.ts (3)
SingleCustomGroup
(74-92)Selector
(109-109)allSelectors
(155-155)
rules/sort-imports.ts (5)
rules/sort-imports/types.ts (3)
Options
(29-141)Selector
(147-167)Modifier
(212-220)utils/common-json-schemas.ts (1)
buildCustomGroupsArrayJsonSchema
(302-351)utils/generate-predefined-groups.ts (1)
generatePredefinedGroups
(23-56)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)
rules/sort-object-types/types.ts (2)
types/common-options.ts (3)
RegexOption
(477-477)CustomGroupsOption
(103-140)FallbackSortOption
(319-331)types/join-with-dash.ts (1)
JoinWithDash
(4-4)
rules/sort-array-includes.ts (6)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-array-includes/types.ts (1)
Options
(24-68)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-import-attributes.ts (20)
rules/sort-import-attributes/types.ts (1)
Options
(45-77)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/is-sortable.ts (1)
isSortable
(7-9)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-45)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/validate-newlines-and-partition-configuration.ts (1)
validateNewlinesAndPartitionConfiguration
(98-119)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)types/sorting-node.ts (1)
SortingNode
(18-102)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)utils/range-to-diff.ts (1)
rangeToDiff
(32-41)utils/should-partition.ts (1)
shouldPartition
(69-95)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/common-json-schemas.ts (6)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)partitionByCommentJsonSchema
(241-262)partitionByNewLineJsonSchema
(268-272)newlinesBetweenJsonSchema
(146-158)groupsJsonSchema
(165-190)utils/report-errors.ts (4)
MISSED_SPACING_ERROR
(33-34)EXTRA_SPACING_ERROR
(30-31)GROUP_ORDER_ERROR
(27-28)ORDER_ERROR
(21-22)
test/rules/sort-export-attributes.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
rules/sort-named-exports.ts (5)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-named-exports/types.ts (1)
Options
(26-66)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/get-custom-groups-compare-options.ts (1)
buildGetCustomGroupOverriddenOptionsFunction
(137-148)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)
rules/sort-maps.ts (3)
rules/sort-array-includes.ts (1)
defaultOptions
(60-74)rules/sort-maps/types.ts (1)
Options
(20-64)utils/filter-options-by-all-names-match.ts (1)
filterOptionsByAllNamesMatch
(80-94)
test/rules/sort-imports.test.ts (1)
rules/sort-imports/types.ts (1)
Options
(29-141)
test/rules/sort-object-types/get-custom-groups-compare-options.test.ts (2)
rules/sort-interfaces.ts (1)
Options
(12-12)rules/sort-object-types/types.ts (1)
Options
(28-106)
🔇 Additional comments (29)
rules/sort-maps.ts (4)
25-25
: LGTM!The import change from
getMatchingContextOptions
tofilterOptionsByAllNamesMatch
improves code clarity with a more descriptive function name that better conveys the filtering behavior.
46-46
: LGTM!The type change from
Required<Options[0]>
toRequired<Options[number]>
adopts the idiomatic TypeScript pattern for referencing array element types, improving code consistency across the codebase.
81-88
: LGTM!The function call correctly adapts to the new
filterOptionsByAllNamesMatch
signature, passingnodeNames
andcontextOptions
as an object parameter while preserving the original logic.
235-235
: LGTM!Adding
defaultOptions
to the rule metadata exposes the default configuration, improving rule introspection and documentation. The duplication with the root-leveldefaultOptions
at line 239 is intentional per the migration objectives.test/rules/sort-named-exports.test.ts (3)
116-121
: LGTM! Clean migration to groups-based API.The error metadata has been correctly updated to use
unexpectedNamedExportsGroupOrder
withrightGroup
andleftGroup
fields for group-order violations. The migration from the deprecatedgroupKind
option to the array-basedgroups
format is properly implemented.Also applies to: 167-167
1486-1491
: LGTM! Consistent application across test sections.The migration pattern is consistently applied in the natural sorting tests, maintaining the same structure and error metadata as the alphabetical tests.
Also applies to: 1537-1537
2856-2861
: LGTM! Comprehensive test coverage across sorting types.The migration is consistently applied across alphabetical, natural, and line-length sorting tests, ensuring the new groups-based API functions correctly with all sorting methods.
Also applies to: 2907-2907
docs/content/rules/sort-object-types.mdx (2)
287-287
: LGTM! Type definition aligns with existing patterns.The
declarationCommentMatchesPattern
type definition correctly follows the same pattern as other regex-based filter options in the codebase.
306-319
: LGTM! Clear example of the new array-based API.The example effectively demonstrates the migration to array-based
customGroups
, showing how to define custom groups withgroupName
andelementNamePattern
properties. The RGB color sorting use case makes the feature easy to understand.rules/sort-decorators/types.ts (5)
1-14
: LGTM!Import structure is clean with appropriate type-only imports and a single utility import for schema validation.
16-29
: LGTM!Options type correctly uses
CustomGroupsOption<SingleCustomGroup>
without the deprecated alternative, aligning with the v5 API changes. The decorator-specific options (sortOn*) are appropriate for controlling where decorator sorting applies.
31-33
: LGTM!The
SingleCustomGroup
interface appropriately defines the structure for custom decorator grouping based on element name patterns.
35-37
: LGTM!Type aliases are well-defined.
SortDecoratorsSortingNode
correctly specializesSortingNode
for decorator nodes, and the internalGroup
type appropriately represents group identifiers.
39-41
: LGTM!The exported schema correctly maps
elementNamePattern
to the regex validation schema, enabling proper JSON schema validation for custom groups.index.ts (2)
6-7
: LGTM!New rule imports for
sort-import-attributes
andsort-export-attributes
follow the established import pattern and are correctly positioned alphabetically among other rule imports.
31-32
: LGTM!
PluginConfig
interface correctly extended with the new rule entries. Type annotations are appropriate and positioning follows the established order.rules/sort-named-imports.ts (4)
54-68
: LGTM!The
defaultOptions
declaration correctly usesRequired<Options[number]>
to ensure all optional fields have default values. The default values are appropriate for the sort-named-imports rule.
165-177
: LGTM!The refactored
sortNodesExcludingEslintDisabled
function correctly delegates tosortNodesByGroups
with proper options override viabuildGetCustomGroupOverriddenOptionsFunction
. This aligns with the group-based sorting approach adopted across the codebase.
179-192
: LGTM!The
reportAllErrors
invocation is correctly structured. The nodes are properly flattened, thesortNodesExcludingEslintDisabled
function is passed for sorting within error reporting, and all message IDs are appropriately mapped.
229-229
: LGTM!Exposing
defaultOptions
in the rule metadata is good practice, allowing consumers to inspect the default configuration programmatically.test/rules/sort-jsx-props.test.ts (2)
203-203
: LGTM! Group identifier renamed consistently.The group identifiers have been systematically updated from
shorthand
toshorthand-prop
andmultiline
tomultiline-prop
throughout all test cases. This aligns with the PR objective to remove deprecated APIs and standardize naming.Also applies to: 224-224, 259-259, 284-284, 1538-1538, 1559-1559, 1594-1594, 1619-1619, 2866-2866, 2887-2887, 2922-2922, 2947-2947
329-335
: LGTM! Comprehensive migration to array-based customGroups API.The test file demonstrates a thorough migration from an object-based customGroups API to an array-based API. The new structure provides:
- Better support for multiple custom groups with the same matching criteria
- Cleaner syntax with explicit
groupName
properties- Support for advanced features like
elementNamePattern
,elementValuePattern
,modifiers
, andanyOf
- Per-group configuration overrides (type, order, fallbackSort)
The migration is systematic and covers all test scenarios comprehensively.
Also applies to: 867-872, 933-942, 976-997, 1079-1092, 1188-1199, 1248-1267, 1664-1670, 2202-2207, 2268-2277, 2311-2332, 2414-2427, 2999-3004, 3537-3542, 3603-3612, 3646-3667, 3749-3762
rules/sort-imports.ts (7)
68-70
: LGTM! Type refinement aligns with array-based Options.The type change from
Options
toOptions[number]
correctly reflects thatOptions
is now an array type (as defined at line 28 of rules/sort-imports/types.ts). Using indexed access type[number]
extracts the element type of the array.
109-109
: LGTM! Simplified validation call.Passing the full
options
object directly tovalidateGeneratedGroupsConfiguration
is cleaner than the previous approach of wrapping/extracting specific properties. This aligns with the removal of deprecated API patterns.
115-115
: LGTM! Cleaner tsconfig configuration structure.The migration from
options.tsconfigRootDir
tooptions.tsconfig?.rootDir
provides a better-organized API by grouping TypeScript configuration under a singletsconfig
object. This is a breaking change but aligns with the PR objectives to remove deprecated APIs.
313-313
: LGTM! Consistent removal of options wrapping.Passing the full
options
object directly togetCustomGroupOverriddenOptions
andreportAllErrors
is more straightforward and eliminates unnecessary wrapping layers. This simplification is consistent with the changes at line 109.Also applies to: 368-368
425-427
: LGTM! Schema migration to array-based customGroups.The use of
buildCustomGroupsArrayJsonSchema({ singleCustomGroupJsonSchema })
aligns with the comprehensive migration to an array-based customGroups API seen throughout the codebase. This provides better JSON schema validation for the new API structure.
533-564
: LGTM! Clean helper function for group computation.The new
computeGroupExceptUnknown
function provides a cleaner abstraction by:
- Encapsulating the group computation logic
- Returning
null
when the computed group is 'unknown', allowing the caller to provide a fallback- Accepting a properly typed subset of options (omitting
maxLineLength
andtsconfig
which aren't needed for group computation)This improves code organization and makes the intent clearer at the call site (lines 223-228).
453-453
: No action needed:defaultOptions
duplication is intentional and consistent All rules (includingsort-imports.ts
) declaredefaultOptions
inmeta
and at the root; this matches the project pattern.
groups: ['r', 'g', 'b'], // Sort tag with colors keys by RGB | ||
customGroups: { | ||
r: '^r$', | ||
g: '^g$', | ||
b: '^b$', | ||
}, | ||
customGroups: [ | ||
{ | ||
groupName: 'r', | ||
elementNamePattern: '^r$', | ||
}, | ||
{ | ||
groupName: 'g', | ||
elementNamePattern: '^g$', | ||
}, | ||
{ | ||
groupName: 'b', | ||
elementNamePattern: '^b$', | ||
}, | ||
], | ||
useConfigurationIf: { | ||
allNamesMatchPattern: '^r|g|b$', | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the RGB regex example.
'^r|g|b$'
is parsed as (^r)
or g
or (b$)
, so it matches many names that do not start/end with the intended letters. Please wrap the alternatives in a single, anchored group.
- allNamesMatchPattern: '^r|g|b$',
+ allNamesMatchPattern: '^(?:r|g|b)$',
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
groups: ['r', 'g', 'b'], // Sort tag with colors keys by RGB | |
customGroups: { | |
r: '^r$', | |
g: '^g$', | |
b: '^b$', | |
}, | |
customGroups: [ | |
{ | |
groupName: 'r', | |
elementNamePattern: '^r$', | |
}, | |
{ | |
groupName: 'g', | |
elementNamePattern: '^g$', | |
}, | |
{ | |
groupName: 'b', | |
elementNamePattern: '^b$', | |
}, | |
], | |
useConfigurationIf: { | |
allNamesMatchPattern: '^r|g|b$', | |
}, | |
groups: ['r', 'g', 'b'], // Sort tag with colors keys by RGB | |
customGroups: [ | |
{ | |
groupName: 'r', | |
elementNamePattern: '^r$', | |
}, | |
{ | |
groupName: 'g', | |
elementNamePattern: '^g$', | |
}, | |
{ | |
groupName: 'b', | |
elementNamePattern: '^b$', | |
}, | |
], | |
useConfigurationIf: { | |
allNamesMatchPattern: '^(?:r|g|b)$', | |
}, |
🤖 Prompt for AI Agents
In docs/content/rules/sort-jsx-props.mdx around lines 269 to 286, the regex
'^r|g|b$' is incorrectly anchored and thus matches unintended names; replace it
with a single anchored alternation such as '^(r|g|b)$' or '^(?:r|g|b)$' so the
pattern matches only names that are exactly "r", "g", or "b".
export let rules = { | ||
'sort-variable-declarations': sortVariableDeclarations, | ||
'sort-intersection-types': sortIntersectionTypes, | ||
'sort-import-attributes': sortImportAttributes, | ||
'sort-export-attributes': sortExportAttributes, | ||
'sort-heritage-clauses': sortHeritageClauses, | ||
'sort-array-includes': sortArrayIncludes, | ||
'sort-named-imports': sortNamedImports, | ||
'sort-named-exports': sortNamedExports, | ||
'sort-object-types': sortObjectTypes, | ||
'sort-union-types': sortUnionTypes, | ||
'sort-switch-case': sortSwitchCase, | ||
'sort-decorators': sortDecorators, | ||
'sort-interfaces': sortInterfaces, | ||
'sort-jsx-props': sortJsxProps, | ||
'sort-modules': sortModules, | ||
'sort-classes': sortClasses, | ||
'sort-imports': sortImports, | ||
'sort-exports': sortExports, | ||
'sort-objects': sortObjects, | ||
'sort-enums': sortEnums, | ||
'sort-sets': sortSets, | ||
'sort-maps': sortMaps, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Use const for the rules export.
The rules
object is part of the public API and should be immutable to prevent accidental modification.
Apply this diff:
-export let rules = {
+export const rules = {
'sort-variable-declarations': sortVariableDeclarations,
'sort-intersection-types': sortIntersectionTypes,
'sort-import-attributes': sortImportAttributes,
'sort-export-attributes': sortExportAttributes,
'sort-heritage-clauses': sortHeritageClauses,
'sort-array-includes': sortArrayIncludes,
'sort-named-imports': sortNamedImports,
'sort-named-exports': sortNamedExports,
'sort-object-types': sortObjectTypes,
'sort-union-types': sortUnionTypes,
'sort-switch-case': sortSwitchCase,
'sort-decorators': sortDecorators,
'sort-interfaces': sortInterfaces,
'sort-jsx-props': sortJsxProps,
'sort-modules': sortModules,
'sort-classes': sortClasses,
'sort-imports': sortImports,
'sort-exports': sortExports,
'sort-objects': sortObjects,
'sort-enums': sortEnums,
'sort-sets': sortSets,
'sort-maps': sortMaps,
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export let rules = { | |
'sort-variable-declarations': sortVariableDeclarations, | |
'sort-intersection-types': sortIntersectionTypes, | |
'sort-import-attributes': sortImportAttributes, | |
'sort-export-attributes': sortExportAttributes, | |
'sort-heritage-clauses': sortHeritageClauses, | |
'sort-array-includes': sortArrayIncludes, | |
'sort-named-imports': sortNamedImports, | |
'sort-named-exports': sortNamedExports, | |
'sort-object-types': sortObjectTypes, | |
'sort-union-types': sortUnionTypes, | |
'sort-switch-case': sortSwitchCase, | |
'sort-decorators': sortDecorators, | |
'sort-interfaces': sortInterfaces, | |
'sort-jsx-props': sortJsxProps, | |
'sort-modules': sortModules, | |
'sort-classes': sortClasses, | |
'sort-imports': sortImports, | |
'sort-exports': sortExports, | |
'sort-objects': sortObjects, | |
'sort-enums': sortEnums, | |
'sort-sets': sortSets, | |
'sort-maps': sortMaps, | |
} | |
export const rules = { | |
'sort-variable-declarations': sortVariableDeclarations, | |
'sort-intersection-types': sortIntersectionTypes, | |
'sort-import-attributes': sortImportAttributes, | |
'sort-export-attributes': sortExportAttributes, | |
'sort-heritage-clauses': sortHeritageClauses, | |
'sort-array-includes': sortArrayIncludes, | |
'sort-named-imports': sortNamedImports, | |
'sort-named-exports': sortNamedExports, | |
'sort-object-types': sortObjectTypes, | |
'sort-union-types': sortUnionTypes, | |
'sort-switch-case': sortSwitchCase, | |
'sort-decorators': sortDecorators, | |
'sort-interfaces': sortInterfaces, | |
'sort-jsx-props': sortJsxProps, | |
'sort-modules': sortModules, | |
'sort-classes': sortClasses, | |
'sort-imports': sortImports, | |
'sort-exports': sortExports, | |
'sort-objects': sortObjects, | |
'sort-enums': sortEnums, | |
'sort-sets': sortSets, | |
'sort-maps': sortMaps, | |
} |
🤖 Prompt for AI Agents
In index.ts around lines 75 to 98, the export uses "let rules" which allows
reassignment; change it to "export const rules" so the rules object is immutable
as part of the public API, and scan the repo for any reassignment or mutation
sites (remove or update them) to ensure no code expects rules to be re-bound or
reassigned.
let { fallbackSort, customGroups, sortBy, groups } = options | ||
let fallbackSortBy = fallbackSort.sortBy | ||
if (Array.isArray(customGroups)) { | ||
let group = groups[groupIndex] | ||
let customGroup = | ||
typeof group === 'string' | ||
? customGroups.find(currentGroup => group === currentGroup.groupName) | ||
: null | ||
let group = groups[groupIndex] | ||
let customGroup = | ||
typeof group === 'string' | ||
? customGroups.find(currentGroup => group === currentGroup.groupName) | ||
: null | ||
|
||
if (customGroup) { | ||
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy | ||
if ('sortBy' in customGroup && customGroup.sortBy) { | ||
;({ sortBy } = customGroup) | ||
} | ||
if (customGroup) { | ||
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy | ||
if ('sortBy' in customGroup && customGroup.sortBy) { | ||
;({ sortBy } = customGroup) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore custom overrides for grouped entries.
After removing the old object-map path we now only look up overrides when group
is a string. For group blocks like ['index-signature', 'member']
(or any array entry produced by GroupsOptions
) we never resolve the corresponding customGroup
, so per-group sortBy
/fallbackSort
overrides stop applying. This breaks existing configurations that combine groups.
Please collect all group names (strings inside arrays) before searching the customGroups
list so the override still kicks in for grouped entries.
- let group = groups[groupIndex]
- let customGroup =
- typeof group === 'string'
- ? customGroups.find(currentGroup => group === currentGroup.groupName)
- : null
+ let group = groups[groupIndex]
+ let groupNames =
+ typeof group === 'string'
+ ? [group]
+ : Array.isArray(group)
+ ? group
+ : []
+ let customGroup =
+ groupNames
+ .map(name =>
+ customGroups.find(currentGroup => currentGroup.groupName === name),
+ )
+ .find(
+ (matchedGroup): matchedGroup is (typeof customGroups)[number] =>
+ Boolean(matchedGroup),
+ ) ?? null
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
let { fallbackSort, customGroups, sortBy, groups } = options | |
let fallbackSortBy = fallbackSort.sortBy | |
if (Array.isArray(customGroups)) { | |
let group = groups[groupIndex] | |
let customGroup = | |
typeof group === 'string' | |
? customGroups.find(currentGroup => group === currentGroup.groupName) | |
: null | |
let group = groups[groupIndex] | |
let customGroup = | |
typeof group === 'string' | |
? customGroups.find(currentGroup => group === currentGroup.groupName) | |
: null | |
if (customGroup) { | |
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy | |
if ('sortBy' in customGroup && customGroup.sortBy) { | |
;({ sortBy } = customGroup) | |
} | |
if (customGroup) { | |
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy | |
if ('sortBy' in customGroup && customGroup.sortBy) { | |
;({ sortBy } = customGroup) | |
} | |
let { fallbackSort, customGroups, sortBy, groups } = options | |
let fallbackSortBy = fallbackSort.sortBy | |
let group = groups[groupIndex] | |
let groupNames = | |
typeof group === 'string' | |
? [group] | |
: Array.isArray(group) | |
? group | |
: [] | |
let customGroup = | |
groupNames | |
.map(name => | |
customGroups.find(currentGroup => currentGroup.groupName === name), | |
) | |
.find( | |
(matchedGroup): matchedGroup is (typeof customGroups)[number] => | |
Boolean(matchedGroup), | |
) ?? null | |
if (customGroup) { | |
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy | |
if ('sortBy' in customGroup && customGroup.sortBy) { | |
;({ sortBy } = customGroup) | |
} |
🤖 Prompt for AI Agents
In rules/sort-object-types/get-custom-groups-compare-options.ts around lines 43
to 55, the current logic only finds a customGroup when group is a string and
therefore misses overrides when group is an array (e.g.,
['index-signature','member']). Update the lookup so if group is an array you
first collect all string names from that array (e.g., filter/map to strings),
then search customGroups for any entry whose groupName matches any of those
names; use the first match as customGroup, then apply its fallbackSort.sortBy
and sortBy overrides exactly as you do now for string groups so per-group
overrides still take effect for grouped entries.
Close #566.