npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-plugin-sonar-config

v0.1.3

Published

ESLint plugin com regras customizadas para melhorar a qualidade de código em projeto com Sonar implementado.

Downloads

582

Readme

eslint-plugin-sonar-config

Preset ESLint auto-contido que replica o perfil SonarJS para JS/React. Combina ESLint core + 7 plugins oficiais (react, react-hooks, jsx-a11y, sonarjs, unicorn, import, jest) + 13 customs, cobrindo 165 regras em cada preset.

Entrega dois presets tunados para contextos diferentes:

  • modules-legacy — React 16, JS puro, módulos Liferay legado (.eslintrc.js)
  • flat/client-extension — React 18+, TypeScript, client extensions modernos (eslint.config.js)

Instalação

Auto-contido — os plugins externos vêm como deps transitivas:

npm install --save-dev eslint eslint-plugin-sonar-config

eslint-plugin-jest é optionalDependency — instalado por padrão mas ignorado silenciosamente se o projeto remover, e as regras jest/* saem do preset automaticamente.

Uso — Client Extension (moderno)

Pensado pra código moderno: React 18+, TypeScript, hooks only, eslint.config.js.

const sonarConfig = require("eslint-plugin-sonar-config");

module.exports = [
  sonarConfig.configs["flat/client-extension"],
];

Ou equivalente com o alias flat/recommended:

module.exports = [sonarConfig.configs["flat/recommended"]];

Uma linha. Plugins já registrados, settings.react.version = "detect".

Versão ESM:

import sonarConfig from "eslint-plugin-sonar-config";
export default [sonarConfig.configs["flat/client-extension"]];

Características deste preset:

  • no-unused-vars desativado — delega pra @typescript-eslint/no-unused-vars que o consumer ativa
  • react/no-deprecated = error
  • react-hooks/rules-of-hooks = error, exhaustive-deps = warn
  • react/hook-use-state = error
  • no-var = error

Uso — Modules Legacy

Pensado pro Liferay legado: React 16, JS puro, jQuery/AUI, modules/**.

// .eslintrc.js
module.exports = {
  extends: ["plugin:sonar-config/modules-legacy"],
  // ...resto da sua config
};

Ou equivalente com o alias recommended:

extends: ["plugin:sonar-config/recommended"]

Características deste preset:

  • no-unused-vars = error com varsIgnorePattern: "^React$|^Component$" e argsIgnorePattern: "^_"
  • no-var = warn (legado tem muito var, não bloqueia build)
  • react/no-deprecated = off (componentWillMount etc ainda aparecem)
  • react-hooks/rules-of-hooks = warn (mistura class + FC)
  • react/hook-use-state = off
  • sonar-config/no-this-in-functional-component = off (classes existem)
  • react/no-access-state-in-setstate = error (classes existem)
  • settings.react.version = "16"

Se quiser customizar alguma regra, basta adicionar um bloco depois:

export default [
  sonarConfig.configs["flat/recommended"],
  {
    rules: {
      "react/jsx-key": "warn",          // downgrade
      "sonar-config/no-infinite-loop": "off",  // desativa uma custom
    },
  },
];

Legacy config (.eslintrc.js)

module.exports = {
  extends: ["plugin:sonar-config/recommended"],
};

Uma linha no extends. O preset legacy já declara internamente os 8 plugins (sonar-config + 7 externos) no array plugins, e o ESLint legacy resolve cada pacote a partir do node_modules (os plugins vêm via dependencies transitivas).

Se o projeto já tem outros plugins ou settings, basta compor:

module.exports = {
  extends: [
    "plugin:sonar-config/recommended",
    "plugin:prettier/recommended",
  ],
  plugins: ["prettier"],
  rules: {
    "react/prop-types": "off",
  },
};

⚠️ Versões internas fixadas:

  • eslint-plugin-sonarjs@^4 — catálogo completo usado pelo preset
  • eslint-plugin-unicorn@^56 — v57+ é ESM-only, incompatível com workspaces CommonJS

Regras customizadas deste plugin (13)

Apenas as regras Sonar que não têm equivalente funcional em ESLint core, plugins oficiais ou sonarjs v4 (sem type info do TS):

| Regra | Sonar ID | Descrição | |---|---|---| | await-only-promises | — | await só em Promises | | no-this-in-functional-component | — | Não usar this em componentes funcionais | | prefer-for-of | — | Prefere for…of a for (let i…) | | array-method-missing-args | — | push() / unshift() sem argumento | | no-misleading-array-mutation | — | const b = a.reverse() é enganoso | | no-unsafe-window-open | — | window.open sem noopener/noreferrer | | no-useless-async | S4326 | async sem nenhum await no corpo | | no-infinite-loop | S2189 | Loops sem break/return/throw | | no-array-delete | S2870 | Proíbe delete arr[i] | | no-index-of-compare-positive | S2692 | Evita indexOf(x) > 0 (ignora o primeiro elemento) | | prefer-regex-exec | S6594 | Prefere regex.exec() em certos contextos | | no-internal-api | S6627 | Acesso a APIs internas (_*) de libs externas | | no-non-numeric-array-index | — | Não usar chave não-numérica em array |

Regras marcadas com Sonar ID existem como sonarjs/* na v4, mas exigem @typescript-eslint/parser com type info — silenciosamente não-op em JS/JSX puro. Por isso mantemos customs.

Rodando os testes das customs

npm test

Usa o RuleTester oficial do ESLint. Cobre casos positivos e negativos pras 13 customs.

Regras Sonar não cobertas

Duas regras Sonar não têm implementação viável apenas em JavaScript (sem TypeScript) e foram deixadas fora do preset:

  • Boolean literals should not be used in comparisons — só existe em @typescript-eslint/no-unnecessary-boolean-literal-compare (requer type info)
  • Optional chaining should be preferred — sem regra JS-only confiável; use @typescript-eslint/prefer-optional-chain em projetos TS

Mapeamento completo

Veja .planning/sonar-rules-mapping.md para a tabela completa: cada uma das 164 regras Sonar e qual regra ESLint core/plugin/custom a implementa.

Integração com a CLI SEA-LI

Este preset é consumido automaticamente pela CLI de qualidade de código Liferay.

Desenvolvimento

eslint-plugin-sonar-config/
├── index.js              # Preset + registro das customs
├── package.json
├── README.MD
├── .planning/
│   └── sonar-rules-mapping.md   # Mapeamento Sonar → ESLint
└── rules/                # 18 regras custom

Testando localmente

npm link
# no projeto de teste:
npm link eslint-plugin-sonar-config