@mocoto/mahoraga 0.14.1 → 0.14.3
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 +0 -34
- package/dist/analysts/architects/analyst-structure.js +20 -20
- package/dist/analysts/architects/archetypes-custom.js +16 -19
- package/dist/analysts/architects/detector-archetypes.js +43 -36
- package/dist/analysts/architects/orchestrator-archetypes.js +3 -3
- package/dist/analysts/architects/signals-project-advanced.js +26 -28
- package/dist/analysts/architects/signals-project.js +2 -2
- package/dist/analysts/architects/strategist-structure.js +47 -66
- package/dist/analysts/azure-pipelines/analysts/analyst-azure.js +41 -35
- package/dist/analysts/azure-pipelines/corrections/correction-azure.js +22 -19
- package/dist/analysts/azure-pipelines/detectors/detector-azure-performance.js +21 -18
- package/dist/analysts/azure-pipelines/detectors/detector-azure-security.js +25 -20
- package/dist/analysts/azure-pipelines/detectors/detector-azure-structure.js +39 -40
- package/dist/analysts/azure-pipelines/scorers/scorer-azure.js +10 -7
- package/dist/analysts/circleci/analysts/analyst-circleci.js +33 -27
- package/dist/analysts/circleci/corrections/correction-circleci.js +22 -20
- package/dist/analysts/circleci/detectors/detector-circleci-performance.js +23 -19
- package/dist/analysts/circleci/detectors/detector-circleci-security.js +78 -82
- package/dist/analysts/circleci/detectors/detector-circleci-structure.js +22 -22
- package/dist/analysts/converters/convert-registry.js +1 -1
- package/dist/analysts/converters/engines/converter-gha-to-gitlab.js +17 -15
- package/dist/analysts/converters/index.js +1 -1
- package/dist/analysts/corrections/analyst-quick-fixes.js +25 -28
- package/dist/analysts/corrections/analyst-scoring.js +24 -21
- package/dist/analysts/corrections/auto-fix-engine.js +1 -1
- package/dist/analysts/corrections/corrector-structure.js +43 -42
- package/dist/analysts/corrections/fix-alias-imports.js +10 -6
- package/dist/analysts/corrections/fix-md-fences.js +23 -23
- package/dist/analysts/corrections/map-reversion.js +56 -53
- package/dist/analysts/corrections/pruning.js +19 -16
- package/dist/analysts/corrections/quick-fixes/fix-any-to-proper-type.js +57 -61
- package/dist/analysts/corrections/quick-fixes/fix-unknown-to-specific-type.js +30 -30
- package/dist/analysts/corrections/reorganize-barrels.js +13 -13
- package/dist/analysts/corrections/rewrite-testes-aliases.js +23 -22
- package/dist/analysts/corrections/scoring-shared.js +19 -18
- package/dist/analysts/corrections/type-safety/context-analyzer.js +15 -10
- package/dist/analysts/corrections/type-safety/type-analyzer.js +3 -3
- package/dist/analysts/corrections/type-safety/type-validator.js +4 -3
- package/dist/analysts/corrections/type-safety/usage-analyzer.js +39 -42
- package/dist/analysts/css/analysts/analyst-css.js +42 -42
- package/dist/analysts/css/corrections/correction-css.js +19 -11
- package/dist/analysts/css/detectors/detector-css-best-practices.js +129 -118
- package/dist/analysts/css/scorers/scorer-css.js +23 -18
- package/dist/analysts/css-in-js/analysts/analyst-css-in-js.js +24 -17
- package/dist/analysts/css-in-js/corrections/correction-css-in-js.js +31 -16
- package/dist/analysts/css-in-js/detectors/detector-css-in-js-best-practices.js +28 -30
- package/dist/analysts/css-in-js/scorers/scorer-css-in-js.js +79 -54
- package/dist/analysts/css-in-js/shared.js +7 -0
- package/dist/analysts/detectors/detector-architecture.js +91 -85
- package/dist/analysts/detectors/detector-bugs-ml.js +29 -27
- package/dist/analysts/detectors/detector-code-fragile.js +41 -36
- package/dist/analysts/detectors/detector-dependencies.js +5 -5
- package/dist/analysts/detectors/detector-duplications.js +26 -26
- package/dist/analysts/detectors/detector-monorepo.js +51 -45
- package/dist/analysts/detectors/detector-performance.js +24 -17
- package/dist/analysts/detectors/detector-recommendation-architecture.js +40 -36
- package/dist/analysts/detectors/detector-security.js +43 -42
- package/dist/analysts/detectors/detector-structure.js +31 -28
- package/dist/analysts/github-actions/analysts/analyst-github-actions.js +5 -8
- package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.js +1 -9
- package/dist/analysts/github-actions/detectors/detector-workflow-structure.js +1 -4
- package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js +6 -5
- package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js +2 -2
- package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js +0 -3
- package/dist/analysts/go/analysts/analyst-best-practices.js +2 -2
- package/dist/analysts/go/analysts/analyst-concurrency.js +1 -1
- package/dist/analysts/go/analysts/analyst-security.js +1 -1
- package/dist/analysts/go/detectors/detector-conventions.js +1 -1
- package/dist/analysts/html/analysts/analyst-html.js +10 -12
- package/dist/analysts/html/detectors/detector-html.js +3 -3
- package/dist/analysts/js-ts/analysts/analyst-commands-cli.js +22 -22
- package/dist/analysts/js-ts/analysts/analyst-functions-long.js +5 -5
- package/dist/analysts/js-ts/analysts/analyst-patterns-usage.js +6 -2
- package/dist/analysts/js-ts/detectors/detector-anti-patterns-async.js +84 -9
- package/dist/analysts/js-ts/detectors/detector-constructions-syntactic.js +33 -10
- package/dist/analysts/js-ts/detectors/detector-context-smart.js +6 -6
- package/dist/analysts/js-ts/detectors/detector-leaks-memory.js +1 -1
- package/dist/analysts/js-ts/detectors/detector-types-unsafe.js +33 -2
- package/dist/analysts/php/analysts/analyst-php.js +3 -3
- package/dist/analysts/php/detectors/detector-php-best-practices.js +5 -5
- package/dist/analysts/php/detectors/detector-php-security.js +5 -5
- package/dist/analysts/php/scorers/scorer-php.js +2 -2
- package/dist/analysts/plugins/detector-documentation.js +6 -6
- package/dist/analysts/plugins/detector-markdown.js +7 -7
- package/dist/analysts/python/analysts/analyst-python.js +2 -5
- package/dist/analysts/react/analysts/analyst-react-hooks.js +66 -9
- package/dist/analysts/react/analysts/analyst-react.js +46 -2
- package/dist/analysts/react/corrections/correction-react.js +41 -1
- package/dist/analysts/react/detectors/detector-react-best-practices.js +5 -5
- package/dist/analysts/react/scorers/scorer-react.js +36 -1
- package/dist/analysts/registry/autodiscovery.js +2 -2
- package/dist/analysts/rust/analysts/analyst-best-practices.js +42 -3
- package/dist/analysts/rust/analysts/analyst-memory.js +2 -2
- package/dist/analysts/rust/analysts/analyst-rust.js +52 -5
- package/dist/analysts/rust/analysts/analyst-security.js +29 -1
- package/dist/analysts/scorers/scorer.js +5 -5
- package/dist/analysts/shell/analysts/analyst-shell.js +81 -5
- package/dist/analysts/shell/corrections/correction-shell.js +34 -1
- package/dist/analysts/shell/detectors/detector-shell-security.js +88 -0
- package/dist/analysts/shell/scorers/scorer-shell.js +58 -1
- package/dist/analysts/strategists/operator-structure.js +5 -7
- package/dist/analysts/strategists/suggestions-contextuais.js +5 -2
- package/dist/analysts/svg/analysts/analyst-svg.js +1 -0
- package/dist/analysts/tailwind/analysts/analyst-tailwind.js +79 -55
- package/dist/analysts/tailwind/corrections/correction-tailwind.js +108 -9
- package/dist/analysts/tailwind/detectors/detector-tailwind-best-practices.js +122 -7
- package/dist/analysts/tailwind/scorers/scorer-tailwind.js +62 -11
- package/dist/analysts/xml/analysts/analyst-xml.js +2 -2
- package/dist/app/index.js +1 -0
- package/dist/bin/cli-bootstrap.js +6 -4
- package/dist/bin/index.js +6 -4
- package/dist/caretakers/scoring.js +1 -0
- package/dist/cli/commands/command-analysts.js +4 -3
- package/dist/cli/commands/command-azure.js +1 -1
- package/dist/cli/commands/command-circleci.js +1 -1
- package/dist/cli/commands/command-compliance.js +1 -1
- package/dist/cli/commands/command-diagnose.js +10 -13
- package/dist/cli/commands/command-fix-types.js +9 -32
- package/dist/cli/commands/command-formatters.js +2 -2
- package/dist/cli/commands/command-github-actions.js +1 -1
- package/dist/cli/commands/command-gitlab-ci.js +1 -1
- package/dist/cli/commands/command-guardian.js +1 -1
- package/dist/cli/commands/command-imports.js +6 -6
- package/dist/cli/commands/command-jenkins.js +1 -1
- package/dist/cli/commands/command-licenses.js +1 -1
- package/dist/cli/commands/command-marketplace.js +7 -7
- package/dist/cli/commands/command-names.js +3 -8
- package/dist/cli/commands/command-perf.js +7 -9
- package/dist/cli/commands/command-plugins.js +4 -4
- package/dist/cli/diagnostic/auto-fix.js +2 -2
- package/dist/cli/diagnostic/exporters/json-exporter.js +1 -1
- package/dist/cli/diagnostic/exporters/sharded-exporter.js +0 -3
- package/dist/cli/diagnostic/exporters/svg-optimization-exporter.js +1 -1
- package/dist/cli/diagnostic/filters.js +9 -9
- package/dist/cli/diagnostic/handlers/archetype-handler.js +3 -6
- package/dist/cli/diagnostic/handlers/auto-fix-handler.js +4 -4
- package/dist/cli/diagnostic/handlers/guardian-handler.js +1 -1
- package/dist/cli/diagnostic/processing-diagnostic.js +31 -35
- package/dist/cli/diagnostic/processing-helpers.js +2 -2
- package/dist/cli/handlers/fix-types-exporter.js +1 -4
- package/dist/cli/helpers/display-frame.js +5 -5
- package/dist/core/config/auto/auto-fix-config.js +0 -6
- package/dist/core/config/chalk-safe.js +6 -6
- package/dist/core/config/config.js +11 -13
- package/dist/core/config/conventions.js +1 -1
- package/dist/core/config/security.js +2 -2
- package/dist/core/execution/analysis-cache.js +5 -8
- package/dist/core/execution/ast-cache.js +1 -3
- package/dist/core/execution/executor.js +8 -21
- package/dist/core/execution/inquisitor.js +24 -21
- package/dist/core/execution/results.js +1 -0
- package/dist/core/execution/scanner.js +4 -4
- package/dist/core/messages/en/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/en/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/en/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/en/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/en/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/en/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/en/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/en/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/en/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/en/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/en/core/plugin-messages.js +31 -3
- package/dist/core/messages/en/log/log.js +4 -4
- package/dist/core/messages/en/ui/filter-config.js +1 -5
- package/dist/core/messages/i18n-system.js +3 -3
- package/dist/core/messages/index.js +3 -3
- package/dist/core/messages/ja/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/ja/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/ja/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/ja/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/ja/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/ja/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/ja/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/ja/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/ja/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/ja/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/ja/core/plugin-messages.js +31 -3
- package/dist/core/messages/ja/log/log.js +4 -4
- package/dist/core/messages/ja/ui/filter-config.js +1 -1
- package/dist/core/messages/pt/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/pt/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/pt/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/pt/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/pt/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/pt/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/pt/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/pt/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/pt/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/pt/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/pt/core/plugin-messages.js +31 -3
- package/dist/core/messages/pt/log/log-engine.js +6 -6
- package/dist/core/messages/pt/log/log.js +3 -3
- package/dist/core/messages/pt/ui/filter-config.js +1 -1
- package/dist/core/messages/shared/icons.js +3 -3
- package/dist/core/messages/zh/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/zh/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/zh/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/zh/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/zh/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/zh/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/zh/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/zh/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/zh/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/zh/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/zh/core/plugin-messages.js +31 -3
- package/dist/core/messages/zh/log/log.js +3 -3
- package/dist/core/messages/zh/ui/filter-config.js +1 -5
- package/dist/core/parsing/filters.js +3 -3
- package/dist/core/parsing/langs/json.js +1 -1
- package/dist/core/parsing/langs/python.js +1 -1
- package/dist/core/parsing/langs/typescript.js +1 -1
- package/dist/core/parsing/parser.js +3 -4
- package/dist/core/parsing/utils.js +1 -0
- package/dist/core/registry/file-registry.js +3 -2
- package/dist/core/registry/paths.js +3 -3
- package/dist/core/reporting/default-reporter.js +2 -2
- package/dist/core/schema/version.js +6 -6
- package/dist/core/workers/worker-executor.js +3 -3
- package/dist/core/workers/worker-pool.js +0 -0
- package/dist/guardian/baseline.js +1 -1
- package/dist/guardian/gpg.js +3 -1
- package/dist/guardian/integrity.js +2 -7
- package/dist/guardian/records.js +7 -1
- package/dist/guardian/result.js +1 -1
- package/dist/guardian/sentinel.js +7 -1
- package/dist/guardian/watcher-hidden.js +6 -1
- package/dist/licenses/fs-utils.js +5 -1
- package/dist/licenses/generate-notices.js +1 -1
- package/dist/licenses/index.js +1 -0
- package/dist/licenses/normalizer.js +10 -9
- package/dist/node.loader.js +224 -4
- package/dist/reports/analise-async-patterns.js +1 -1
- package/dist/reports/filter-smart.js +2 -5
- package/dist/reports/generator-report.js +7 -7
- package/dist/reports/report-archetypes.js +10 -10
- package/dist/reports/report-caretaker-health.js +2 -1
- package/dist/reports/report-patterns-usage.js +1 -1
- package/dist/sdk/analyzer.js +1 -1
- package/dist/shared/data-processing/fragment-report.js +11 -11
- package/dist/shared/data-processing/json.js +1 -1
- package/dist/shared/data-processing/occurrences.js +3 -2
- package/dist/shared/formatters/code-min-formatter.js +1 -1
- package/dist/shared/formatters/engines/prettier.js +1 -1
- package/dist/shared/formatters/engines/stylelint.js +43 -40
- package/dist/shared/formatters/formatter.js +8 -8
- package/dist/shared/formatters/formatters/code.js +3 -3
- package/dist/shared/formatters/formatters/css.js +2 -10
- package/dist/shared/formatters/formatters/dotfiles.js +1 -1
- package/dist/shared/formatters/formatters/html.js +1 -5
- package/dist/shared/formatters/formatters/json.js +0 -3
- package/dist/shared/formatters/formatters/markdown.js +19 -24
- package/dist/shared/formatters/formatters/properties.js +2 -2
- package/dist/shared/formatters/formatters/shell.js +1 -4
- package/dist/shared/formatters/formatters/sql.js +0 -3
- package/dist/shared/formatters/formatters/xml.js +5 -7
- package/dist/shared/formatters/formatters/yaml.js +2 -7
- package/dist/shared/formatters/index.js +1 -1
- package/dist/shared/helpers/framework-detector.js +6 -2
- package/dist/shared/helpers/json.js +1 -1
- package/dist/shared/helpers/magic-constants-whitelist.js +1 -1
- package/dist/shared/helpers/masking.js +17 -17
- package/dist/shared/helpers/reader-report.js +0 -12
- package/dist/shared/helpers/structural-hash.js +3 -2
- package/dist/shared/helpers/structure.js +1 -1
- package/dist/shared/marketplace/registry.js +1 -1
- package/dist/shared/marketplace/remote.js +4 -4
- package/dist/shared/persistence/persistence.js +13 -6
- package/dist/shared/plugins/core-plugin.js +5 -1
- package/dist/shared/plugins/registry.js +3 -2
- package/dist/types/analysts/tailwind-correction.js +2 -0
- package/dist/types/caretakers/imports-barrel.js +1 -0
- package/dist/types/caretakers/index.js +4 -0
- package/dist/types/caretakers/map-reversion.js +1 -0
- package/dist/types/caretakers/pruning.js +1 -0
- package/dist/types/caretakers/scoring.js +1 -0
- package/dist/types/common/analysts.js +1 -1
- package/dist/types/core/config/filters.js +1 -0
- package/dist/types/core/config/index.js +2 -0
- package/dist/types/core/execution/ambiente.js +1 -0
- package/dist/types/core/execution/linguagens.js +1 -0
- package/dist/types/core/execution/parse-errors.js +1 -0
- package/dist/types/core/execution/results.js +1 -0
- package/dist/types/core/execution/structure-json.js +1 -0
- package/dist/types/core/index.js +1 -0
- package/dist/types/core/messages/index.js +1 -0
- package/dist/types/core/messages/log.js +1 -0
- package/dist/types/core/parsing/babel-narrow.js +1 -0
- package/dist/types/core/parsing/index.js +1 -0
- package/dist/types/core/runtime.js +1 -0
- package/dist/types/guardian/index.js +2 -0
- package/dist/types/guardian/integrity.js +7 -0
- package/dist/types/guardian/snapshot.js +1 -0
- package/dist/types/index.js +4 -4
- package/dist/types/licenses/index.js +2 -0
- package/dist/types/processing/display.js +16 -13
- package/dist/types/processing/filters.js +8 -11
- package/dist/types/reports/compliance.js +1 -0
- package/dist/types/reports/streaming.js +1 -0
- package/dist/types/scripts/index.js +1 -0
- package/dist/types/scripts/migrar-aliases.js +1 -0
- package/dist/types/sdk/index.js +1 -0
- package/dist/types/shared/index.js +2 -0
- package/dist/types/vulnerabilities/index.js +2 -0
- package/dist/vulnerabilities/scanner.js +3 -2
- package/package.json +14 -20
|
@@ -45,7 +45,7 @@ const visitorFragil = {
|
|
|
45
45
|
const fragilidades = visitorState.resultados.get('codigo-fragil') ?? [];
|
|
46
46
|
let depth = 0;
|
|
47
47
|
let current = path;
|
|
48
|
-
while (current) {
|
|
48
|
+
while (current.node.type !== 'Program') {
|
|
49
49
|
if (current.isIfStatement()) {
|
|
50
50
|
depth++;
|
|
51
51
|
}
|
|
@@ -65,9 +65,9 @@ const visitorFragil = {
|
|
|
65
65
|
FunctionDeclaration(path, state) {
|
|
66
66
|
const visitorState = state;
|
|
67
67
|
const fragilidades = visitorState.resultados.get('codigo-fragil') ?? [];
|
|
68
|
-
const maxLinhas = config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_LINHAS_FUNCAO
|
|
68
|
+
const maxLinhas = config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_LINHAS_FUNCAO;
|
|
69
69
|
const node = path.node;
|
|
70
|
-
|
|
70
|
+
{
|
|
71
71
|
const inicio = node.loc?.start.line ?? 0;
|
|
72
72
|
const fim = node.loc?.end.line ?? 0;
|
|
73
73
|
const numLinhas = fim - inicio;
|
|
@@ -90,7 +90,7 @@ const visitorFragil = {
|
|
|
90
90
|
if (isInVariableDeclarator(path) || isInArrayIndex(path)) {
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
frameworksDetectados
|
|
93
|
+
frameworksDetectados = detectarFrameworks(process.cwd()).map(arquivo => arquivo.name);
|
|
94
94
|
if (isWhitelistedConstant(value, frameworksDetectados)) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
@@ -104,14 +104,43 @@ const visitorFragil = {
|
|
|
104
104
|
visitorState.resultados.set('codigo-fragil', fragilidades);
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
|
+
function converterFragilidadesParaOcorrencias(fragilidades, relPath) {
|
|
108
|
+
const ocorrencias = [];
|
|
109
|
+
const porSeveridade = agruparPor(fragilidades, arquivo => arquivo.severidade ?? 'media');
|
|
110
|
+
for (const [severidade, items] of Object.entries(porSeveridade)) {
|
|
111
|
+
if (items.length === 0) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const nivel = severidade === 'critica' || severidade === 'alta' ? 'erro' : severidade === 'media' ? 'aviso' : 'info';
|
|
115
|
+
const tipos = {};
|
|
116
|
+
for (const it of items) {
|
|
117
|
+
tipos[it.tipo] = (tipos[it.tipo] || 0) + 1;
|
|
118
|
+
}
|
|
119
|
+
const resumo = items.slice(0, 3).map(caminho => caminho.tipo).join(', ');
|
|
120
|
+
const amostra = items.slice(0, 5).map(it => `${it.tipo} (L${it.linha})`);
|
|
121
|
+
ocorrencias.push(criarOcorrencia({
|
|
122
|
+
tipo: 'codigo-fragil',
|
|
123
|
+
nivel,
|
|
124
|
+
mensagem: messages.DetectorCodigoFragilMensagens.fragilidadesResumo(severidade, resumo, {
|
|
125
|
+
severidade,
|
|
126
|
+
total: items.length,
|
|
127
|
+
tipos,
|
|
128
|
+
amostra
|
|
129
|
+
}),
|
|
130
|
+
relPath,
|
|
131
|
+
linha: items[0].linha
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
return ocorrencias;
|
|
135
|
+
}
|
|
107
136
|
export const analistaCodigoFragil = {
|
|
108
137
|
nome: 'codigo-fragil',
|
|
109
138
|
categoria: 'qualidade',
|
|
110
139
|
descricao: 'Detecta padrões de código que podem levar a problemas futuros',
|
|
111
140
|
limites: {
|
|
112
|
-
maxLinhasFuncao: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_LINHAS_FUNCAO
|
|
113
|
-
maxParametros: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_PARAMETROS
|
|
114
|
-
maxNestedCallbacks: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_NESTED_CALLBACKS
|
|
141
|
+
maxLinhasFuncao: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_LINHAS_FUNCAO,
|
|
142
|
+
maxParametros: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_PARAMETROS,
|
|
143
|
+
maxNestedCallbacks: config.ANALISE_LIMITES.CODIGO_FRAGIL.MAX_NESTED_CALLBACKS
|
|
115
144
|
},
|
|
116
145
|
visitor: visitorFragil,
|
|
117
146
|
test: (relPath) => {
|
|
@@ -156,11 +185,12 @@ export const analistaCodigoFragil = {
|
|
|
156
185
|
});
|
|
157
186
|
}
|
|
158
187
|
// Processamento AST: Otimizado (preColetado) ou Fallback
|
|
159
|
-
|
|
160
|
-
|
|
188
|
+
const astMeta = ast;
|
|
189
|
+
if (astMeta?.preColetado) {
|
|
190
|
+
fragilidades.push(...astMeta.preColetado);
|
|
161
191
|
}
|
|
162
192
|
else {
|
|
163
|
-
const nodeToTraverse =
|
|
193
|
+
const nodeToTraverse = astMeta?.node ?? ast;
|
|
164
194
|
const stateMock = {
|
|
165
195
|
resultados: new Map([['codigo-fragil', []]])
|
|
166
196
|
};
|
|
@@ -169,32 +199,7 @@ export const analistaCodigoFragil = {
|
|
|
169
199
|
}
|
|
170
200
|
// Detecções de texto complementares (Heurísticas)
|
|
171
201
|
detectarProblemasAvancados(src, fragilidades);
|
|
172
|
-
|
|
173
|
-
const ocorrencias = [];
|
|
174
|
-
const porSeveridade = agruparPor(fragilidades, arquivo => arquivo.severidade ?? 'media');
|
|
175
|
-
for (const [severidade, items] of Object.entries(porSeveridade)) {
|
|
176
|
-
if (items.length > 0) {
|
|
177
|
-
const nivel = severidade === 'critica' || severidade === 'alta' ? 'erro' : severidade === 'media' ? 'aviso' : 'info';
|
|
178
|
-
const resumo = items.slice(0, 3).map(caminho => caminho.tipo).join(', ');
|
|
179
|
-
const tipos = {};
|
|
180
|
-
for (const it of items) {
|
|
181
|
-
tipos[it.tipo] = (tipos[it.tipo] || 0) + 1;
|
|
182
|
-
}
|
|
183
|
-
const amostra = items.slice(0, 5).map(it => `${it.tipo} (L${it.linha})`);
|
|
184
|
-
ocorrencias.push(criarOcorrencia({
|
|
185
|
-
tipo: 'codigo-fragil',
|
|
186
|
-
nivel,
|
|
187
|
-
mensagem: messages.DetectorCodigoFragilMensagens.fragilidadesResumo(severidade, resumo, {
|
|
188
|
-
severidade,
|
|
189
|
-
total: items.length,
|
|
190
|
-
tipos,
|
|
191
|
-
amostra
|
|
192
|
-
}),
|
|
193
|
-
relPath,
|
|
194
|
-
linha: items[0].linha
|
|
195
|
-
}));
|
|
196
|
-
}
|
|
197
|
-
}
|
|
202
|
+
const ocorrencias = converterFragilidadesParaOcorrencias(fragilidades, relPath);
|
|
198
203
|
return filtrarOcorrenciasSuprimidas(ocorrencias, 'codigo-fragil', src);
|
|
199
204
|
}
|
|
200
205
|
};
|
|
@@ -14,7 +14,7 @@ function ehImportSomenteTipo(node) {
|
|
|
14
14
|
if (node.importKind === 'type') {
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
-
const specifiers = node.specifiers
|
|
17
|
+
const specifiers = node.specifiers;
|
|
18
18
|
if (specifiers.length === 0) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
@@ -185,12 +185,12 @@ function processarImportDeclaration(caminho, state) {
|
|
|
185
185
|
}
|
|
186
186
|
const val = caminho.node.source.value;
|
|
187
187
|
if (somenteTipo) {
|
|
188
|
-
const specifiers = caminho.node.specifiers
|
|
188
|
+
const specifiers = caminho.node.specifiers;
|
|
189
189
|
for (const s of specifiers) {
|
|
190
190
|
if (s.type === 'ImportDefaultSpecifier' || s.type === 'ImportSpecifier') {
|
|
191
191
|
state.importsDeclarados.add(s.local.name);
|
|
192
192
|
}
|
|
193
|
-
else
|
|
193
|
+
else {
|
|
194
194
|
state.importsDeclarados.add(s.local.name);
|
|
195
195
|
}
|
|
196
196
|
}
|
|
@@ -240,12 +240,12 @@ function processarImportDeclaration(caminho, state) {
|
|
|
240
240
|
});
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
const specifiers = caminho.node.specifiers
|
|
243
|
+
const specifiers = caminho.node.specifiers;
|
|
244
244
|
for (const s of specifiers) {
|
|
245
245
|
if (s.type === 'ImportDefaultSpecifier' || s.type === 'ImportSpecifier') {
|
|
246
246
|
state.importsDeclarados.add(s.local.name);
|
|
247
247
|
}
|
|
248
|
-
else
|
|
248
|
+
else {
|
|
249
249
|
state.importsDeclarados.add(s.local.name);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
@@ -13,7 +13,7 @@ export const analistaDuplicacoes = {
|
|
|
13
13
|
test: (relPath) => {
|
|
14
14
|
return /\.(js|jsx|ts|tsx|mjs|cjs)$/.test(relPath);
|
|
15
15
|
},
|
|
16
|
-
aplicar:
|
|
16
|
+
aplicar: (src, relPath, ast, fullCaminho, contexto) => {
|
|
17
17
|
if (!ast || !src || !contexto) {
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
@@ -40,24 +40,7 @@ export const analistaDuplicacoes = {
|
|
|
40
40
|
if (duplicacoes.length === 0) {
|
|
41
41
|
return [];
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
const porTipo = agruparPorTipoSimilaridade(duplicacoes);
|
|
45
|
-
const ocorrencias = [];
|
|
46
|
-
for (const [tipo, dups] of Object.entries(porTipo)) {
|
|
47
|
-
if (dups.length > 0) {
|
|
48
|
-
const nivel = tipo === 'identica' ? 'aviso' : 'info';
|
|
49
|
-
const primeiraFunc = dups[0]?.funcaoA;
|
|
50
|
-
const resumo = dups.map(diretorio => `${diretorio.funcaoA?.nome ?? 'unknown'} ≈ ${diretorio.funcaoB?.nome ?? 'unknown'} (${diretorio.similaridade.toFixed(0)}%)`).slice(0, 3).join(', ');
|
|
51
|
-
ocorrencias.push(criarOcorrencia({
|
|
52
|
-
tipo: 'codigo_duplicado',
|
|
53
|
-
nivel,
|
|
54
|
-
mensagem: messages.DetectorAgregadosMensagens.duplicacoesResumo(tipo, resumo, dups.length),
|
|
55
|
-
relPath,
|
|
56
|
-
linha: primeiraFunc?.inicio ?? 1
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return ocorrencias;
|
|
43
|
+
return agruparEConverterDuplicacoes(duplicacoes, relPath);
|
|
61
44
|
}
|
|
62
45
|
catch (erro) {
|
|
63
46
|
return [criarOcorrencia({
|
|
@@ -70,6 +53,26 @@ export const analistaDuplicacoes = {
|
|
|
70
53
|
}
|
|
71
54
|
}
|
|
72
55
|
};
|
|
56
|
+
function agruparEConverterDuplicacoes(duplicacoes, relPath) {
|
|
57
|
+
const porTipo = agruparPorTipoSimilaridade(duplicacoes);
|
|
58
|
+
const ocorrencias = [];
|
|
59
|
+
for (const [tipo, dups] of Object.entries(porTipo)) {
|
|
60
|
+
if (dups.length === 0) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const nivel = tipo === 'identica' ? 'aviso' : 'info';
|
|
64
|
+
const primeiraFunc = dups[0]?.funcaoA;
|
|
65
|
+
const resumo = dups.map(diretorio => `${diretorio.funcaoA?.nome ?? 'unknown'} ≈ ${diretorio.funcaoB?.nome ?? 'unknown'} (${diretorio.similaridade.toFixed(0)}%)`).slice(0, 3).join(', ');
|
|
66
|
+
ocorrencias.push(criarOcorrencia({
|
|
67
|
+
tipo: 'codigo_duplicado',
|
|
68
|
+
nivel,
|
|
69
|
+
mensagem: messages.DetectorAgregadosMensagens.duplicacoesResumo(tipo, resumo, dups.length),
|
|
70
|
+
relPath,
|
|
71
|
+
linha: primeiraFunc?.inicio ?? 1
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
return ocorrencias;
|
|
75
|
+
}
|
|
73
76
|
function extrairFuncoes(ast, caminho, src) {
|
|
74
77
|
const funcoes = [];
|
|
75
78
|
const linhas = src.split('\n');
|
|
@@ -125,12 +128,12 @@ function extrairInfoFuncao(path, caminho, tipoFuncao, linhas) {
|
|
|
125
128
|
if ('id' in node && node.id && 'name' in node.id) {
|
|
126
129
|
nome = node.id.name;
|
|
127
130
|
}
|
|
128
|
-
else if ('key' in node &&
|
|
131
|
+
else if ('key' in node && 'name' in node.key) {
|
|
129
132
|
nome = node.key.name;
|
|
130
133
|
}
|
|
131
134
|
else if (path.parentPath.isVariableDeclarator()) {
|
|
132
135
|
const parent = path.parentPath.node;
|
|
133
|
-
nome = 'id' in parent &&
|
|
136
|
+
nome = 'id' in parent && 'name' in parent.id ? parent.id.name : 'assigned';
|
|
134
137
|
}
|
|
135
138
|
// Extrair parâmetros
|
|
136
139
|
const parametros = ('params' in node && Array.isArray(node.params) ? node.params : []).map((param) => {
|
|
@@ -138,7 +141,7 @@ function extrairInfoFuncao(path, caminho, tipoFuncao, linhas) {
|
|
|
138
141
|
if (param.type === 'Identifier' && 'name' in param) {
|
|
139
142
|
return param.name;
|
|
140
143
|
} // Identifier node
|
|
141
|
-
if (param.type === 'RestElement' && 'argument' in param &&
|
|
144
|
+
if (param.type === 'RestElement' && 'argument' in param && 'name' in param.argument) {
|
|
142
145
|
return `...${param.argument.name}`; // RestElement node
|
|
143
146
|
}
|
|
144
147
|
return param.type;
|
|
@@ -257,10 +260,7 @@ function agruparPorTipoSimilaridade(duplicacoes) {
|
|
|
257
260
|
return duplicacoes.reduce((acc, dup) => {
|
|
258
261
|
const tipo = dup.tipoSimilaridade;
|
|
259
262
|
if (tipo) {
|
|
260
|
-
|
|
261
|
-
acc[tipo] = [];
|
|
262
|
-
}
|
|
263
|
-
acc[tipo].push(dup);
|
|
263
|
+
(acc[tipo] ??= []).push(dup);
|
|
264
264
|
}
|
|
265
265
|
return acc;
|
|
266
266
|
}, {});
|
|
@@ -14,7 +14,7 @@ export function detectarMonorepo(baseDir) {
|
|
|
14
14
|
return info;
|
|
15
15
|
}
|
|
16
16
|
// Detect package manager
|
|
17
|
-
const pm = rootPkg.packageManager
|
|
17
|
+
const pm = rootPkg.packageManager ?? '';
|
|
18
18
|
if (pm) {
|
|
19
19
|
info.packageManager = pm;
|
|
20
20
|
}
|
|
@@ -51,11 +51,12 @@ export function detectarMonorepo(baseDir) {
|
|
|
51
51
|
info.type = 'nx';
|
|
52
52
|
try {
|
|
53
53
|
const nx = JSON.parse(fs.readFileSync(nxPath, 'utf-8'));
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const nxLayout = nx.workspaceLayout;
|
|
55
|
+
if (nxLayout?.appsDir) {
|
|
56
|
+
workspaceGlobs.push(nxLayout.appsDir);
|
|
56
57
|
}
|
|
57
|
-
if (
|
|
58
|
-
workspaceGlobs.push(
|
|
58
|
+
if (nxLayout?.libsDir) {
|
|
59
|
+
workspaceGlobs.push(nxLayout.libsDir);
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
catch { }
|
|
@@ -82,7 +83,7 @@ export function detectarMonorepo(baseDir) {
|
|
|
82
83
|
if (Array.isArray(rootPkg.workspaces)) {
|
|
83
84
|
workspaceGlobs = rootPkg.workspaces;
|
|
84
85
|
}
|
|
85
|
-
else if (typeof rootPkg.workspaces === 'object'
|
|
86
|
+
else if (typeof rootPkg.workspaces === 'object') {
|
|
86
87
|
const ws = rootPkg.workspaces;
|
|
87
88
|
if (Array.isArray(ws.packages)) {
|
|
88
89
|
workspaceGlobs = ws.packages;
|
|
@@ -132,9 +133,9 @@ function resolverWorkspaces(rootDir, globs) {
|
|
|
132
133
|
name: pkg.name || entry.name,
|
|
133
134
|
dir: resolved,
|
|
134
135
|
packageJson: pkg,
|
|
135
|
-
dependencies: pkg.dependencies
|
|
136
|
-
devDependencies: pkg.devDependencies
|
|
137
|
-
peerDependencies: pkg.peerDependencies
|
|
136
|
+
dependencies: pkg.dependencies,
|
|
137
|
+
devDependencies: pkg.devDependencies,
|
|
138
|
+
peerDependencies: pkg.peerDependencies,
|
|
138
139
|
});
|
|
139
140
|
}
|
|
140
141
|
}
|
|
@@ -173,7 +174,7 @@ export const detectorMonorepo = {
|
|
|
173
174
|
// Check for missing root scripts
|
|
174
175
|
const rootPkg = lerPackageJson(baseDir);
|
|
175
176
|
if (rootPkg) {
|
|
176
|
-
const scripts = rootPkg.scripts
|
|
177
|
+
const scripts = rootPkg.scripts;
|
|
177
178
|
const expectedScripts = ['build', 'test', 'lint'];
|
|
178
179
|
for (const script of expectedScripts) {
|
|
179
180
|
if (!scripts[script]) {
|
|
@@ -236,47 +237,52 @@ export const detectorMonorepo = {
|
|
|
236
237
|
versionMap.set(dep, verMap);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
240
|
+
detectarVersionMismatch(versionMap, ocorrencias);
|
|
241
|
+
detectarDependenciasInternasFaltando(info, ocorrencias);
|
|
242
|
+
return ocorrencias;
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
function detectarVersionMismatch(versionMap, ocorrencias) {
|
|
246
|
+
for (const [dep, versions] of versionMap) {
|
|
247
|
+
if (versions.size > 1) {
|
|
248
|
+
const uniqueVersions = new Set(versions.values());
|
|
249
|
+
if (uniqueVersions.size > 1) {
|
|
250
|
+
ocorrencias.push({
|
|
251
|
+
tipo: 'monorepo-versao-mismatch',
|
|
252
|
+
nivel: 'aviso',
|
|
253
|
+
mensagem: `Dependência ${dep} com versões diferentes entre workspaces: ${Array.from(versions.entries()).map(([w, v]) => `${w}@${v}`).join(', ')}`,
|
|
254
|
+
origem: 'detector-monorepo',
|
|
255
|
+
relPath: '[monorepo]',
|
|
256
|
+
linha: 0,
|
|
257
|
+
});
|
|
252
258
|
}
|
|
253
259
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function detectarDependenciasInternasFaltando(info, ocorrencias) {
|
|
263
|
+
const workspaceNames = new Set(info.workspaces.map(w => w.name));
|
|
264
|
+
for (const ws of info.workspaces) {
|
|
265
|
+
const imports = coletarImports(ws.dir);
|
|
266
|
+
for (const imp of imports) {
|
|
267
|
+
for (const wsName of workspaceNames) {
|
|
268
|
+
if (imp.includes(wsName) && wsName !== ws.name) {
|
|
269
|
+
const isDep = ws.dependencies[wsName] || ws.devDependencies[wsName] || ws.peerDependencies[wsName];
|
|
270
|
+
if (!isDep) {
|
|
271
|
+
ocorrencias.push({
|
|
272
|
+
tipo: 'monorepo-dependencia-interna-faltando',
|
|
273
|
+
nivel: 'aviso',
|
|
274
|
+
mensagem: `${ws.name} importa ${wsName} mas não o declara como dependência`,
|
|
275
|
+
origem: 'detector-monorepo',
|
|
276
|
+
relPath: `[${ws.name}]`,
|
|
277
|
+
linha: 0,
|
|
278
|
+
});
|
|
273
279
|
}
|
|
280
|
+
break;
|
|
274
281
|
}
|
|
275
282
|
}
|
|
276
283
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
280
286
|
function coletarImports(dir) {
|
|
281
287
|
const imports = [];
|
|
282
288
|
try {
|
|
@@ -169,12 +169,33 @@ function detectarPadroesPerformance(src, problemas, relPath) {
|
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
|
+
function detectarTimerSemCleanup(path, ast, problemas, relPath) {
|
|
173
|
+
if (path.node.callee.type !== 'Identifier') {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (path.node.callee.name !== 'setTimeout' && path.node.callee.name !== 'setInterval') {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const parentFunction = path.getFunctionParent();
|
|
180
|
+
const context = parentFunction ? parentFunction.toString() : ast.toString();
|
|
181
|
+
if (context.includes('clear') || relPath.includes('test')) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
problemas.push({
|
|
185
|
+
tipo: 'memory-leak',
|
|
186
|
+
descricao: `${path.node.callee.name} sem cleanup pode causar vazamento`,
|
|
187
|
+
impacto: 'medio',
|
|
188
|
+
linha: path.node.loc?.start.line ?? 0,
|
|
189
|
+
coluna: path.node.loc?.start.column ?? 0,
|
|
190
|
+
sugestao: `Use clear${path.node.callee.name.replace('set', '')} para limpar`
|
|
191
|
+
});
|
|
192
|
+
}
|
|
172
193
|
function detectarProblemasPerformanceAST(ast, problemas, relPath) {
|
|
173
194
|
try {
|
|
174
195
|
const isLoop = (type) => ['ForStatement', 'WhileStatement', 'DoWhileStatement', 'ForInStatement', 'ForOfStatement'].includes(type);
|
|
175
196
|
const checkNesting = (path) => {
|
|
176
197
|
let parent = path.parentPath;
|
|
177
|
-
while (parent) {
|
|
198
|
+
while ((parent.node).type !== 'Program') {
|
|
178
199
|
if (isLoop(parent.type)) {
|
|
179
200
|
problemas.push({
|
|
180
201
|
tipo: 'inefficient-loop',
|
|
@@ -195,23 +216,8 @@ function detectarProblemasPerformanceAST(ast, problemas, relPath) {
|
|
|
195
216
|
DoWhileStatement: checkNesting,
|
|
196
217
|
ForInStatement: checkNesting,
|
|
197
218
|
ForOfStatement: checkNesting,
|
|
198
|
-
// Detectar função setTimeout/setInterval sem cleanup
|
|
199
219
|
CallExpression(path) {
|
|
200
|
-
|
|
201
|
-
// Heurística simples: se não há clear* na mesma função/arquivo
|
|
202
|
-
const parentFunction = path.getFunctionParent();
|
|
203
|
-
const context = parentFunction ? parentFunction.toString() : ast.toString();
|
|
204
|
-
if (!context.includes('clear') && !relPath.includes('test')) {
|
|
205
|
-
problemas.push({
|
|
206
|
-
tipo: 'memory-leak',
|
|
207
|
-
descricao: `${path.node.callee.name} sem cleanup pode causar vazamento`,
|
|
208
|
-
impacto: 'medio',
|
|
209
|
-
linha: path.node.loc?.start.line ?? 0,
|
|
210
|
-
coluna: path.node.loc?.start.column ?? 0,
|
|
211
|
-
sugestao: `Use clear${path.node.callee.name.replace('set', '')} para limpar`
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
220
|
+
detectarTimerSemCleanup(path, ast, problemas, relPath);
|
|
215
221
|
}
|
|
216
222
|
});
|
|
217
223
|
}
|
|
@@ -226,6 +232,7 @@ function mapearImpactoParaNivel(impacto) {
|
|
|
226
232
|
case 'medio':
|
|
227
233
|
return 'aviso';
|
|
228
234
|
case 'baixo':
|
|
235
|
+
return 'info';
|
|
229
236
|
case undefined: {
|
|
230
237
|
throw new Error('Not implemented yet: undefined case');
|
|
231
238
|
}
|
|
@@ -3,6 +3,43 @@ import { criarOcorrencia } from '../../types/index.js';
|
|
|
3
3
|
* Analista global que analisa o projeto completo e recomenda
|
|
4
4
|
* a melhor arquitetura (Clean Architecture, Microsserviços, MVC, etc.)
|
|
5
5
|
*/
|
|
6
|
+
const CONFIANCA_SIMPLES = 60;
|
|
7
|
+
function adicionarOcorrenciasRecomendacao(ocorrencias, _relPath, sinaisCleanArch, sinaisDistributed, recomendacoes, arquiteturaRecomendada, confianca) {
|
|
8
|
+
ocorrencias.push(criarOcorrencia({
|
|
9
|
+
tipo: 'recomendacao-arquitetura',
|
|
10
|
+
nivel: 'info',
|
|
11
|
+
relPath: _relPath,
|
|
12
|
+
linha: 1,
|
|
13
|
+
mensagem: `[TARGET] Arquitetura recomendada: ${arquiteturaRecomendada} (${confianca}% confiança)`
|
|
14
|
+
}));
|
|
15
|
+
if (sinaisCleanArch.length > 0) {
|
|
16
|
+
ocorrencias.push(criarOcorrencia({
|
|
17
|
+
tipo: 'sinais-clean-arch',
|
|
18
|
+
nivel: 'info',
|
|
19
|
+
relPath: _relPath,
|
|
20
|
+
linha: 1,
|
|
21
|
+
mensagem: `Sinais de Clean Architecture: ${sinaisCleanArch.join(', ')}`
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
if (sinaisDistributed.length > 0) {
|
|
25
|
+
ocorrencias.push(criarOcorrencia({
|
|
26
|
+
tipo: 'sinais-distributed-arch',
|
|
27
|
+
nivel: 'info',
|
|
28
|
+
relPath: _relPath,
|
|
29
|
+
linha: 1,
|
|
30
|
+
mensagem: `Sinais de Arquitetura Distribuída: ${sinaisDistributed.join(', ')}`
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
for (const rec of recomendacoes.slice(0, 5)) {
|
|
34
|
+
ocorrencias.push(criarOcorrencia({
|
|
35
|
+
tipo: 'recomendacao-arquitetura-item',
|
|
36
|
+
nivel: 'info',
|
|
37
|
+
relPath: _relPath,
|
|
38
|
+
linha: 1,
|
|
39
|
+
mensagem: `[IDEA] ${rec}`
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
6
43
|
export const analistaRecomendacaoArquitetura = {
|
|
7
44
|
nome: 'recomendacao-arquitetura',
|
|
8
45
|
categoria: 'arquitetura',
|
|
@@ -210,7 +247,7 @@ export const analistaRecomendacaoArquitetura = {
|
|
|
210
247
|
}
|
|
211
248
|
// MVC para projetos web tradicionais
|
|
212
249
|
if (temFrontend && temControllers && !temEntities) {
|
|
213
|
-
const scoreMvc =
|
|
250
|
+
const scoreMvc = 30;
|
|
214
251
|
if (scoreMvc > melhorScore && !complexidadeBaixa) {
|
|
215
252
|
arquiteturaRecomendada = 'MVC (Model-View-Controller)';
|
|
216
253
|
melhorScore = scoreMvc;
|
|
@@ -221,7 +258,7 @@ export const analistaRecomendacaoArquitetura = {
|
|
|
221
258
|
if (melhorScore === 0) {
|
|
222
259
|
if (complexidadeBaixa) {
|
|
223
260
|
arquiteturaRecomendada = 'Arquitetura Simples / Monolítica';
|
|
224
|
-
confianca =
|
|
261
|
+
confianca = CONFIANCA_SIMPLES;
|
|
225
262
|
recomendacoes.push('Projeto de baixa complexidade - comece com uma estrutura simples');
|
|
226
263
|
recomendacoes.push('Considere evoluir para Clean Architecture conforme o projeto crescer');
|
|
227
264
|
}
|
|
@@ -243,40 +280,7 @@ export const analistaRecomendacaoArquitetura = {
|
|
|
243
280
|
if (totalArquivos > 100 && servicosSet.size === 0) {
|
|
244
281
|
recomendacoes.push('Projeto grande e monolítico - considere dividir em serviços menores');
|
|
245
282
|
}
|
|
246
|
-
ocorrencias
|
|
247
|
-
tipo: 'recomendacao-arquitetura',
|
|
248
|
-
nivel: 'info',
|
|
249
|
-
relPath: _relPath,
|
|
250
|
-
linha: 1,
|
|
251
|
-
mensagem: `[TARGET] Arquitetura recomendada: ${arquiteturaRecomendada} (${confianca}% confiança)`
|
|
252
|
-
}));
|
|
253
|
-
if (sinaisCleanArch.length > 0) {
|
|
254
|
-
ocorrencias.push(criarOcorrencia({
|
|
255
|
-
tipo: 'sinais-clean-arch',
|
|
256
|
-
nivel: 'info',
|
|
257
|
-
relPath: _relPath,
|
|
258
|
-
linha: 1,
|
|
259
|
-
mensagem: `Sinais de Clean Architecture: ${sinaisCleanArch.join(', ')}`
|
|
260
|
-
}));
|
|
261
|
-
}
|
|
262
|
-
if (sinaisDistributed.length > 0) {
|
|
263
|
-
ocorrencias.push(criarOcorrencia({
|
|
264
|
-
tipo: 'sinais-distributed-arch',
|
|
265
|
-
nivel: 'info',
|
|
266
|
-
relPath: _relPath,
|
|
267
|
-
linha: 1,
|
|
268
|
-
mensagem: `Sinais de Arquitetura Distribuída: ${sinaisDistributed.join(', ')}`
|
|
269
|
-
}));
|
|
270
|
-
}
|
|
271
|
-
for (const rec of recomendacoes.slice(0, 5)) {
|
|
272
|
-
ocorrencias.push(criarOcorrencia({
|
|
273
|
-
tipo: 'recomendacao-arquitetura-item',
|
|
274
|
-
nivel: 'info',
|
|
275
|
-
relPath: _relPath,
|
|
276
|
-
linha: 1,
|
|
277
|
-
mensagem: `[IDEA] ${rec}`
|
|
278
|
-
}));
|
|
279
|
-
}
|
|
283
|
+
adicionarOcorrenciasRecomendacao(ocorrencias, _relPath, sinaisCleanArch, sinaisDistributed, recomendacoes, arquiteturaRecomendada, confianca);
|
|
280
284
|
return ocorrencias;
|
|
281
285
|
}
|
|
282
286
|
};
|