@mocoto/mahoraga 0.14.3 → 0.14.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/analysts/architects/archetypes-custom.js +1 -1
- package/dist/analysts/architects/detector-archetypes.js +1 -0
- package/dist/analysts/architects/strategist-structure.js +1 -1
- package/dist/analysts/azure-pipelines/corrections/correction-azure.js +1 -0
- package/dist/analysts/azure-pipelines/detectors/detector-azure-performance.js +1 -0
- package/dist/analysts/azure-pipelines/detectors/detector-azure-security.js +1 -0
- package/dist/analysts/azure-pipelines/detectors/detector-azure-structure.js +1 -0
- package/dist/analysts/azure-pipelines/scorers/scorer-azure.js +1 -0
- package/dist/analysts/circleci/detectors/detector-circleci-performance.js +1 -0
- package/dist/analysts/circleci/detectors/detector-circleci-security.js +1 -0
- package/dist/analysts/circleci/detectors/detector-circleci-structure.js +9 -10
- package/dist/analysts/converters/engines/converter-gha-to-gitlab.js +1 -0
- package/dist/analysts/corrections/corrector-structure.js +2 -2
- package/dist/analysts/corrections/fix-md-fences.js +1 -0
- package/dist/analysts/corrections/map-reversion.js +1 -0
- package/dist/analysts/corrections/quick-fixes/fix-any-to-proper-type.js +1 -0
- package/dist/analysts/corrections/reorganize-barrels.js +1 -0
- package/dist/analysts/corrections/scoring-shared.js +1 -0
- package/dist/analysts/corrections/type-safety/context-analyzer.js +1 -1
- package/dist/analysts/corrections/type-safety/usage-analyzer.js +1 -0
- package/dist/analysts/css/analysts/analyst-css.js +3 -2
- package/dist/analysts/css/corrections/correction-css.js +1 -0
- package/dist/analysts/css/detectors/detector-css-best-practices.js +1 -0
- package/dist/analysts/css/scorers/scorer-css.js +1 -0
- package/dist/analysts/css-in-js/analysts/analyst-css-in-js.js +1 -0
- package/dist/analysts/css-in-js/corrections/correction-css-in-js.js +1 -1
- package/dist/analysts/css-in-js/detectors/detector-css-in-js-best-practices.js +2 -2
- package/dist/analysts/css-in-js/scorers/scorer-css-in-js.js +2 -2
- package/dist/analysts/detectors/detector-bugs-ml.js +4 -2
- package/dist/analysts/detectors/detector-dependencies.js +1 -0
- package/dist/analysts/detectors/detector-monorepo.js +1 -0
- package/dist/analysts/detectors/detector-security.js +1 -1
- package/dist/analysts/detectors/detector-structure.js +1 -1
- package/dist/analysts/github-actions/corrections/correction-workflow.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-dependencies-vulnerable.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-workflow-compliance.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-workflow-performance.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-workflow-security.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-workflow-structure.js +1 -0
- package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js +1 -0
- package/dist/analysts/github-actions/scorers/scorer-workflow.js +1 -0
- package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js +1 -0
- package/dist/analysts/gitlab-ci/corrections/correction-gitlab-ci.js +1 -0
- package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-performance.js +1 -0
- package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-security.js +1 -0
- package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js +1 -0
- package/dist/analysts/go/analysts/analyst-best-practices.js +1 -0
- package/dist/analysts/go/analysts/analyst-concurrency.js +1 -0
- package/dist/analysts/go/analysts/analyst-go.js +1 -0
- package/dist/analysts/go/analysts/analyst-resources.js +1 -0
- package/dist/analysts/go/detectors/detector-conventions.js +1 -0
- package/dist/analysts/go/detectors/detector-errors-un-handled.js +1 -0
- package/dist/analysts/go/detectors/detector-vulnerabilities.js +1 -0
- package/dist/analysts/html/analysts/analyst-html.js +1 -0
- package/dist/analysts/html/corrections/correction-html.js +1 -0
- package/dist/analysts/html/detectors/detector-html-accessibility.js +1 -0
- package/dist/analysts/html/detectors/detector-html.js +1 -0
- package/dist/analysts/jenkins/analysts/analyst-jenkins.js +1 -0
- package/dist/analysts/jenkins/corrections/correction-jenkins.js +1 -0
- package/dist/analysts/jenkins/detectors/detector-jenkins-best-practices.js +1 -0
- package/dist/analysts/jenkins/detectors/detector-jenkins-security.js +1 -0
- package/dist/analysts/jenkins/scorers/scorer-jenkins.js +1 -0
- package/dist/analysts/js-ts/analysts/analyst-todo-comments.js +1 -6
- package/dist/analysts/js-ts/detectors/detector-context-smart.js +1 -0
- package/dist/analysts/js-ts/detectors/detector-interfaces-inline.js +1 -0
- package/dist/analysts/js-ts/detectors/detector-leaks-memory.js +1 -0
- package/dist/analysts/js-ts/detectors/detector-types-unsafe.js +88 -5
- package/dist/analysts/php/analysts/analyst-php.js +1 -0
- package/dist/analysts/php/detectors/detector-php-best-practices.js +1 -0
- package/dist/analysts/php/detectors/detector-php-security.js +1 -0
- package/dist/analysts/plugins/analyst-formatter.js +1 -0
- package/dist/analysts/plugins/detector-markdown.js +1 -0
- package/dist/analysts/python/analysts/analyst-python.js +2 -1
- package/dist/analysts/python/corrections/correction-python.js +1 -0
- package/dist/analysts/python/scorers/scorer-python.js +1 -0
- package/dist/analysts/react/analysts/analyst-react-hooks.js +6 -6
- package/dist/analysts/react/scorers/scorer-react.js +4 -1
- package/dist/analysts/registry/autodiscovery.js +1 -0
- package/dist/analysts/rust/analysts/analyst-best-practices.js +1 -0
- package/dist/analysts/rust/analysts/analyst-concurrency.js +1 -0
- package/dist/analysts/rust/analysts/analyst-memory.js +1 -0
- package/dist/analysts/rust/analysts/analyst-rust.js +1 -0
- package/dist/analysts/rust/analysts/analyst-security.js +1 -0
- package/dist/analysts/rust/detectors/detector-conventions.js +1 -0
- package/dist/analysts/rust/detectors/detector-errors-potential.js +1 -0
- package/dist/analysts/shell/analysts/analyst-shell.js +1 -0
- package/dist/analysts/shell/corrections/correction-shell.js +1 -0
- package/dist/analysts/shell/detectors/detector-shell-security.js +1 -0
- package/dist/analysts/shell/scorers/scorer-shell.js +1 -0
- package/dist/analysts/sql/corrections/correction-sql.js +1 -0
- package/dist/analysts/sql/detectors/detector-sql.js +1 -0
- package/dist/analysts/sql/scorers/scorer-sql.js +1 -0
- package/dist/analysts/strategists/operator-structure.js +1 -1
- package/dist/analysts/strategists/suggestions-contextuais.js +1 -0
- package/dist/analysts/svg/analysts/analyst-svg.js +1 -0
- package/dist/analysts/svg/corrections/correction-svg.js +1 -0
- package/dist/analysts/svg/detectors/detector-svg-security.js +1 -0
- package/dist/analysts/tailwind/analysts/analyst-tailwind.js +1 -0
- package/dist/analysts/tailwind/corrections/correction-tailwind.js +1 -0
- package/dist/analysts/tailwind/detectors/detector-tailwind-best-practices.js +1 -0
- package/dist/analysts/xml/analysts/analyst-xml.js +1 -0
- package/dist/analysts/xml/corrections/correction-xml.js +1 -0
- package/dist/analysts/xml/detectors/detector-xml-security.js +1 -0
- package/dist/analysts/xml/scorers/scorer-xml.js +1 -0
- package/dist/app/github.js +1 -0
- package/dist/bin/cli-bootstrap.js +1 -1
- package/dist/bin/index.js +1 -1
- package/dist/caretakers/caretaker-imports.js +1 -0
- package/dist/cli/commands/command-analysts.js +1 -0
- package/dist/cli/commands/command-azure.js +1 -0
- package/dist/cli/commands/command-barrels.js +1 -0
- package/dist/cli/commands/command-circleci.js +1 -0
- package/dist/cli/commands/command-compliance.js +1 -0
- package/dist/cli/commands/command-convert.js +1 -0
- package/dist/cli/commands/command-diagnose.js +1 -1
- package/dist/cli/commands/command-fix-types.js +1 -1
- package/dist/cli/commands/command-format.js +1 -0
- package/dist/cli/commands/command-formatters.js +6 -4
- package/dist/cli/commands/command-github-actions.js +1 -0
- package/dist/cli/commands/command-gitlab-ci.js +1 -0
- package/dist/cli/commands/command-guardian.js +1 -1
- package/dist/cli/commands/command-imports.js +1 -0
- package/dist/cli/commands/command-jenkins.js +1 -0
- package/dist/cli/commands/command-licenses.js +1 -0
- package/dist/cli/commands/command-marketplace.js +1 -0
- package/dist/cli/commands/command-metrics.js +1 -1
- package/dist/cli/commands/command-names.js +1 -0
- package/dist/cli/commands/command-optimize-svg.js +1 -0
- package/dist/cli/commands/command-perf.js +1 -0
- package/dist/cli/commands/command-plugins.js +1 -0
- package/dist/cli/commands/command-prune.js +1 -0
- package/dist/cli/commands/command-reverter.js +1 -0
- package/dist/cli/commands/command-update.js +1 -0
- package/dist/cli/diagnostic/auto-fix.js +1 -0
- package/dist/cli/diagnostic/exporters/json-exporter.js +1 -0
- package/dist/cli/diagnostic/exporters/sharded-exporter.js +1 -1
- package/dist/cli/diagnostic/handlers/auto-fix-handler.js +1 -0
- package/dist/cli/diagnostic/handlers/guardian-handler.js +1 -0
- package/dist/cli/diagnostic/processing-diagnostic.js +1 -0
- package/dist/cli/diagnostic/processing-helpers.js +1 -0
- package/dist/cli/handlers/command-vulnerabilities.js +1 -0
- package/dist/cli/handlers/fix-types-exporter.js +1 -0
- package/dist/cli/handlers/guardian-exporter.js +1 -0
- package/dist/cli/helpers/display-frame.js +1 -0
- package/dist/core/config/auto/validation.js +1 -0
- package/dist/core/config/config.js +1 -0
- package/dist/core/config/excludes-padrao.js +1 -0
- package/dist/core/execution/executor.js +1 -0
- package/dist/core/execution/inquisitor.js +1 -0
- package/dist/core/formatters/registro-builtin.js +1 -0
- package/dist/core/messages/en/analysts/detector-react-messages.js +3 -0
- package/dist/core/messages/en/analysts/report-circleci-messages.js +5 -5
- package/dist/core/messages/en/cli/cli-command-marketplace-messages.js +1 -0
- package/dist/core/messages/en/core/plugin-messages.js +1 -1
- package/dist/core/messages/en/log/log-helper.js +1 -1
- package/dist/core/messages/en/ui/suggestions.js +1 -1
- package/dist/core/messages/ja/analysts/report-circleci-messages.js +5 -5
- package/dist/core/messages/ja/core/plugin-messages.js +1 -1
- package/dist/core/messages/ja/log/log-helper.js +1 -1
- package/dist/core/messages/ja/ui/suggestions.js +1 -1
- package/dist/core/messages/pt/analysts/detector-react-messages.js +3 -0
- package/dist/core/messages/pt/analysts/report-circleci-messages.js +5 -5
- package/dist/core/messages/pt/core/plugin-messages.js +1 -1
- package/dist/core/messages/pt/log/log-helper.js +1 -1
- package/dist/core/messages/pt/ui/suggestions.js +1 -1
- package/dist/core/messages/shared/icons.js +1 -0
- package/dist/core/messages/zh/analysts/report-circleci-messages.js +5 -5
- package/dist/core/messages/zh/core/plugin-messages.js +1 -1
- package/dist/core/messages/zh/log/log-helper.js +1 -1
- package/dist/core/messages/zh/ui/suggestions.js +1 -1
- package/dist/core/parsing/langs/css.js +1 -0
- package/dist/core/parsing/langs/html.js +1 -0
- package/dist/core/parsing/langs/json.js +1 -0
- package/dist/core/parsing/langs/php.js +1 -0
- package/dist/core/parsing/langs/python.js +1 -0
- package/dist/core/parsing/langs/rust.js +1 -0
- package/dist/core/parsing/langs/scss.js +1 -0
- package/dist/core/parsing/langs/shell.js +1 -0
- package/dist/core/parsing/langs/vue.js +1 -0
- package/dist/core/parsing/parser.js +1 -0
- package/dist/core/workers/worker-executor.js +1 -0
- package/dist/core/workers/worker-pool.js +0 -0
- package/dist/licenses/disclaimer.js +1 -0
- package/dist/licenses/generate-notices.js +1 -0
- package/dist/licenses/normalizer.js +1 -0
- package/dist/licenses/scanner.js +1 -0
- package/dist/node.loader.js +1 -0
- package/dist/reports/filter-smart.js +1 -1
- package/dist/reports/report-archetypes.js +1 -0
- package/dist/shared/data-processing/fragment-report.js +1 -0
- package/dist/shared/data-processing/json.js +1 -0
- package/dist/shared/formatters/engines/prettier.js +1 -0
- package/dist/shared/formatters/engines/stylelint.js +1 -0
- package/dist/shared/formatters/formatters/code.js +1 -0
- package/dist/shared/formatters/formatters/css.js +1 -0
- package/dist/shared/formatters/formatters/dockerfile.js +1 -0
- package/dist/shared/formatters/formatters/dotfiles.js +1 -0
- package/dist/shared/formatters/formatters/go.js +1 -0
- package/dist/shared/formatters/formatters/html.js +1 -0
- package/dist/shared/formatters/formatters/json.js +1 -0
- package/dist/shared/formatters/formatters/markdown.js +1 -0
- package/dist/shared/formatters/formatters/shell.js +1 -0
- package/dist/shared/formatters/formatters/sql.js +1 -0
- package/dist/shared/formatters/formatters/toml.js +1 -0
- package/dist/shared/formatters/formatters/xml.js +1 -0
- package/dist/shared/formatters/formatters/yaml.js +1 -0
- package/dist/shared/helpers/analyst-wrapper.js +1 -0
- package/dist/shared/helpers/detectors-common.js +1 -0
- package/dist/shared/helpers/framework-detector.js +1 -0
- package/dist/shared/helpers/imports.js +1 -1
- package/dist/shared/helpers/reader-report.js +1 -0
- package/dist/shared/helpers/rule-config.js +1 -0
- package/dist/shared/helpers/suppressao.js +1 -0
- package/dist/shared/marketplace/remote.js +1 -0
- package/dist/shared/persistence/persistence.js +3 -3
- package/dist/shared/plugins/registry.js +1 -0
- package/dist/types/analysts/css-in-js.js +2 -0
- package/dist/types/analysts/index.js +1 -0
- package/dist/types/processing/display.js +1 -1
- package/dist/types/processing/filters.js +1 -0
- package/dist/vulnerabilities/scanner.js +1 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @mahoraga-disable ml-alta-probabilidade-bugs ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
3
|
/**
|
|
3
4
|
* Detector de tipos inseguros (any e unknown) - Versão Inteligente
|
|
@@ -253,6 +254,27 @@ const ANALISTA = {
|
|
|
253
254
|
});
|
|
254
255
|
}
|
|
255
256
|
// ─── DETECTAR 'as' QUE PODEM SER SUBSTITUÍDOS POR 'satisfies' ─
|
|
257
|
+
// Referência: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator
|
|
258
|
+
//
|
|
259
|
+
// PRINCÍPIO FUNDAMENTAL:
|
|
260
|
+
// 'as' (type assertion) MUDA o tipo da expressão — pode estreitar (narrow)
|
|
261
|
+
// de unknown→concreto, string→union, tipo→subtipo, ou até mentir.
|
|
262
|
+
// 'satisfies' apenas VALIDA — o tipo da expressão permanece o original.
|
|
263
|
+
//
|
|
264
|
+
// Portanto, 'satisfies' SÓ pode substituir 'as' sem quebrar o código
|
|
265
|
+
// quando a expressão é um LITERAL (objeto {...} ou array [...]).
|
|
266
|
+
// Nesse caso, 'satisfies' é ESTRITAMENTE MELHOR: valida a constraint
|
|
267
|
+
// sem widen (perda de inferência precisa).
|
|
268
|
+
//
|
|
269
|
+
// Para QUALQUER outra expressão (variável, função, propriedade, acesso
|
|
270
|
+
// indexado, parênteses, operador), 'as' está fazendo narrowing que
|
|
271
|
+
// 'satisfies' não replica — NUNCA sugerir satisfies.
|
|
272
|
+
//
|
|
273
|
+
// Exemplo clássico onde satisfies é melhor:
|
|
274
|
+
// const x = { red: [255,0,0], blue: [0,0,255] } as Record<string, number[]>
|
|
275
|
+
// → perde inferência de 'red' e 'blue' como tuplas
|
|
276
|
+
// const x = { red: [255,0,0], blue: [0,0,255] } satisfies Record<string, number[]>
|
|
277
|
+
// → valida a constraint, mantém inferência precisa das tuplas
|
|
256
278
|
const asTypePadrao = /\bas\s+([A-Za-z_$][A-Za-z0-9_$.]+)\b(?!\s*[=(])/g;
|
|
257
279
|
let asTypeMatch;
|
|
258
280
|
while ((asTypeMatch = asTypePadrao.exec(src)) !== null) {
|
|
@@ -262,12 +284,73 @@ const ANALISTA = {
|
|
|
262
284
|
}
|
|
263
285
|
const linha = splitLines(src.substring(0, position)).length;
|
|
264
286
|
const lineContext = splitLines(src)[linha - 1]?.trim() || '';
|
|
265
|
-
|
|
266
|
-
|
|
287
|
+
const tipoAsserido = asTypeMatch[1];
|
|
288
|
+
// Skip 'as any' — já detectado em seção anterior como erro
|
|
289
|
+
// Skip 'as const' — é literal narrowing, não type assertion
|
|
290
|
+
if (tipoAsserido === 'any' || tipoAsserido === 'const') {
|
|
267
291
|
continue;
|
|
268
292
|
}
|
|
269
|
-
//
|
|
270
|
-
|
|
293
|
+
// ─── FILTROS DE SEGURANÇA: padrões que NUNCA devem sugerir satisfies ───
|
|
294
|
+
// Import/export rename: 'import { x as y }', 'export { x as y }'
|
|
295
|
+
// Pega linhas que começam com import/export E linhas de continuação
|
|
296
|
+
// dentro de blocos import { ... } (linhas indentadas com 'as' entre vírgulas)
|
|
297
|
+
if (/^(import|export)\b/.test(lineContext)) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
// Detecta 'as' dentro de blocos import/export em linhas de continuação:
|
|
301
|
+
// Padrão: linha indentada com 'identificador as identificador,' e há
|
|
302
|
+
// um import/export nas linhas anteriores próximas
|
|
303
|
+
const windowBefore = src.slice(Math.max(0, position - 500), position);
|
|
304
|
+
if (/^\s+\w+\s+as\s+\w+,?\s*$/.test(lineContext) &&
|
|
305
|
+
/(?:^|\n)\s*(?:import|export)\s*\{/.test(windowBefore)) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
// Skip 'as' dentro de template literal ${...}
|
|
309
|
+
const beforePos = src.slice(Math.max(0, position - 120), position);
|
|
310
|
+
if (lineContext.includes('${') || beforePos.includes('${')) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
// Skip dupla asserção 'unknown as'
|
|
314
|
+
if (lineContext.includes('unknown as')) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
// Skip em arrow function: (x) => x as Type
|
|
318
|
+
if (/=>\s*\(?[^)]*\)?\s*as\s+\w+/.test(lineContext)) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
// ─── VERIFICAÇÃO PRINCIPAL: expressão antes de 'as' é literal? ───
|
|
322
|
+
//
|
|
323
|
+
// A única situação onde 'satisfies' pode substituir 'as' com segurança
|
|
324
|
+
// é quando a expressão é um literal objeto `{...}` ou array `[...]`.
|
|
325
|
+
//
|
|
326
|
+
// Diferente da abordagem anterior (que usava 120 chars de janela e
|
|
327
|
+
// podia capturar { de linhas anteriores), aqui extraímos APENAS o
|
|
328
|
+
// texto na MESMA LINHA antes de 'as'.
|
|
329
|
+
//
|
|
330
|
+
// Critérios para identificar literal:
|
|
331
|
+
// 1. Objeto: texto (após remover declaração) começa com '{' e termina com '}'
|
|
332
|
+
// 2. Array: texto (após remover declaração) começa com '[' e termina com ']'
|
|
333
|
+
// 3. '{}' vazio → sentinel, pular
|
|
334
|
+
//
|
|
335
|
+
// Isso diferencia corretamente:
|
|
336
|
+
// - `{ a: 1 } as T` → objeto literal ✓
|
|
337
|
+
// - `[1, 2] as T` → array literal ✓
|
|
338
|
+
// - `arr[i] as T` → index access (começa com 'a', não '[') ✗
|
|
339
|
+
// - `found.ast as T` → property access (começa com 'f') ✗
|
|
340
|
+
// - `framework as T` → variável simples ✗
|
|
341
|
+
const lineText = splitLines(src)[linha - 1];
|
|
342
|
+
const colMatch = src.lastIndexOf('\n', Math.max(0, position - 1));
|
|
343
|
+
const posInLine = position - (colMatch >= 0 ? colMatch + 1 : 0);
|
|
344
|
+
const textBeforeOnLine = lineText.substring(0, Math.max(0, posInLine - 'as'.length)).trimEnd();
|
|
345
|
+
// Remove declaração (const/let/var/return/yield) para ver a expressão pura
|
|
346
|
+
const exprText = textBeforeOnLine
|
|
347
|
+
.replace(/^(?:const|let|var|return|yield)\s+\w+\s*=\s*/, '')
|
|
348
|
+
.trim();
|
|
349
|
+
// Verifica se é literal: abre e fecha com {}/{ ou [ /]
|
|
350
|
+
const isObjectLiteral = /\}\s*$/.test(exprText) && /^\s*\{/.test(exprText) && !/^\s*\{\s*\}\s*$/.test(exprText);
|
|
351
|
+
const isArrayLiteral = /\]\s*$/.test(exprText) && /^\s*\[/.test(exprText);
|
|
352
|
+
// Se NÃO é literal → é narrowing, NUNCA sugerir satisfies
|
|
353
|
+
if (!isObjectLiteral && !isArrayLiteral) {
|
|
271
354
|
continue;
|
|
272
355
|
}
|
|
273
356
|
if (shouldSuppressOccurrence('tipo-inseguro-as-satisfies', relPath)) {
|
|
@@ -276,7 +359,7 @@ const ANALISTA = {
|
|
|
276
359
|
const mensagemCompleta = `${messages.DetectorJsTsMensagens.satisfiesAvailable} | [IDEIA] ${messages.DetectorJsTsMensagens.satisfiesAvailableSugestao}`;
|
|
277
360
|
ocorrencias.push({
|
|
278
361
|
tipo: 'tipo-inseguro-as-satisfies',
|
|
279
|
-
nivel: '
|
|
362
|
+
nivel: 'aviso',
|
|
280
363
|
mensagem: mensagemCompleta,
|
|
281
364
|
relPath,
|
|
282
365
|
linha,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @mahoraga-disable ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
3
|
import { messages } from '../../../core/messages/index.js';
|
|
3
4
|
import { createLineLookup, maskPythonComments, maskPythonStringsAndComments, splitLines } from '../../../shared/helpers/index.js';
|
|
@@ -189,7 +190,7 @@ export function collectPythonIssues(src, relPath) {
|
|
|
189
190
|
ocorrencias.push(warn(messages.PythonMensagens.shadowBuiltin, relPath, line, messages.SeverityNiveis.info));
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
|
-
//
|
|
193
|
+
// Task/FIXME comments (on original src, before masking)
|
|
193
194
|
for (const match of src.matchAll(/#\s*(TODO|FIXME|HACK|XXX|BUG|WORKAROUND)[:\s]/gi)) {
|
|
194
195
|
const line = lineOf(match.index);
|
|
195
196
|
ocorrencias.push(warn(messages.PythonMensagens.todoFixme, relPath, line, messages.SeverityNiveis.info));
|
|
@@ -103,14 +103,14 @@ function collectHookIssues(src, relPath) {
|
|
|
103
103
|
// React 19: useActionState detected
|
|
104
104
|
for (const match of src.matchAll(/\buseActionState\s*\(/g)) {
|
|
105
105
|
const line = lineOf(match.index);
|
|
106
|
-
ocorrencias.push(warn('useActionState (React 19) detected
|
|
106
|
+
ocorrencias.push(warn('useActionState (React 19) detected - verify form action integration', relPath, line, messages.SeverityNiveis.info));
|
|
107
107
|
}
|
|
108
108
|
// React 19: useFormStatus detected
|
|
109
109
|
for (const match of src.matchAll(/\buseFormStatus\s*\(/g)) {
|
|
110
110
|
const line = lineOf(match.index);
|
|
111
|
-
ocorrencias.push(warn('useFormStatus (React 19) detected
|
|
111
|
+
ocorrencias.push(warn('useFormStatus (React 19) detected - access pending form state', relPath, line, messages.SeverityNiveis.info));
|
|
112
112
|
}
|
|
113
|
-
// React 19: use() hook
|
|
113
|
+
// React 19: use() hook - suspends, must be in Suspense boundary
|
|
114
114
|
for (const match of src.matchAll(/\buse\s*\(/g)) {
|
|
115
115
|
const line = lineOf(match.index);
|
|
116
116
|
// Avoid matching "useState", "useEffect", etc.
|
|
@@ -118,7 +118,7 @@ function collectHookIssues(src, relPath) {
|
|
|
118
118
|
if (src[match.index - 1]?.match(/[a-zA-Z]/)) {
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
|
-
ocorrencias.push(warn('React 19 use() hook detected
|
|
121
|
+
ocorrencias.push(warn('React 19 use() hook detected - must be wrapped in <Suspense> boundary', relPath, line, messages.SeverityNiveis.error));
|
|
122
122
|
}
|
|
123
123
|
// Custom hooks naming convention
|
|
124
124
|
const customHooks = [...src.matchAll(/\buse[A-Z][A-Za-z0-9_]*\s*=\s*\(/g)];
|
|
@@ -254,7 +254,7 @@ function parseHooksWithBabel(src, relPath) {
|
|
|
254
254
|
}
|
|
255
255
|
// React 19: use() hook should be in Suspense boundary
|
|
256
256
|
if (name === 'use') {
|
|
257
|
-
pushOnce(warn('React 19 use() hook
|
|
257
|
+
pushOnce(warn('React 19 use() hook - ensure wrapped in <Suspense> boundary', relPath, locLine));
|
|
258
258
|
}
|
|
259
259
|
// React 19: useOptimistic should have reducer function
|
|
260
260
|
if (name === 'useOptimistic' && path.node.arguments.length < 2) {
|
|
@@ -262,7 +262,7 @@ function parseHooksWithBabel(src, relPath) {
|
|
|
262
262
|
}
|
|
263
263
|
// React 19: useActionState should have form action
|
|
264
264
|
if (name === 'useActionState') {
|
|
265
|
-
pushOnce(warn('useActionState (React 19)
|
|
265
|
+
pushOnce(warn('useActionState (React 19) - verify form action handler', relPath, locLine));
|
|
266
266
|
}
|
|
267
267
|
if (isEffectLike(name) && path.node.arguments.length >= 2) {
|
|
268
268
|
const callback = path.node.arguments[0];
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
// @mahoraga-disable react-hooks/regra ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Justificativa: O scorer analisa padrões de hooks (condicionais, useEffect sem deps, context)
|
|
4
|
+
// através de regex em STRINGS de mensagem, não contendo violações reais de regras de hooks.
|
|
2
5
|
// @mahoraga-disable react-hooks/rule
|
|
3
6
|
export function pontuarReact(src, _relPath) {
|
|
4
7
|
let score = 0;
|
|
@@ -9,7 +12,7 @@ export function pontuarReact(src, _relPath) {
|
|
|
9
12
|
// React 19 patterns: forwardRef deprecation, React.FC, Server Components
|
|
10
13
|
const hasForwardRef = /\bforwardRef\s*\(/.test(srcCompleto);
|
|
11
14
|
if (hasForwardRef) {
|
|
12
|
-
issues.push('forwardRef é deprecated no React 19
|
|
15
|
+
issues.push('forwardRef é deprecated no React 19 - passe ref como prop direta');
|
|
13
16
|
}
|
|
14
17
|
else {
|
|
15
18
|
score += 3;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// @mahoraga-disable tipo-literal-inline-complexo ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// @mahoraga-disable tipo-literal-inline-complexo
|
|
3
3
|
// Justificativa: tipos locais para operações de estrutura
|
|
4
4
|
import { config } from '../../core/config/index.js';
|
|
5
5
|
import { getMessages } from '../../core/messages/index.js';
|
package/dist/app/github.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
// @mahoraga-disable tipo-permissivo-object tipo-inseguro-unknown
|
|
3
|
+
// @mahoraga-disable tipo-permissivo-object tipo-inseguro-unknown ml-deep-nesting
|
|
4
4
|
// Justificativa: Object.keys é chamada de API, não tipo. unknown em catch handlers é intencional.
|
|
5
5
|
import { realpathSync } from 'node:fs';
|
|
6
6
|
import { dirname, join, resolve as resolvePath } from 'node:path';
|
package/dist/bin/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
// @mahoraga-disable tipo-permissivo-object tipo-inseguro-unknown
|
|
3
|
+
// @mahoraga-disable tipo-permissivo-object tipo-inseguro-unknown ml-deep-nesting
|
|
4
4
|
// Justificativa: Object.keys é chamada de API, não tipo. unknown em catch handlers é intencional.
|
|
5
5
|
import { realpathSync } from 'node:fs';
|
|
6
6
|
import { dirname, join, resolve as resolvePath } from 'node:path';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// @mahoraga-disable tipo-literal-inline-complexo tipo-permissivo-object ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// @mahoraga-disable tipo-literal-inline-complexo tipo-permissivo-object
|
|
3
3
|
// Justificativa: tipos inline para opções de comando CLI são locais e não precisam de extração. Object.create é chamada de API, não tipo.
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import ora from 'ora';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// @mahoraga-disable tipo-inseguro-unknown tipo-permissivo-object ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// @mahoraga-disable tipo-inseguro-unknown tipo-permissivo-object
|
|
3
3
|
// Justificativa: err: unknown é correto para catch handlers. Object.* são chamadas de API, não tipo.
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { config } from '../../core/config/index.js';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
// @mahoraga-disable ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
3
|
import { accessSync } from 'node:fs';
|
|
3
|
-
import { resolve, sep } from 'node:path';
|
|
4
4
|
import { Command } from 'commander';
|
|
5
|
+
import { resolverPluginSeguro } from '../../core/config/index.js';
|
|
5
6
|
import { listarFormatters, registrarFormatter, removerFormatter } from '../../core/formatters/index.js';
|
|
6
7
|
import { getMessages } from '../../core/messages/index.js';
|
|
8
|
+
import { PROJETO_RAIZ } from '../../core/registry/index.js';
|
|
7
9
|
const { log, FormattersMensagens } = getMessages();
|
|
8
10
|
export function comandoFormatters() {
|
|
9
11
|
const cmd = new Command('formatters')
|
|
@@ -34,12 +36,12 @@ export function comandoFormatters() {
|
|
|
34
36
|
.argument('<caminho>', 'Caminho do módulo do formatador')
|
|
35
37
|
.action(async (nome, caminho) => {
|
|
36
38
|
try {
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
+
const resolvido = resolverPluginSeguro(PROJETO_RAIZ, caminho);
|
|
40
|
+
if (resolvido.erro || !resolvido.caminho) {
|
|
39
41
|
log.erro(FormattersMensagens.moduloInvalido(caminho));
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
|
-
const caminhoResolvido =
|
|
44
|
+
const caminhoResolvido = resolvido.caminho;
|
|
43
45
|
try {
|
|
44
46
|
accessSync(caminhoResolvido);
|
|
45
47
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// @mahoraga-disable tipo-literal-inline-complexo tipo-inseguro-unknown ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// @mahoraga-disable tipo-literal-inline-complexo tipo-inseguro-unknown
|
|
3
3
|
// Justificativa: tipos inline para opções de comando CLI são locais e não precisam de extração. err em catch handlers é unknown propositalmente.
|
|
4
4
|
// Importar handler modular do Guardian (Sprint 2)
|
|
5
5
|
import { acceptNewBaseline } from '../../guardian/index.js';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// CLI wrapper around the license-auditor functionality migrated from `implantar/licensas`.
|
|
3
3
|
// The original package exported a simple node script; here we integrate into the main Commander
|
|
4
4
|
// program and convert to TypeScript.
|
|
5
|
+
// @mahoraga-disable ml-deep-nesting
|
|
5
6
|
import path from 'node:path';
|
|
6
7
|
import * as licensas from '../../licenses/index.js';
|
|
7
8
|
import { Command } from 'commander';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// @mahoraga-disable tipo-literal-inline-complexo ml-deep-nesting
|
|
1
2
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// @mahoraga-disable tipo-literal-inline-complexo
|
|
3
3
|
// Justificativa: tipos inline para opções de comando CLI são locais e não precisam de extração
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { Command } from 'commander';
|