feat: add support for the strategy parameter in component-name-unique rule - #3011
feat: add support for the strategy parameter in component-name-unique rule#3011harshit078 wants to merge 10 commits into
Conversation
🦋 Changeset detectedLatest commit: cd72939 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Performance Benchmark (Lower is Faster)
|
|
Interesting idea! |
kanoru3101
left a comment
There was a problem hiding this comment.
Thank you for your contribution.
Three descriptions now behave differently under lint and bundle: two in my comments, plus the Bugbot one above — that one is correct, I reproduced it.
Left to do:
- make the rule agree with the bundler in all three cases;
- mirror the bundler's tests — none of the three cases is covered today.
The rest is in the inline comments.
| if ( | ||
| !useTitleStrategy || | ||
| typeName !== TYPE_NAME_SCHEMA || | ||
| resolved.location.source.absoluteRef === rootSourceRef |
There was a problem hiding this comment.
The rule skips the title strategy for every schema in the root file. The bundle command does not skip those schemas. It renames a root schema if an external file refers to it. So two schemas end up wanting the same name and the rule stays quiet.
Example
# openapi.yaml
components:
schemas:
Foo:
title: Bar thing
type: object
# ...a response in this file refers to ./Other.yaml
# Other.yaml
title: Bar thing
type: object
properties:
inner:
$ref: './openapi.yaml#/components/schemas/Foo'
The bundle is still written, but Other.yaml gets Other, not the name from its title. The rule sees no problem here, the bundler does — both should see the same. Please check where the $ref comes from, not only where it points.
|
|
||
| const { node } = resolved; | ||
| const title = isPlainObject(node) && isString(node.title) ? node.title.trim() : ''; | ||
| return title === '' ? null : componentNameFromTitle(title); |
There was a problem hiding this comment.
If a schema has no title, the rule uses the file name and says nothing. The bundler doesn't — it stops.
# openapi.yaml
openapi: 3.0.0
info:
title: Referenced schema without a title
version: 1.0.0
paths:
/carts:
get:
responses:
'200':
description: ok
content:
application/json:
schema:
$ref: './Cart.yaml'
# Cart.yaml — no title here
type: object
properties:
total:
type: number
Lint says the description is fine, and then there is no bundle at all. The two commands disagree again, and this is the most common way the title strategy breaks — so the rule should report it:
| } | ||
|
|
||
| const { node } = resolved; | ||
| const title = isPlainObject(node) && isString(node.title) ? node.title.trim() : ''; |
There was a problem hiding this comment.
This duplicates code that already exists; you should consider reusing the existing logic
| addComponentFromAbsoluteLocation(typeName, resolvedRef.location); | ||
| const titleName = getTitleComponentName(typeName, resolvedRef); | ||
| if (titleName) { | ||
| addFoundComponent(typeName, titleName, resolvedRef.location); |
There was a problem hiding this comment.
The report points at the start of the file, but the line to change is title. Pass resolvedRef.location.child('title') here — the same place the bundler reports at bundle-visitor.ts.
Co-authored-by: Viktor Sydor <31951646+kanoru3101@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cd72939. Configure here.
| resolved.location.source.absoluteRef === rootSourceRef | ||
| ) { | ||
| return null; | ||
| } |
There was a problem hiding this comment.
Root schemas skip title strategy
High Severity
getTitleComponentName returns null for every schema whose target lives in the root file. bundle only skips renaming when both the target and the $ref are in the root; an external file that references a root schema still renames it from title. Collisions between that renamed root schema and another title-named schema go unreported.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit cd72939. Configure here.
| addComponentFromAbsoluteLocation(typeName, resolvedRef.location); | ||
| const titleName = getTitleComponentName(typeName, resolvedRef); | ||
| if (titleName) { | ||
| addFoundComponent(typeName, titleName, resolvedRef.location); |
There was a problem hiding this comment.
Reports point at file root
Medium Severity
When the title strategy records a component, it stores resolvedRef.location, so collisions report at the file root. The field that determines the bundled name is title; bundle-visitor.ts reports at location.child('title') for the same reason.
Reviewed by Cursor Bugbot for commit cd72939. Configure here.


What/Why/How?
#2898
Reference
Testing
Screenshots (optional)
Check yourself
Security
Note
Low Risk
Lint/bundle naming alignment only; default behavior unchanged and coverage is strong. Misconfigured strategy could cause false positives/negatives relative to bundle, not runtime security issues.
Overview
Adds a
strategyoption (basenameortitle, defaultbasename) to thecomponent-name-uniquerule so lint can predict the component keysbundlewill produce when using--component-names-strategy.With
strategy: title, externally referenced schemas are checked for collisions on title-derived names (PascalCase + sanitization), not file basename—matchingtitlebundling. Schemas in the rootcomponents/schemasstill use their keys; referenced schemas withouttitlefall back to basename-based naming.Title-to-name logic is moved into shared
componentNameFromTitleand reused inbundle-visitor(replacing inline logic). Docs for the rule andbundlecommand are updated; tests cover title strategy cases.Reviewed by Cursor Bugbot for commit cd72939. Bugbot is set up for automated code reviews on this repo. Configure here.