feat(eslint-plugin-azure-sdk): add opt-in recommendedStrict preset with sonarjs integration#38405
Draft
feat(eslint-plugin-azure-sdk): add opt-in recommendedStrict preset with sonarjs integration#38405
recommendedStrict preset with sonarjs integration#38405Conversation
- Add eslint-plugin-sonarjs ^3.0.2 as peer and dev dependency - New src/configs/recommended-strict.ts with recommendedStrictDelta() - New configs: recommendedStrict and recommendedStrictTypeChecked in index - New configStrict() helper in src/index.ts - Updated README.md with new preset documentation - Added unit tests in tests/configs/recommended-strict.spec.ts Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-js/sessions/ecc2227a-f6b0-4267-8109-ac71ae35fdcd Co-authored-by: jeremymeng <7583839+jeremymeng@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-js/sessions/ecc2227a-f6b0-4267-8109-ac71ae35fdcd Co-authored-by: jeremymeng <7583839+jeremymeng@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add recommendedStrict preset to eslint-plugin-azure-sdk
feat(eslint-plugin-azure-sdk): add opt-in May 4, 2026
recommendedStrict preset with sonarjs integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds two new opt-in ESLint configs to
@azure/eslint-plugin-azure-sdktargeting AI-generated and hard-to-maintain code patterns. The new presets are purely additive — existingrecommended/recommendedTypeCheckedconsumers see zero change.Packages impacted by this PR
@azure/eslint-plugin-azure-sdk(common/tools/eslint-plugin-azure-sdk)Issues associated with this PR
N/A
Describe the problem that is addressed by this PR
The existing
recommendedpreset has no structural complexity caps or code-smell detection. As AI agents generate more SDK code, reviewers need a single opt-in switch to catch overly complex, redundant, dead, or hard-to-read code that wouldn't otherwise be flagged.What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen?
Option A (chosen): A delta function
recommendedStrictDelta({ typeChecked })that returns only the additional rules, composed withrecommendedat config-export time. This keeps the strict rules isolated from the base preset and makes the type-checked split explicit with a single boolean. Consumers referenceazsdkEslint.configs.recommendedStrictorrecommendedStrictTypeCheckeddirectly.Option B: Bake strict rules into
recommendedbehind a flag. Rejected — would affect all existing consumers and make the type-checked distinction harder to reason about.Changes
package.json:eslint-plugin-sonarjs ^3.0.2added topeerDependenciesanddevDependencies. Version 3.0.7 installed (ESLint 9 flat-config compatible; exportsconfigs.recommendedas a single flat-config object).New
src/configs/recommended-strict.ts: ExportsrecommendedStrictDelta({ typeChecked }). Rule groups:max-lines-per-function(100),max-classes-per-file(1),@typescript-eslint/max-params(7),sonarjs/cognitive-complexity(15)no-nested-ternary,no-unneeded-ternary,no-implicit-coercion,no-lonely-if,no-else-returnno-param-reassignpromoted toerror+props: true;@typescript-eslint/prefer-readonly(type-checked)curly: all(overridesmulti-line);default-case;@typescript-eslint/switch-exhaustiveness-check(type-checked)no-duplicate-imports;@typescript-eslint/consistent-type-importspromoted toerror;@typescript-eslint/no-deprecated(type-checked)no-empty(noallowEmptyCatch);@typescript-eslint/only-throw-error/use-unknown-in-catch-callback-variable(type-checked)no-await-in-loop(warn),no-promise-executor-return,@typescript-eslint/return-await(type-checked)no-useless-rename/return/concat;@typescript-eslint/no-unnecessary-condition/type-arguments/template-expression(type-checked)sonarjs/recommendedbase withno-duplicate-string,no-commented-code, andtodo-tagsilenced;no-hardcoded-ipkept atwarnsrc/configs/index.ts: AddsrecommendedStrictandrecommendedStrictTypeCheckedexports. No changes to existing configs.src/index.ts: AddsconfigStrict()convenience helper (mirrorsconfig()but spreadsrecommendedStrict).README.md: Documents new configs,configStrict()helper, peer dep, and rule categories.Usage:
Are there test cases added in this PR? (If not, why?)
Yes —
tests/configs/recommended-strict.spec.ts(Vitest). Covers:recommendedStrictDelta({ typeChecked: false }): asserts presence of always-on rules and absence of type-checked-only rulesrecommendedStrictDelta({ typeChecked: true }): asserts all type-checked rules are includedrecommendedStrictandrecommendedStrictTypeCheckedare defined and non-emptyrecommendedrule values (curly: multi-line,no-param-reassign: warn/props:false) are unchanged after this PRProvide a list of related PRs (if any)
None
Checklists
Original prompt
Goal
Add a new opt-in
recommendedStrictpreset to@azure/eslint-plugin-azure-sdkthat layers a curated set of additional maintainability and code-smell rules on top of the existingrecommendedpreset. The intent is to give package authors (and reviewers of AI-generated code) a single switch they can flip to catch overly complex, redundant, dead, or hard-to-read code that AI agents commonly produce.This preset must be purely additive and opt-in:
azsdkEslint.configs.recommended,recommendedTypeChecked,internal, or theazsdkEslint.config()helper. Existing packages that don't opt in must see zero rule changes.recommended-type-checkedcallers must also be unaffected unless they explicitly opt in.Scope of files in this PR
All work is inside
common/tools/eslint-plugin-azure-sdk/. Do NOT modify any package'seslint.config.*file undersdk/**or any other consumer in this PR — adoption is a separate effort.Required changes
1. Add
eslint-plugin-sonarjsas a peer dependencyEdit
common/tools/eslint-plugin-azure-sdk/package.json:"eslint-plugin-sonarjs": "^3.0.2"(or the latest 3.x at install time that supports ESLint 9 flat config) underpeerDependencies, alphabetically placed.devDependenciesso the plugin's own build/lint step can resolve it.configs.recommendedas a flat-config object compatible with ESLint 9 andtypescript-eslint8.x. If 3.x has issues, fall back to^2.0.4. Document whichever version you pick in the PR description.2. Create a new file:
src/configs/recommended-strict.tsThis file defines the strict-only delta — i.e. ONLY the rules that go beyond what
recommended/recommendedTypeCheckedalready enable. It must export:The delta should include the rules below. Group rules logically with comments. Use
errorseverity unless noted; for highly noisy rules usewarnand add a// TODOcomment explaining the intent so we can promote later.Structural caps (always on, no type info needed)
max-lines-per-function:["error", { max: 100, skipBlankLines: true, skipComments: true, IIFEs: true }]max-classes-per-file:["error", 1]max-params:"off"— disable core in favor of TS extension@typescript-eslint/max-params:["error", { max: 7, countVoidThis: false }]sonarjs/cognitive-complexity:["error", 15]Anti-"clever one-liner" (always on)
no-nested-ternary:"error"no-unneeded-ternary:"error"no-implicit-coercion:"error"no-lonely-if:"error"no-else-return:["error", { allowElseIf: false }]Mutation / scoping (always on)
no-param-reassign:["error", { props: true }]— note: existingeslint-customized.tssets this to["warn", { props: false }]; the strict preset must override it.@typescript-eslint/no-shadow:["error", { ignoreTypeValueShadow: true }]— already error in customized; keep consistent.@typescript-eslint/prefer-readonly:"error"(type-checked only — see below)Switch / control flow (always on)
curly:["error", "all"]— note: existingeslint-customized.tssets this to["error", "multi-line"]; the strict preset must override it.default-case:"error"default-case-last:"error"consistent-return:"off"— disable core in favor of TS extension@typescript-eslint/consistent-return:"error"(type-checked only)@typescript-eslint/switch-exhaustiveness-check:"error"(type-checked only)Imports (always on)
no-duplicate-imports:"error"@typescript-eslint/consistent-type-imports:"error"(existing customized has"warn"; strict promotes to error)@typescript-eslint/no-import-type-side-effects:"error"@typescript-eslint/no-deprecated:"error"(type-checked only)Errors thrown / caught (always on)
no-empty:["error", { allowEmptyCatch: false }]@typescript-eslint/only-throw-error:"error"(type-checked only)@typescript-eslint/use-unknown-in-catch-callback-variable:"error"(type-checked only)@typescript-eslint/prefer-promise-reject-errors:"error"(type-checked only)Async safety (type-checked only)
@typescript-eslint/return-await:["error", "in-try-catch"]no-await-in-loop:"warn"— TODO: promote after auditno-promise-executor-return:"error"require-atomic-updates:"error"Dead / redundant code (type-checked only)
@typescript-eslint/no-unnecessary-condition:"error"@typescript-eslint/no-unnecessary-type-arguments:"error"@typescript-eslint/no-unnecessary-template-expression:"error"no-useless-rename:"error"no-useless-return:"error"-...
This pull request was created from Copilot chat.