@mocoto/mahoraga 0.14.1 → 0.14.2
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/dist/analysts/architects/analyst-structure.js +1 -1
- package/dist/analysts/architects/archetypes-custom.js +8 -13
- package/dist/analysts/architects/detector-archetypes.js +39 -35
- package/dist/analysts/architects/orchestrator-archetypes.js +3 -3
- package/dist/analysts/architects/signals-project-advanced.js +2 -2
- package/dist/analysts/architects/signals-project.js +1 -1
- package/dist/analysts/azure-pipelines/analysts/analyst-azure.js +20 -21
- package/dist/analysts/azure-pipelines/detectors/detector-azure-structure.js +0 -3
- package/dist/analysts/circleci/analysts/analyst-circleci.js +22 -24
- package/dist/analysts/circleci/detectors/detector-circleci-structure.js +4 -7
- package/dist/analysts/converters/convert-registry.js +1 -1
- package/dist/analysts/converters/index.js +1 -1
- package/dist/analysts/corrections/auto-fix-engine.js +1 -1
- package/dist/analysts/corrections/corrector-structure.js +8 -7
- package/dist/analysts/corrections/map-reversion.js +2 -2
- package/dist/analysts/corrections/reorganize-barrels.js +3 -3
- package/dist/analysts/corrections/rewrite-testes-aliases.js +23 -22
- package/dist/analysts/corrections/type-safety/type-analyzer.js +3 -3
- package/dist/analysts/corrections/type-safety/type-validator.js +2 -2
- package/dist/analysts/corrections/type-safety/usage-analyzer.js +3 -3
- package/dist/analysts/css/analysts/analyst-css.js +27 -28
- package/dist/analysts/css-in-js/detectors/detector-css-in-js-best-practices.js +8 -15
- package/dist/analysts/detectors/detector-architecture.js +2 -2
- package/dist/analysts/detectors/detector-bugs-ml.js +8 -8
- package/dist/analysts/detectors/detector-code-fragile.js +11 -10
- package/dist/analysts/detectors/detector-dependencies.js +5 -5
- package/dist/analysts/detectors/detector-duplications.js +5 -8
- package/dist/analysts/detectors/detector-monorepo.js +10 -9
- package/dist/analysts/detectors/detector-performance.js +2 -1
- package/dist/analysts/detectors/detector-recommendation-architecture.js +1 -1
- package/dist/analysts/detectors/detector-security.js +1 -1
- package/dist/analysts/detectors/detector-structure.js +3 -3
- 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 +81 -9
- package/dist/analysts/js-ts/detectors/detector-constructions-syntactic.js +35 -6
- 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 +5 -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 +63 -8
- package/dist/analysts/react/analysts/analyst-react.js +45 -1
- package/dist/analysts/react/corrections/correction-react.js +40 -0
- package/dist/analysts/react/detectors/detector-react-best-practices.js +4 -4
- package/dist/analysts/react/scorers/scorer-react.js +36 -1
- 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 +116 -9
- package/dist/analysts/tailwind/detectors/detector-tailwind-best-practices.js +122 -7
- package/dist/analysts/tailwind/scorers/scorer-tailwind.js +62 -10
- 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 +1 -1
- 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-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 +3 -3
- 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/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 +2 -2
- package/dist/core/config/config.js +6 -8
- 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/executor.js +8 -19
- package/dist/core/execution/inquisitor.js +24 -21
- package/dist/core/execution/results.js +1 -0
- package/dist/core/execution/scanner.js +3 -3
- 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/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/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/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/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 +2 -2
- 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 +6 -1
- package/dist/guardian/result.js +1 -1
- package/dist/guardian/sentinel.js +6 -1
- package/dist/guardian/watcher-hidden.js +5 -1
- package/dist/licenses/fs-utils.js +4 -1
- package/dist/licenses/generate-notices.js +1 -1
- package/dist/licenses/header-options.js +0 -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 +4 -4
- package/dist/reports/report-archetypes.js +10 -10
- package/dist/reports/report-caretaker-health.js +2 -1
- package/dist/sdk/analyzer.js +1 -1
- package/dist/shared/data-processing/fragment-report.js +10 -10
- 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 +6 -9
- 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 +18 -23
- 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 +1 -1
- 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 +0 -1
- package/dist/shared/plugins/core-plugin.js +3 -1
- package/dist/shared/plugins/registry.js +3 -2
- 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 +3 -7
- 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/npm-audit.js +0 -1
- package/dist/vulnerabilities/scanner.js +2 -1
- package/dist/vulnerabilities/vulnerabilities.js +0 -1
- package/package.json +11 -12
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
import { splitLines } from '../../../shared/helpers/index.js';
|
|
3
3
|
import { criarOcorrencia } from '../../../types/index.js';
|
|
4
|
+
const V3_DEPRECATED_UTILITIES_MAP = {
|
|
5
|
+
'shadow-sm': 'shadow-xs',
|
|
6
|
+
'drop-shadow-sm': 'drop-shadow-xs',
|
|
7
|
+
'blur-sm': 'blur-xs',
|
|
8
|
+
'backdrop-blur-sm': 'backdrop-blur-xs',
|
|
9
|
+
'rounded-sm': 'rounded-xs',
|
|
10
|
+
'outline-none': 'outline-hidden',
|
|
11
|
+
'flex-shrink': 'shrink',
|
|
12
|
+
'flex-grow': 'grow',
|
|
13
|
+
'overflow-ellipsis': 'text-ellipsis',
|
|
14
|
+
'decoration-slice': 'box-decoration-slice',
|
|
15
|
+
'decoration-clone': 'box-decoration-clone',
|
|
16
|
+
};
|
|
17
|
+
const V3_SUFFIX_UTILITIES_MAP = {
|
|
18
|
+
'shadow': 'shadow-sm',
|
|
19
|
+
'drop-shadow': 'drop-shadow-sm',
|
|
20
|
+
'blur': 'blur-sm',
|
|
21
|
+
'backdrop-blur': 'backdrop-blur-sm',
|
|
22
|
+
'rounded': 'rounded-sm',
|
|
23
|
+
'ring': 'ring-3',
|
|
24
|
+
};
|
|
4
25
|
const TAILWIND_UTILITIES = new Set([
|
|
5
26
|
'bg-', 'text-', 'm-', 'mt-', 'mr-', 'mb-', 'ml-', 'mx-', 'my-',
|
|
6
27
|
'p-', 'pt-', 'pr-', 'pb-', 'pl-', 'px-', 'py-',
|
|
@@ -11,13 +32,16 @@ const TAILWIND_UTILITIES = new Set([
|
|
|
11
32
|
'transition', 'duration-', 'ease-', 'animate-',
|
|
12
33
|
'z-', 'overflow-', 'cursor-', 'select-', 'blur-',
|
|
13
34
|
'top-', 'left-', 'right-', 'bottom-', 'inset-',
|
|
35
|
+
'field-sizing-', 'text-shadow-', 'inset-shadow-', 'zoom-', 'perspective-',
|
|
36
|
+
'outline-', 'drop-shadow-', 'backdrop-blur-',
|
|
14
37
|
]);
|
|
15
38
|
const TAILWIND_COLORS = [
|
|
16
39
|
'slate', 'gray', 'zinc', 'neutral', 'stone', 'red', 'orange', 'amber',
|
|
17
40
|
'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue',
|
|
18
41
|
'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose',
|
|
42
|
+
'mauve', 'olive', 'mist', 'taupe',
|
|
19
43
|
];
|
|
20
|
-
function
|
|
44
|
+
function isTailwindColor(value) {
|
|
21
45
|
return TAILWIND_COLORS.some(c => value.includes(c));
|
|
22
46
|
}
|
|
23
47
|
function getPropertyKey(token) {
|
|
@@ -45,12 +69,27 @@ function getPropertyKey(token) {
|
|
|
45
69
|
if (/^opacity/.test(token)) {
|
|
46
70
|
return 'opacity';
|
|
47
71
|
}
|
|
72
|
+
if (/^field-sizing/.test(token)) {
|
|
73
|
+
return 'field-sizing';
|
|
74
|
+
}
|
|
75
|
+
if (/^text-shadow/.test(token)) {
|
|
76
|
+
return 'text-shadow';
|
|
77
|
+
}
|
|
78
|
+
if (/^inset-shadow/.test(token)) {
|
|
79
|
+
return 'inset-shadow';
|
|
80
|
+
}
|
|
81
|
+
if (/^zoom/.test(token)) {
|
|
82
|
+
return 'zoom';
|
|
83
|
+
}
|
|
84
|
+
if (/^perspective/.test(token)) {
|
|
85
|
+
return 'perspective';
|
|
86
|
+
}
|
|
48
87
|
return null;
|
|
49
88
|
}
|
|
50
89
|
export const detectorTailwindBestPractices = {
|
|
51
90
|
nome: 'detector-tailwind-best-practices',
|
|
52
91
|
categoria: 'estilo',
|
|
53
|
-
descricao: 'Detecta más práticas em Tailwind CSS',
|
|
92
|
+
descricao: 'Detecta más práticas em Tailwind CSS v4',
|
|
54
93
|
test: (relPath) => /\.(jsx|tsx|js|ts|html|astro)$/i.test(relPath),
|
|
55
94
|
aplicar: (src, relPath) => {
|
|
56
95
|
if (!src) {
|
|
@@ -62,10 +101,86 @@ export const detectorTailwindBestPractices = {
|
|
|
62
101
|
let inlineStyleCount = 0;
|
|
63
102
|
linhas.forEach((linha, index) => {
|
|
64
103
|
const numeroLinha = index + 1;
|
|
65
|
-
if (
|
|
104
|
+
if (/@tailwind\s+(base|components|utilities)/.test(linha)) {
|
|
105
|
+
ocorrencias.push(criarOcorrencia({
|
|
106
|
+
tipo: 'tailwind-v3-directive',
|
|
107
|
+
nivel: 'aviso',
|
|
108
|
+
mensagem: 'Diretiva @tailwind detectada (v3) - use @import "tailwindcss"',
|
|
109
|
+
relPath,
|
|
110
|
+
linha: numeroLinha,
|
|
111
|
+
sugestao: 'Substitua @tailwind base/components/utilities por @import "tailwindcss"'
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
if (/@layer\s+utilities\s*\{/.test(linha)) {
|
|
115
|
+
ocorrencias.push(criarOcorrencia({
|
|
116
|
+
tipo: 'tailwind-v3-layer-utilities',
|
|
117
|
+
nivel: 'info',
|
|
118
|
+
mensagem: '@layer utilities detectado (v3) - use @utility (v4)',
|
|
119
|
+
relPath,
|
|
120
|
+
linha: numeroLinha,
|
|
121
|
+
sugestao: 'Use @utility nome-da-utilidade { ... } ao invés de @layer utilities { ... }'
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
if (/\btheme\(/.test(linha)) {
|
|
125
|
+
ocorrencias.push(criarOcorrencia({
|
|
126
|
+
tipo: 'tailwind-theme-function',
|
|
127
|
+
nivel: 'info',
|
|
128
|
+
mensagem: 'theme() detectado (deprecated v3) - use CSS variables',
|
|
129
|
+
relPath,
|
|
130
|
+
linha: numeroLinha,
|
|
131
|
+
sugestao: 'Substitua theme(colors.red.500) por var(--color-red-500)'
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
if (/\bclass(Name)?\s*=\s*["'][^"']*![\w-]/.test(linha)) {
|
|
135
|
+
ocorrencias.push(criarOcorrencia({
|
|
136
|
+
tipo: 'tailwind-important-prefix',
|
|
137
|
+
nivel: 'info',
|
|
138
|
+
mensagem: '!important como prefixo (v3) - mova ! para o final da classe',
|
|
139
|
+
relPath,
|
|
140
|
+
linha: numeroLinha,
|
|
141
|
+
sugestao: 'Use "flex!" ao invés de "!flex"'
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
if (/\bclass(Name)?\s*=\s*["'][^"']*\[--[^\]]+\]/.test(linha)) {
|
|
145
|
+
ocorrencias.push(criarOcorrencia({
|
|
146
|
+
tipo: 'tailwind-arbitrary-var-syntax',
|
|
147
|
+
nivel: 'info',
|
|
148
|
+
mensagem: 'Variável em colchetes (v3) - use parênteses (v4)',
|
|
149
|
+
relPath,
|
|
150
|
+
linha: numeroLinha,
|
|
151
|
+
sugestao: 'Use bg-(--brand-color) ao invés de bg-[--brand-color]'
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
if (/\bclass(Name)?\s*=\s*["']([^"']*)["']/.test(linha)) {
|
|
66
155
|
const classMatch = linha.match(/\bclass(Name)?\s*=\s*["']([^"']*)["']/);
|
|
67
156
|
if (classMatch) {
|
|
68
157
|
const classes = classMatch[2].split(/\s+/).filter(Boolean);
|
|
158
|
+
for (const cls of classes) {
|
|
159
|
+
const v4Equivalent = V3_DEPRECATED_UTILITIES_MAP[cls];
|
|
160
|
+
if (v4Equivalent) {
|
|
161
|
+
ocorrencias.push(criarOcorrencia({
|
|
162
|
+
tipo: 'tailwind-v3-deprecated-utility',
|
|
163
|
+
nivel: 'aviso',
|
|
164
|
+
mensagem: `Classe obsoleta do v3: "${cls}" → use "${v4Equivalent}"`,
|
|
165
|
+
relPath,
|
|
166
|
+
linha: numeroLinha,
|
|
167
|
+
sugestao: `Substitua ${cls} por ${v4Equivalent}`
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
const baseClass = cls.split(':').pop() ?? cls;
|
|
171
|
+
if (baseClass && V3_SUFFIX_UTILITIES_MAP[baseClass]) {
|
|
172
|
+
const variante = cls.endsWith(baseClass) ? '' : cls.slice(0, -baseClass.length);
|
|
173
|
+
const v4Suffix = V3_SUFFIX_UTILITIES_MAP[baseClass];
|
|
174
|
+
ocorrencias.push(criarOcorrencia({
|
|
175
|
+
tipo: 'tailwind-v3-deprecated-utility',
|
|
176
|
+
nivel: 'aviso',
|
|
177
|
+
mensagem: `Classe renomeada no v4: "${cls}" → use "${variante}${v4Suffix}"`,
|
|
178
|
+
relPath,
|
|
179
|
+
linha: numeroLinha,
|
|
180
|
+
sugestao: `Substitua ${cls} por ${variante}${v4Suffix} (ex: shadow → shadow-sm)`
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
69
184
|
const seen = new Map();
|
|
70
185
|
classes.forEach(token => {
|
|
71
186
|
const base = token.split(':').pop() ?? token;
|
|
@@ -139,7 +254,7 @@ export const detectorTailwindBestPractices = {
|
|
|
139
254
|
}
|
|
140
255
|
const hardcodedValues = classes.filter(c => {
|
|
141
256
|
const val = c.split('-').pop() ?? '';
|
|
142
|
-
return /^\d+$/.test(val) && !
|
|
257
|
+
return /^\d+$/.test(val) && !isTailwindColor(c) && val.length > 2;
|
|
143
258
|
});
|
|
144
259
|
if (hardcodedValues.length > 0 && !hardcodedValues.some(v => /^[0-9]+\/[0-9]+$/.test(v))) {
|
|
145
260
|
ocorrencias.push(criarOcorrencia({
|
|
@@ -148,7 +263,7 @@ export const detectorTailwindBestPractices = {
|
|
|
148
263
|
mensagem: 'Valor hardcoded detectado - use tokens de design do Tailwind',
|
|
149
264
|
relPath,
|
|
150
265
|
linha: numeroLinha,
|
|
151
|
-
sugestao: 'Extraia cores, espaçamentos e tamanhos para
|
|
266
|
+
sugestao: 'Extraia cores, espaçamentos e tamanhos para @theme no CSS (v4)'
|
|
152
267
|
}));
|
|
153
268
|
}
|
|
154
269
|
}
|
|
@@ -166,7 +281,7 @@ export const detectorTailwindBestPractices = {
|
|
|
166
281
|
mensagem: `Valor arbitrário detectado: ${val}`,
|
|
167
282
|
relPath,
|
|
168
283
|
linha: numeroLinha,
|
|
169
|
-
sugestao: 'Considere adicionar ao
|
|
284
|
+
sugestao: 'Considere adicionar ao @theme no CSS (v4)'
|
|
170
285
|
}));
|
|
171
286
|
}
|
|
172
287
|
}
|
|
@@ -204,7 +319,7 @@ export const detectorTailwindBestPractices = {
|
|
|
204
319
|
mensagem: 'Uso excessivo de valores arbitrários - pode indicar falta de tokens de design',
|
|
205
320
|
relPath,
|
|
206
321
|
linha: 1,
|
|
207
|
-
sugestao: 'Defina tokens personalizados
|
|
322
|
+
sugestao: 'Defina tokens personalizados via @theme no CSS ao invés de valores arbitrários'
|
|
208
323
|
}));
|
|
209
324
|
}
|
|
210
325
|
return ocorrencias;
|
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
import { splitLines } from '../../../shared/helpers/index.js';
|
|
3
|
+
const V3_DEPRECATED_MAP = {
|
|
4
|
+
'shadow-sm': 'shadow-xs',
|
|
5
|
+
'drop-shadow-sm': 'drop-shadow-xs',
|
|
6
|
+
'blur-sm': 'blur-xs',
|
|
7
|
+
'rounded-sm': 'rounded-xs',
|
|
8
|
+
'outline-none': 'outline-hidden',
|
|
9
|
+
'flex-shrink': 'shrink',
|
|
10
|
+
'flex-grow': 'grow',
|
|
11
|
+
'overflow-ellipsis': 'text-ellipsis',
|
|
12
|
+
'decoration-slice': 'box-decoration-slice',
|
|
13
|
+
'decoration-clone': 'box-decoration-clone',
|
|
14
|
+
};
|
|
3
15
|
export function pontuarTailwind(src, _relPath) {
|
|
4
16
|
let score = 0;
|
|
5
17
|
const maxScore = 100;
|
|
6
18
|
const issues = [];
|
|
7
19
|
const strengths = [];
|
|
8
|
-
const _linhas = splitLines(src);
|
|
9
20
|
const srcCompleto = src;
|
|
10
21
|
const classMatches = srcCompleto.match(/\bclass(Name)?\s*=\s*["']([^"']*)["']/g) ?? [];
|
|
11
22
|
const allClasses = classMatches.map(metrica => {
|
|
12
23
|
const match = metrica.match(/["']([^"']*)["']/);
|
|
13
24
|
return match ? match[1].split(/\s+/).filter(Boolean) : [];
|
|
14
25
|
}).flat();
|
|
26
|
+
const v3Deprecated = allClasses.filter(c => V3_DEPRECATED_MAP[c] !== undefined);
|
|
27
|
+
if (v3Deprecated.length === 0) {
|
|
28
|
+
score += 5;
|
|
29
|
+
strengths.push('Sem classes obsoletas do v3');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
issues.push(`${v3Deprecated.length} classe(s) obsoleta(s) do v3 detectadas: ${v3Deprecated.map(c => `${c}→${V3_DEPRECATED_MAP[c]}`).join(', ')}`);
|
|
33
|
+
}
|
|
15
34
|
const duplicates = allClasses.filter((elem, indice) => allClasses.indexOf(elem) !== indice);
|
|
16
35
|
if (duplicates.length === 0) {
|
|
17
36
|
score += 10;
|
|
@@ -55,7 +74,7 @@ export function pontuarTailwind(src, _relPath) {
|
|
|
55
74
|
}
|
|
56
75
|
else {
|
|
57
76
|
score += 2;
|
|
58
|
-
issues.push(`${arbitraryValues.length} valores arbitrários - considere
|
|
77
|
+
issues.push(`${arbitraryValues.length} valores arbitrários - considere @theme no CSS`);
|
|
59
78
|
}
|
|
60
79
|
const importantCount = (srcCompleto.match(/class(Name)?=.*!/g) ?? []).length;
|
|
61
80
|
if (importantCount === 0) {
|
|
@@ -123,15 +142,48 @@ export function pontuarTailwind(src, _relPath) {
|
|
|
123
142
|
else {
|
|
124
143
|
issues.push(`Média de ${avgClasses.toFixed(1)} classes por elemento - considere extrair componentes`);
|
|
125
144
|
}
|
|
126
|
-
const
|
|
127
|
-
|
|
145
|
+
const hasThemeDirective = /@theme\b/.test(srcCompleto);
|
|
146
|
+
const hasConfigRef = /\btailwind\.config|\b@config\b/.test(srcCompleto);
|
|
147
|
+
if (hasThemeDirective) {
|
|
128
148
|
score += 5;
|
|
129
|
-
strengths.push('Uso de @
|
|
149
|
+
strengths.push('Uso de @theme para design tokens (v4)');
|
|
130
150
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
151
|
+
else if (hasConfigRef) {
|
|
152
|
+
score += 2;
|
|
153
|
+
issues.push('Use @theme no CSS ao invés de tailwind.config.js (v4)');
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
score += 3;
|
|
157
|
+
}
|
|
158
|
+
const hasImportTailwindcss = /@import\s+["']tailwindcss["']/.test(srcCompleto);
|
|
159
|
+
const hasTailwindDirective = /@tailwind\s+(base|components|utilities)/.test(srcCompleto);
|
|
160
|
+
if (hasImportTailwindcss) {
|
|
161
|
+
score += 3;
|
|
162
|
+
strengths.push('Importa Tailwind via @import "tailwindcss" (v4)');
|
|
163
|
+
}
|
|
164
|
+
else if (hasTailwindDirective) {
|
|
165
|
+
issues.push('Use @import "tailwindcss" ao invés de @tailwind (v4)');
|
|
166
|
+
}
|
|
167
|
+
const hasUtilityDirective = /@utility\b/.test(srcCompleto);
|
|
168
|
+
const hasLayerUtilities = /@layer\s+utilities/.test(srcCompleto);
|
|
169
|
+
if (hasUtilityDirective) {
|
|
170
|
+
score += 4;
|
|
171
|
+
strengths.push('Uso de @utility para custom utilities (v4)');
|
|
172
|
+
}
|
|
173
|
+
else if (hasLayerUtilities) {
|
|
174
|
+
issues.push('Use @utility ao invés de @layer utilities (v4)');
|
|
175
|
+
}
|
|
176
|
+
const v3ImportantPrefix = (srcCompleto.match(/class(Name)?\s*=\s*["'][^"']*![\w-]/g) ?? []).length;
|
|
177
|
+
if (v3ImportantPrefix > 0) {
|
|
178
|
+
issues.push(`${v3ImportantPrefix} uso(s) de ! como prefixo (v3) - mova ! para o final (ex: flex! no lugar de !flex)`);
|
|
179
|
+
}
|
|
180
|
+
const v3VariableArbitrary = (srcCompleto.match(/\[--[^\]]+\]/g) ?? []).length;
|
|
181
|
+
if (v3VariableArbitrary > 0) {
|
|
182
|
+
issues.push(`${v3VariableArbitrary} variável(is) em colchetes - use bg-(--var) ao invés de bg-[--var] (v4)`);
|
|
183
|
+
}
|
|
184
|
+
const themeFunction = (srcCompleto.match(/\btheme\(/g) ?? []).length;
|
|
185
|
+
if (themeFunction > 0) {
|
|
186
|
+
issues.push(`${themeFunction} uso(s) de theme() - prefira CSS variables (var(--color-*)) (v4)`);
|
|
135
187
|
}
|
|
136
188
|
return {
|
|
137
189
|
score: Math.min(score, maxScore),
|
|
@@ -144,6 +196,6 @@ export function pontuarTailwind(src, _relPath) {
|
|
|
144
196
|
export const pontuadorTailwind = {
|
|
145
197
|
nome: 'pontuador-tailwind',
|
|
146
198
|
categoria: 'estilo',
|
|
147
|
-
descricao: 'Pontua qualidade de Tailwind CSS',
|
|
199
|
+
descricao: 'Pontua qualidade de Tailwind CSS v4',
|
|
148
200
|
pontuar: pontuarTailwind
|
|
149
201
|
};
|
|
@@ -147,7 +147,7 @@ function collectXmlIssues(src, relPath) {
|
|
|
147
147
|
}
|
|
148
148
|
// DOCTYPE + ENTITY (XXE)
|
|
149
149
|
for (const metrica of scan.matchAll(/<!DOCTYPE\b[\s\S]*?(?:\]\s*>|>)/gi)) {
|
|
150
|
-
const chunk = metrica[0]
|
|
150
|
+
const chunk = metrica[0];
|
|
151
151
|
const hasExternalId = /\b(SYSTEM|PUBLIC)\b/i.test(chunk);
|
|
152
152
|
const line = lineOf(metrica.index);
|
|
153
153
|
ocorrencias.push(warn(messages.XmlMensagens.doctypeDetectado, relPath, line));
|
|
@@ -156,7 +156,7 @@ function collectXmlIssues(src, relPath) {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
for (const metrica of scan.matchAll(/<!ENTITY\b[\s\S]*?>/gi)) {
|
|
159
|
-
const chunk = metrica[0]
|
|
159
|
+
const chunk = metrica[0];
|
|
160
160
|
const hasExternal = /\b(SYSTEM|PUBLIC)\b/i.test(chunk);
|
|
161
161
|
const isParamEntity = /<!ENTITY\s+%/i.test(chunk);
|
|
162
162
|
const line = lineOf(metrica.index);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './github.js';
|
|
@@ -35,9 +35,11 @@ async function registrarLoader() {
|
|
|
35
35
|
const loaderCaminho = resolvePath(distRaiz, 'node.loader.js');
|
|
36
36
|
const loaderUrl = pathToFileURL(loaderCaminho).toString();
|
|
37
37
|
// Tenta registrar o loader via API experimental da v20+
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
const moduleImport = await import('node:module');
|
|
39
|
+
const registerHooks = moduleImport.registerHooks;
|
|
40
|
+
if (typeof registerHooks === 'function') {
|
|
41
|
+
const hooks = await import(loaderUrl);
|
|
42
|
+
registerHooks(hooks);
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
catch (err) {
|
|
@@ -170,7 +172,7 @@ export async function mainCli() {
|
|
|
170
172
|
log.debug(CliBinMensagens.erroInicializarFormatadores.replace('{erro}', err instanceof Error ? err.message : String(err)));
|
|
171
173
|
}
|
|
172
174
|
// 4. Registro de Comandos
|
|
173
|
-
registrarComandos(program, ocorrencia => aplicarFlagsGlobais(ocorrencia));
|
|
175
|
+
registrarComandos(program, ocorrencia => void aplicarFlagsGlobais(ocorrencia));
|
|
174
176
|
program.addCommand(comandoPerf());
|
|
175
177
|
// 5. Flags de histórico
|
|
176
178
|
const argv = process.argv.slice(2);
|
package/dist/bin/index.js
CHANGED
|
@@ -35,9 +35,11 @@ async function registrarLoader() {
|
|
|
35
35
|
const loaderCaminho = resolvePath(distRaiz, 'node.loader.js');
|
|
36
36
|
const loaderUrl = pathToFileURL(loaderCaminho).toString();
|
|
37
37
|
// Tenta registrar o loader via API experimental da v20+
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
const moduleImport = await import('node:module');
|
|
39
|
+
const registerHooks = moduleImport.registerHooks;
|
|
40
|
+
if (typeof registerHooks === 'function') {
|
|
41
|
+
const hooks = await import(loaderUrl);
|
|
42
|
+
registerHooks(hooks);
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
catch (err) {
|
|
@@ -170,7 +172,7 @@ export async function mainCli() {
|
|
|
170
172
|
log.debug(CliBinMensagens.erroInicializarFormatadores.replace('{erro}', err instanceof Error ? err.message : String(err)));
|
|
171
173
|
}
|
|
172
174
|
// 4. Registro de Comandos
|
|
173
|
-
registrarComandos(program, ocorrencia => aplicarFlagsGlobais(ocorrencia));
|
|
175
|
+
registrarComandos(program, ocorrencia => void aplicarFlagsGlobais(ocorrencia));
|
|
174
176
|
program.addCommand(comandoPerf());
|
|
175
177
|
// 5. Flags de histórico
|
|
176
178
|
const argv = process.argv.slice(2);
|
|
@@ -56,7 +56,7 @@ export function comandoAnalistas() {
|
|
|
56
56
|
geradoEm: new Date().toISOString(),
|
|
57
57
|
total: lista.length,
|
|
58
58
|
analistas: lista,
|
|
59
|
-
configLimites: config.ANALISE_LIMITES
|
|
59
|
+
configLimites: config.ANALISE_LIMITES
|
|
60
60
|
});
|
|
61
61
|
log.sucesso(messages.CliComandoAnalistasMensagens.jsonExportado(destino));
|
|
62
62
|
return;
|
|
@@ -73,7 +73,7 @@ export function comandoAzure() {
|
|
|
73
73
|
console.log('');
|
|
74
74
|
ocorrencias.forEach((ocorrencia) => {
|
|
75
75
|
const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
|
|
76
|
-
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem
|
|
76
|
+
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
|
|
77
77
|
if (ocorrencia.sugestao) {
|
|
78
78
|
log.info(msgs.sugestao(ocorrencia.sugestao));
|
|
79
79
|
}
|
|
@@ -69,7 +69,7 @@ export function comandoCircleCI() {
|
|
|
69
69
|
console.log('');
|
|
70
70
|
ocorrencias.forEach(ocorrencia => {
|
|
71
71
|
const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
|
|
72
|
-
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem
|
|
72
|
+
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
|
|
73
73
|
if (ocorrencia.sugestao) {
|
|
74
74
|
log.info(msgs.sugestao(ocorrencia.sugestao));
|
|
75
75
|
}
|
|
@@ -28,7 +28,7 @@ export function comandoCompliance() {
|
|
|
28
28
|
}
|
|
29
29
|
const { processarDiagnostico } = await import('../diagnostic/index.js');
|
|
30
30
|
const resultado = await processarDiagnostico({ json: true });
|
|
31
|
-
const ocorrencias = resultado.resultadoFinal.ocorrencias
|
|
31
|
+
const ocorrencias = resultado.resultadoFinal.ocorrencias;
|
|
32
32
|
const relatorio = gerarRelatorioCompliance(framework, ocorrencias, {
|
|
33
33
|
nomeProjeto: process.cwd().split('/').pop() ?? 'projeto',
|
|
34
34
|
duracao: resultado.resultadoFinal.metricas.tempoTotal ?? 0,
|
|
@@ -44,10 +44,6 @@ async function mostrarSugestoesVerbose(opts, command, logNivel) {
|
|
|
44
44
|
const activeFlags = [];
|
|
45
45
|
const details = [];
|
|
46
46
|
const parentOpts = obterOptsParent(command);
|
|
47
|
-
if (json) {
|
|
48
|
-
activeFlags.push('--json');
|
|
49
|
-
details.push(messages.CliComandoDiagnosticarMensagens.detalheSaidaEstruturada);
|
|
50
|
-
}
|
|
51
47
|
if (Boolean(opts['guardianCheck'])) {
|
|
52
48
|
activeFlags.push('--guardian-check');
|
|
53
49
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheGuardian);
|
|
@@ -81,28 +77,29 @@ async function mostrarSugestoesVerbose(opts, command, logNivel) {
|
|
|
81
77
|
activeFlags.push('--auto-fix-conservative');
|
|
82
78
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheAutoFixConservative);
|
|
83
79
|
}
|
|
84
|
-
const includes = opts['include']
|
|
85
|
-
const excludes = opts['exclude']
|
|
80
|
+
const includes = opts['include'];
|
|
81
|
+
const excludes = opts['exclude'];
|
|
86
82
|
if (includes.length) {
|
|
87
83
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheIncludePatterns(includes.length, includes.join(', ')));
|
|
88
84
|
}
|
|
89
85
|
if (excludes.length) {
|
|
90
86
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheExcludePatterns(excludes.length, excludes.join(', ')));
|
|
91
87
|
}
|
|
92
|
-
const parentExport = (
|
|
93
|
-
const parentExportFull = (
|
|
88
|
+
const parentExport = (Object.prototype.hasOwnProperty.call(parentOpts, 'export') && Boolean(parentOpts['export']));
|
|
89
|
+
const parentExportFull = (Object.prototype.hasOwnProperty.call(parentOpts, 'exportFull') && Boolean(parentOpts['exportFull']));
|
|
94
90
|
const localExport = Boolean(opts['export']);
|
|
95
91
|
const localExportFull = Boolean(opts['exportFull']);
|
|
96
92
|
if (parentExport || localExport) {
|
|
97
93
|
activeFlags.push('--export');
|
|
98
|
-
const
|
|
99
|
-
|
|
94
|
+
const relDirValue = config?.['REPORTS_DIR'];
|
|
95
|
+
const relDir = typeof relDirValue === 'string' ? relDirValue : 'reports';
|
|
96
|
+
details.push(messages.CliComandoDiagnosticarMensagens.detalheExport(relDir));
|
|
100
97
|
}
|
|
101
98
|
if (parentExportFull || localExportFull) {
|
|
102
99
|
activeFlags.push('--export-full');
|
|
103
100
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheExportFull);
|
|
104
101
|
}
|
|
105
|
-
const resolvedParentLogNivel =
|
|
102
|
+
const resolvedParentLogNivel = Object.prototype.hasOwnProperty.call(parentOpts, 'logLevel') ? String(parentOpts['logLevel']) : undefined;
|
|
106
103
|
const effectiveLogNivel = logNivel || (resolvedParentLogNivel ?? 'info');
|
|
107
104
|
details.push(messages.CliComandoDiagnosticarMensagens.detalheLogLevel(effectiveLogNivel));
|
|
108
105
|
details.push(messages.CliComandoDiagnosticarMensagens.dicaPrefiraLogLevelDebug);
|
|
@@ -151,7 +148,7 @@ export function comandoDiagnosticar(aplicarFlagsGlobais) {
|
|
|
151
148
|
cmd.allowUnknownOption(true);
|
|
152
149
|
cmd.allowExcessArguments(true);
|
|
153
150
|
for (const opt of optionsDiagnosticar) {
|
|
154
|
-
if ('parser' in opt
|
|
151
|
+
if ('parser' in opt) {
|
|
155
152
|
cmd.option(opt.flags, opt.desc, opt.parser, opt.defaultValue);
|
|
156
153
|
}
|
|
157
154
|
else if ('defaultValue' in opt) {
|
|
@@ -162,7 +159,7 @@ export function comandoDiagnosticar(aplicarFlagsGlobais) {
|
|
|
162
159
|
}
|
|
163
160
|
}
|
|
164
161
|
cmd.action(async (opts, command) => {
|
|
165
|
-
|
|
162
|
+
aplicarFlagsCombinadas(command, opts, aplicarFlagsGlobais);
|
|
166
163
|
if (process.env.SUKUNA_TEST_FAST === '1') {
|
|
167
164
|
if (opts.json) {
|
|
168
165
|
console.log(JSON.stringify({
|
|
@@ -8,7 +8,7 @@ import { PROJETO_RAIZ } from '../../core/registry/index.js';
|
|
|
8
8
|
import { exportarRelatoriosFixTypes } from '../handlers/index.js';
|
|
9
9
|
import { ExitCode, expandIncludePatterns, processPatternList, sair } from '../helpers/index.js';
|
|
10
10
|
import { asTecnicas, extrairMensagemErro } from '../../types/index.js';
|
|
11
|
-
const { CliComandoFixTypesMensagens, DICAS, formatarTipoInseguro, gerarResumoCategoria,
|
|
11
|
+
const { CliComandoFixTypesMensagens, DICAS, formatarTipoInseguro, gerarResumoCategoria, log, MENSAGENS_AUTOFIX, MENSAGENS_CLI_CORRECAO_TIPOS, MENSAGENS_ERRO_FIX_TYPES: MENSAGENS_ERRO, MENSAGENS_INICIO_FIX_TYPES: MENSAGENS_INICIO, MENSAGENS_PROGRESSO_FIX_TYPES: MENSAGENS_PROGRESSO, MENSAGENS_RESUMO, MENSAGENS_SUCESSO_FIX_TYPES: MENSAGENS_SUCESSO, TEXTOS_CATEGORIZACAO_CORRECAO_TIPOS, } = getMessages();
|
|
12
12
|
function mostrarErroDev(err) {
|
|
13
13
|
if (!config.DEV_MODE) {
|
|
14
14
|
return;
|
|
@@ -24,8 +24,8 @@ async function carregarInquisicao() {
|
|
|
24
24
|
const modInq = await import('../../core/execution/index.js');
|
|
25
25
|
const modReg = await import('../../analysts/registry/index.js');
|
|
26
26
|
registroAnalistasCache = modReg.registroAnalistas;
|
|
27
|
-
const analistaTiposInseguros = registroAnalistasCache
|
|
28
|
-
return typeof arquivo === 'object' && arquivo
|
|
27
|
+
const analistaTiposInseguros = registroAnalistasCache?.find((arquivo) => {
|
|
28
|
+
return typeof arquivo === 'object' && arquivo.nome === 'detector-tipos-inseguros';
|
|
29
29
|
});
|
|
30
30
|
return {
|
|
31
31
|
iniciarInquisicao: modInq.iniciarInquisicao,
|
|
@@ -210,12 +210,12 @@ async function aplicarCorrecoesAutomaticas(ocorrenciasCategorizadas, verbose) {
|
|
|
210
210
|
const porArquivo = {};
|
|
211
211
|
for (const item of ocorrenciasCategorizadas) {
|
|
212
212
|
const arquivo = item.ocorrencia.relPath || 'desconhecido';
|
|
213
|
-
if (!porArquivo
|
|
213
|
+
if (!(arquivo in porArquivo)) {
|
|
214
214
|
porArquivo[arquivo] = [];
|
|
215
215
|
}
|
|
216
216
|
porArquivo[arquivo].push(item);
|
|
217
217
|
}
|
|
218
|
-
const resultado =
|
|
218
|
+
const resultado = aplicarCorrecoesEmLote(porArquivo, {
|
|
219
219
|
dryRun: false,
|
|
220
220
|
minConfianca: 85,
|
|
221
221
|
verbose,
|
|
@@ -273,17 +273,6 @@ function mostrarExemplosDryRun(tiposInseguros, verbose, minConfidence) {
|
|
|
273
273
|
log.info(DICAS.usarInterativo);
|
|
274
274
|
log.info(DICAS.ajustarConfianca(minConfidence));
|
|
275
275
|
}
|
|
276
|
-
function mostrarMensagemDryRun() {
|
|
277
|
-
console.log();
|
|
278
|
-
log.aviso(MENSAGENS_CLI_CORRECAO_TIPOS.dryRunAviso(ICONES.inicio));
|
|
279
|
-
log.info(MENSAGENS_CLI_CORRECAO_TIPOS.linhaEmBranco);
|
|
280
|
-
log.info(TEMPLATE_RESUMO_FINAL.titulo);
|
|
281
|
-
for (const passo of TEMPLATE_RESUMO_FINAL.passos) {
|
|
282
|
-
log.info(MENSAGENS_CLI_CORRECAO_TIPOS.templatePasso(passo));
|
|
283
|
-
}
|
|
284
|
-
log.info(MENSAGENS_CLI_CORRECAO_TIPOS.linhaEmBranco);
|
|
285
|
-
log.info(MENSAGENS_AUTOFIX.dicas.removerDryRun);
|
|
286
|
-
}
|
|
287
276
|
export function criarComandoFixTypes() {
|
|
288
277
|
const cmd = new Command('fix-types');
|
|
289
278
|
cmd.description(CliComandoFixTypesMensagens.descricao).option('--dry-run', 'Mostra o que seria corrigido sem aplicar mudanças', false).option('--target <path>', 'Diretório ou arquivo específico para analisar', 'src').option('--confidence <number>', 'Nível mínimo de confiança para aplicar correções (0-100)', '85').option('--verbose', 'Mostra detalhes de cada correção', false).option('--interactive', 'Modo interativo: confirma cada correção', false).option('--export', 'Exporta relatórios JSON e Markdown para pasta relatorios/', false).option('--include <padrao>', 'Glob pattern a INCLUIR (pode repetir a flag ou usar vírgulas / espaços para múltiplos)', (val, prev) => {
|
|
@@ -342,7 +331,7 @@ async function executarFixTypes(options) {
|
|
|
342
331
|
sair(ExitCode.Failure);
|
|
343
332
|
return;
|
|
344
333
|
}
|
|
345
|
-
const ocorrencias = resultado.ocorrencias
|
|
334
|
+
const ocorrencias = resultado.ocorrencias;
|
|
346
335
|
const tiposInseguros = ocorrencias.filter((ocorrencia) => ocorrencia.tipo && ['tipo-inseguro-any', 'tipo-inseguro-any-assertion', 'tipo-inseguro-any-cast', 'tipo-inseguro-unknown'].includes(ocorrencia.tipo));
|
|
347
336
|
if (tiposInseguros.length === 0) {
|
|
348
337
|
log.sucesso(MENSAGENS_SUCESSO.nenhumTipoInseguro);
|
|
@@ -351,7 +340,7 @@ async function executarFixTypes(options) {
|
|
|
351
340
|
log.aviso(MENSAGENS_RESUMO.encontrados(tiposInseguros.length));
|
|
352
341
|
const porTipo = tiposInseguros.reduce((acc, ocorrencia) => {
|
|
353
342
|
const tipo = ocorrencia.tipo ?? 'desconhecido';
|
|
354
|
-
if (!acc
|
|
343
|
+
if (!(tipo in acc)) {
|
|
355
344
|
acc[tipo] = [];
|
|
356
345
|
}
|
|
357
346
|
acc[tipo].push(ocorrencia);
|
|
@@ -367,15 +356,9 @@ async function executarFixTypes(options) {
|
|
|
367
356
|
return;
|
|
368
357
|
}
|
|
369
358
|
log.fase(MENSAGENS_CLI_CORRECAO_TIPOS.aplicandoCorrecoesAuto);
|
|
370
|
-
const { fixAnyToProperTipo, fixUnknownToSpecificTipo } = await import('../../analysts/corrections/quick-fixes/index.js');
|
|
371
|
-
if (!fixAnyToProperTipo || !fixUnknownToSpecificTipo) {
|
|
372
|
-
log.erro(MENSAGENS_ERRO.modulosNaoEncontrados);
|
|
373
|
-
sair(ExitCode.Failure);
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
359
|
const porArquivo = tiposInseguros.reduce((acc, ocorrencia) => {
|
|
377
360
|
const arquivo = ocorrencia.relPath || 'desconhecido';
|
|
378
|
-
if (!acc
|
|
361
|
+
if (!(arquivo in acc)) {
|
|
379
362
|
acc[arquivo] = [];
|
|
380
363
|
}
|
|
381
364
|
acc[arquivo].push(ocorrencia);
|
|
@@ -395,9 +378,6 @@ async function executarFixTypes(options) {
|
|
|
395
378
|
if (casosAltaPrioridade.length > 0) {
|
|
396
379
|
await aplicarCorrecoesAutomaticas(ocorrenciasCategorizadas, verbose);
|
|
397
380
|
}
|
|
398
|
-
else if (isDryRun) {
|
|
399
|
-
mostrarMensagemDryRun();
|
|
400
|
-
}
|
|
401
381
|
else {
|
|
402
382
|
console.log();
|
|
403
383
|
log.info(MENSAGENS_SUCESSO.nenhumAltaConfianca);
|
|
@@ -423,10 +403,7 @@ async function executarFixTypes(options) {
|
|
|
423
403
|
verbose
|
|
424
404
|
});
|
|
425
405
|
}
|
|
426
|
-
|
|
427
|
-
if (temAny && !isDryRun) {
|
|
428
|
-
sair(ExitCode.Failure);
|
|
429
|
-
}
|
|
406
|
+
sair(ExitCode.Failure);
|
|
430
407
|
}
|
|
431
408
|
async function salvarAnaliseDetalhada(ocorrenciasCategorizadas, stats, mediaConfianca, verbose) {
|
|
432
409
|
if (!verbose) {
|
|
@@ -48,11 +48,11 @@ export function comandoFormatters() {
|
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
const mod = await import(caminhoResolvido);
|
|
51
|
-
if (
|
|
51
|
+
if (typeof mod.default.gerar !== 'function') {
|
|
52
52
|
log.erro(FormattersMensagens.moduloInvalido(caminho));
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
const formatter = { nome, ...mod.default };
|
|
55
|
+
const formatter = { nome, ...mod.default, descricao: mod.default.descricao ?? '' };
|
|
56
56
|
registrarFormatter(formatter);
|
|
57
57
|
log.sucesso(FormattersMensagens.formatadorRegistrado(nome));
|
|
58
58
|
}
|
|
@@ -69,7 +69,7 @@ export function comandoGitlabCI() {
|
|
|
69
69
|
console.log('');
|
|
70
70
|
ocorrencias.forEach(ocorrencia => {
|
|
71
71
|
const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
|
|
72
|
-
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem
|
|
72
|
+
log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
|
|
73
73
|
if (ocorrencia.sugestao) {
|
|
74
74
|
log.info(msgs.sugestao(ocorrencia.sugestao));
|
|
75
75
|
}
|
|
@@ -167,7 +167,7 @@ export function comandoGuardian(aplicarFlagsGlobais) {
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
catch (err) {
|
|
170
|
-
logGuardian.erroGuardian(err.message
|
|
170
|
+
logGuardian.erroGuardian(err.message);
|
|
171
171
|
mostrarErroDev(err);
|
|
172
172
|
if (opts.json) {
|
|
173
173
|
console.log(JSON.stringify({ status: 'erro', mensagem: extrairMensagemErro(err) }));
|