@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
|
@@ -16,9 +16,6 @@ export const detectorCircleCIEstrutura = {
|
|
|
16
16
|
try {
|
|
17
17
|
const doc = parseDocument(src);
|
|
18
18
|
const config = doc.toJS();
|
|
19
|
-
if (!config) {
|
|
20
|
-
return ocorrencias;
|
|
21
|
-
}
|
|
22
19
|
const jobs = config;
|
|
23
20
|
if (jobs.jobs) {
|
|
24
21
|
for (const [jobName, job] of Object.entries(jobs.jobs)) {
|
|
@@ -91,7 +88,7 @@ export const detectorCircleCIEstrutura = {
|
|
|
91
88
|
const commands = config.commands;
|
|
92
89
|
if (commands) {
|
|
93
90
|
for (const [_cmdName, cmdDef] of Object.entries(commands)) {
|
|
94
|
-
if (
|
|
91
|
+
if (!('parameters' in cmdDef)) {
|
|
95
92
|
ocorrencias.push(criarOcorrencia({
|
|
96
93
|
tipo: 'circleci-command-no-parameters',
|
|
97
94
|
nivel: 'info',
|
|
@@ -130,23 +127,7 @@ export const detectorCircleCIEstrutura = {
|
|
|
130
127
|
}
|
|
131
128
|
// Orphaned job detection
|
|
132
129
|
if (jobs.jobs && workflows) {
|
|
133
|
-
const
|
|
134
|
-
const usedJobs = new Set();
|
|
135
|
-
for (const wf of wfValues) {
|
|
136
|
-
if (wf && typeof wf === 'object') {
|
|
137
|
-
const wfJobs = wf.jobs;
|
|
138
|
-
if (Array.isArray(wfJobs)) {
|
|
139
|
-
for (const wfJob of wfJobs) {
|
|
140
|
-
if (typeof wfJob === 'string') {
|
|
141
|
-
usedJobs.add(wfJob);
|
|
142
|
-
}
|
|
143
|
-
else if (wfJob && typeof wfJob === 'object') {
|
|
144
|
-
Object.keys(wfJob).forEach(k => usedJobs.add(k));
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
130
|
+
const usedJobs = collectUsedJobsFromWorkflows(Object.values(workflows));
|
|
150
131
|
for (const jn of Object.keys(jobs.jobs)) {
|
|
151
132
|
if (!usedJobs.has(jn)) {
|
|
152
133
|
ocorrencias.push(criarOcorrencia({
|
|
@@ -162,7 +143,7 @@ export const detectorCircleCIEstrutura = {
|
|
|
162
143
|
// Resource class pricing consideration
|
|
163
144
|
if (jobs.jobs) {
|
|
164
145
|
for (const [, job] of Object.entries(jobs.jobs)) {
|
|
165
|
-
if (
|
|
146
|
+
if (!('resource_class' in job) && job.steps && job.steps.length > 5) {
|
|
166
147
|
ocorrencias.push(criarOcorrencia({
|
|
167
148
|
tipo: 'circleci-resource-class-pricing',
|
|
168
149
|
nivel: 'info',
|
|
@@ -220,3 +201,22 @@ export const detectorCircleCIEstrutura = {
|
|
|
220
201
|
return ocorrencias;
|
|
221
202
|
}
|
|
222
203
|
};
|
|
204
|
+
function collectUsedJobsFromWorkflows(wfValues) {
|
|
205
|
+
const usedJobs = new Set();
|
|
206
|
+
for (const wf of wfValues) {
|
|
207
|
+
if (typeof wf === 'object' && wf !== null) {
|
|
208
|
+
const wfJobs = wf.jobs;
|
|
209
|
+
if (Array.isArray(wfJobs)) {
|
|
210
|
+
for (const wfJob of wfJobs) {
|
|
211
|
+
if (typeof wfJob === 'string') {
|
|
212
|
+
usedJobs.add(wfJob);
|
|
213
|
+
}
|
|
214
|
+
else if (typeof wfJob === 'object' && wfJob !== null) {
|
|
215
|
+
Object.keys(wfJob).forEach(k => usedJobs.add(k));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return usedJobs;
|
|
222
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConversorGhaToGitlab } from './engines/converter-gha-to-gitlab.js';
|
|
2
2
|
export const registroConversores = [new ConversorGhaToGitlab()];
|
|
3
3
|
export function obterConversor(de, para) {
|
|
4
|
-
return registroConversores
|
|
4
|
+
return registroConversores?.find(elem => elem.de.toLowerCase() === de.toLowerCase() && elem.para.toLowerCase() === para.toLowerCase());
|
|
5
5
|
}
|
|
@@ -10,6 +10,7 @@ export class ConversorGhaToGitlab extends ConversorBase {
|
|
|
10
10
|
de = 'github-actions';
|
|
11
11
|
para = 'gitlab-ci';
|
|
12
12
|
async converter(conteudo) {
|
|
13
|
+
await Promise.resolve();
|
|
13
14
|
const avisos = [];
|
|
14
15
|
const erros = [];
|
|
15
16
|
try {
|
|
@@ -49,21 +50,7 @@ export class ConversorGhaToGitlab extends ConversorBase {
|
|
|
49
50
|
if (job.steps && Array.isArray(job.steps)) {
|
|
50
51
|
const steps = job.steps;
|
|
51
52
|
for (const step of steps) {
|
|
52
|
-
|
|
53
|
-
// Limpar comandos de run (remover multi-line pipe se necessário)
|
|
54
|
-
const cmd = step.run.trim();
|
|
55
|
-
gitlabJob.script.push(cmd);
|
|
56
|
-
}
|
|
57
|
-
else if (step.uses) {
|
|
58
|
-
// Tratamento especial para checkout
|
|
59
|
-
if (step.uses.includes('actions/checkout')) {
|
|
60
|
-
gitlabJob.script.push('# Checkout automático pelo GitLab Runner');
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
avisos.push(`Job '${jobId}': Action '${step.uses}' detectada. Considere usar um componente equivalente do GitLab ou um script customizado.`);
|
|
64
|
-
gitlabJob.script.push(`# TODO: Implementar lógica da action: ${step.uses}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
53
|
+
processWorkflowStep(step, jobId, gitlabJob, avisos);
|
|
67
54
|
}
|
|
68
55
|
}
|
|
69
56
|
// Mapear dependências (needs)
|
|
@@ -85,3 +72,18 @@ export class ConversorGhaToGitlab extends ConversorBase {
|
|
|
85
72
|
}
|
|
86
73
|
}
|
|
87
74
|
}
|
|
75
|
+
function processWorkflowStep(step, jobId, gitlabJob, avisos) {
|
|
76
|
+
if (step.run) {
|
|
77
|
+
const cmd = step.run.trim();
|
|
78
|
+
gitlabJob.script.push(cmd);
|
|
79
|
+
}
|
|
80
|
+
else if (step.uses) {
|
|
81
|
+
if (step.uses.includes('actions/checkout')) {
|
|
82
|
+
gitlabJob.script.push('# Checkout automático pelo GitLab Runner');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
avisos.push(`Job '${jobId}': Action '${step.uses}' detectada. Considere usar um componente equivalente do GitLab ou um script customizado.`);
|
|
86
|
+
gitlabJob.script.push(`# TODO: Implementar lógica da action: ${step.uses}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -10,5 +10,5 @@ export const registroConversores = [new ConversorGhaToGitlab()];
|
|
|
10
10
|
* Busca um conversor compatível com as plataformas de origem e destino.
|
|
11
11
|
*/
|
|
12
12
|
export function obterConversor(de, para) {
|
|
13
|
-
return registroConversores
|
|
13
|
+
return registroConversores?.find(elem => elem.de.toLowerCase() === de.toLowerCase() && elem.para.toLowerCase() === para.toLowerCase());
|
|
14
14
|
}
|
|
@@ -24,39 +24,36 @@ export const analistaQuickFixes = {
|
|
|
24
24
|
const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);
|
|
25
25
|
for (const fixResultado of uniqueFixes) {
|
|
26
26
|
for (const match of fixResultado.matches) {
|
|
27
|
-
|
|
28
|
-
const beforeMatch = src.substring(0, match.index ?? 0);
|
|
29
|
-
const linha = beforeMatch.split('\n').length;
|
|
30
|
-
// Gerar preview da correção
|
|
31
|
-
const previewCorrecao = fixResultado.fix(match, src);
|
|
32
|
-
const originalLine = src.split('\n')[linha - 1] || '';
|
|
33
|
-
const fixedLine = previewCorrecao.split('\n')[linha - 1] || '';
|
|
34
|
-
// Criar sugestão com preview mais detalhado
|
|
35
|
-
const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\n');
|
|
36
|
-
// Mapear categoria para nível
|
|
37
|
-
const nivel = mapearCategoriaNivel(fixResultado.category);
|
|
38
|
-
// Criar ocorrência base
|
|
39
|
-
const ocorrencia = criarOcorrencia({
|
|
40
|
-
tipo: 'auto-fix-disponivel',
|
|
41
|
-
nivel,
|
|
42
|
-
mensagem: fixResultado.title,
|
|
43
|
-
relPath,
|
|
44
|
-
linha
|
|
45
|
-
});
|
|
46
|
-
// Adicionar campos extras como propriedades do objeto genérico
|
|
47
|
-
const ocorrenciaGenerica = ocorrencia; // OcorrenciaGenerica allows extra properties
|
|
48
|
-
ocorrenciaGenerica.sugestao = sugestao;
|
|
49
|
-
ocorrenciaGenerica.quickFixId = fixResultado.id;
|
|
50
|
-
ocorrenciaGenerica.confidence = fixResultado.confidence;
|
|
51
|
-
ocorrenciaGenerica.category = fixResultado.category;
|
|
52
|
-
ocorrenciaGenerica.matchIndex = match.index;
|
|
53
|
-
ocorrenciaGenerica.matchLength = match[0].length;
|
|
54
|
-
ocorrencias.push(ocorrencia);
|
|
27
|
+
processQuickFixMatch(match, fixResultado, src, relPath, ocorrencias);
|
|
55
28
|
}
|
|
56
29
|
}
|
|
57
30
|
return ocorrencias;
|
|
58
31
|
}
|
|
59
32
|
};
|
|
33
|
+
function processQuickFixMatch(match, fixResultado, src, relPath, ocorrencias) {
|
|
34
|
+
const beforeMatch = src.substring(0, match.index ?? 0);
|
|
35
|
+
const linha = beforeMatch.split('\n').length;
|
|
36
|
+
const previewCorrecao = fixResultado.fix(match, src);
|
|
37
|
+
const originalLine = src.split('\n')[linha - 1] || '';
|
|
38
|
+
const fixedLine = previewCorrecao.split('\n')[linha - 1] || '';
|
|
39
|
+
const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\n');
|
|
40
|
+
const nivel = mapearCategoriaNivel(fixResultado.category);
|
|
41
|
+
const ocorrencia = criarOcorrencia({
|
|
42
|
+
tipo: 'auto-fix-disponivel',
|
|
43
|
+
nivel,
|
|
44
|
+
mensagem: fixResultado.title,
|
|
45
|
+
relPath,
|
|
46
|
+
linha
|
|
47
|
+
});
|
|
48
|
+
const ocorrenciaGenerica = ocorrencia;
|
|
49
|
+
ocorrenciaGenerica.sugestao = sugestao;
|
|
50
|
+
ocorrenciaGenerica.quickFixId = fixResultado.id;
|
|
51
|
+
ocorrenciaGenerica.confidence = fixResultado.confidence;
|
|
52
|
+
ocorrenciaGenerica.category = fixResultado.category;
|
|
53
|
+
ocorrenciaGenerica.matchIndex = match.index;
|
|
54
|
+
ocorrenciaGenerica.matchLength = match[0].length;
|
|
55
|
+
ocorrencias.push(ocorrencia);
|
|
56
|
+
}
|
|
60
57
|
function mapearCategoriaNivel(category) {
|
|
61
58
|
switch (category) {
|
|
62
59
|
case 'security':
|
|
@@ -42,32 +42,35 @@ export const analistaQuickFixes = {
|
|
|
42
42
|
const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);
|
|
43
43
|
for (const fixResultado of uniqueFixes) {
|
|
44
44
|
for (const match of fixResultado.matches) {
|
|
45
|
-
|
|
46
|
-
const previewCorrecao = fixResultado.fix(match, src);
|
|
47
|
-
const originalLine = src.split('\n')[linha - 1] || '';
|
|
48
|
-
const fixedLine = previewCorrecao.split('\n')[linha - 1] || '';
|
|
49
|
-
const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\n');
|
|
50
|
-
const nivel = mapearCategoriaNivel(fixResultado.category);
|
|
51
|
-
const ocorrencia = criarOcorrencia({
|
|
52
|
-
tipo: 'auto-fix-disponivel',
|
|
53
|
-
nivel,
|
|
54
|
-
mensagem: fixResultado.title,
|
|
55
|
-
relPath,
|
|
56
|
-
linha
|
|
57
|
-
});
|
|
58
|
-
const ocorrenciaGenerica = ocorrencia;
|
|
59
|
-
ocorrenciaGenerica.sugestao = sugestao;
|
|
60
|
-
ocorrenciaGenerica.quickFixId = fixResultado.id;
|
|
61
|
-
ocorrenciaGenerica.confidence = fixResultado.confidence;
|
|
62
|
-
ocorrenciaGenerica.category = fixResultado.category;
|
|
63
|
-
ocorrenciaGenerica.matchIndex = match.index;
|
|
64
|
-
ocorrenciaGenerica.matchLength = match[0].length;
|
|
65
|
-
ocorrencias.push(ocorrencia);
|
|
45
|
+
processQuickFixMatchScoring(match, fixResultado, src, relPath, ocorrencias);
|
|
66
46
|
}
|
|
67
47
|
}
|
|
68
48
|
return ocorrencias;
|
|
69
49
|
}
|
|
70
50
|
};
|
|
51
|
+
function processQuickFixMatchScoring(match, fixResultado, src, relPath, ocorrencias) {
|
|
52
|
+
const linha = calcularLinha(src, match.index, match);
|
|
53
|
+
const previewCorrecao = fixResultado.fix(match, src);
|
|
54
|
+
const originalLine = src.split('\n')[linha - 1] || '';
|
|
55
|
+
const fixedLine = previewCorrecao.split('\n')[linha - 1] || '';
|
|
56
|
+
const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\n');
|
|
57
|
+
const nivel = mapearCategoriaNivel(fixResultado.category);
|
|
58
|
+
const ocorrencia = criarOcorrencia({
|
|
59
|
+
tipo: 'auto-fix-disponivel',
|
|
60
|
+
nivel,
|
|
61
|
+
mensagem: fixResultado.title,
|
|
62
|
+
relPath,
|
|
63
|
+
linha
|
|
64
|
+
});
|
|
65
|
+
const ocorrenciaGenerica = ocorrencia;
|
|
66
|
+
ocorrenciaGenerica.sugestao = sugestao;
|
|
67
|
+
ocorrenciaGenerica.quickFixId = fixResultado.id;
|
|
68
|
+
ocorrenciaGenerica.confidence = fixResultado.confidence;
|
|
69
|
+
ocorrenciaGenerica.category = fixResultado.category;
|
|
70
|
+
ocorrenciaGenerica.matchIndex = match.index;
|
|
71
|
+
ocorrenciaGenerica.matchLength = match[0].length;
|
|
72
|
+
ocorrencias.push(ocorrencia);
|
|
73
|
+
}
|
|
71
74
|
// ─── analistaPontuacao ────────────────────────────────────────
|
|
72
75
|
export const analistaPontuacao = {
|
|
73
76
|
nome: 'pontuacao-fix',
|
|
@@ -83,7 +83,7 @@ export function aplicarCorrecaoArquivo(arquivo, ocorrencias, config) {
|
|
|
83
83
|
/**
|
|
84
84
|
* Aplica correções em múltiplos arquivos
|
|
85
85
|
*/
|
|
86
|
-
export
|
|
86
|
+
export function aplicarCorrecoesEmLote(porArquivo, config) {
|
|
87
87
|
const resultados = [];
|
|
88
88
|
let sucesso = 0;
|
|
89
89
|
let falhas = 0;
|
|
@@ -12,9 +12,10 @@ import { mapaReversao } from './map-reversion.js';
|
|
|
12
12
|
const { log, logAuto, CorretorEstruturaExtraMensagens } = getMessages();
|
|
13
13
|
export async function corrigirEstrutura(mapa, fileEntries, baseDir = process.cwd()) {
|
|
14
14
|
// Captura dinâmica das configs (evita congelar valores em tempo de import)
|
|
15
|
-
const CONCORRENCIA =
|
|
15
|
+
const CONCORRENCIA = config.STRUCTURE_CONCURRENCY;
|
|
16
16
|
const AUTO_CORRECAO = config.STRUCTURE_AUTO_FIX;
|
|
17
|
-
const
|
|
17
|
+
const rawPlugins = config.STRUCTURE_PLUGINS ?? [];
|
|
18
|
+
const PLUGINS = Array.isArray(rawPlugins) ? rawPlugins.filter((p) => typeof p === 'string') : [];
|
|
18
19
|
const ESTRUTURA_CAMADAS = config.ESTRUTURA_CAMADAS;
|
|
19
20
|
const limit = pLimit(CONCORRENCIA);
|
|
20
21
|
await Promise.all(mapa.map(entry => limit(async () => {
|
|
@@ -30,55 +31,21 @@ export async function corrigirEstrutura(mapa, fileEntries, baseDir = process.cwd
|
|
|
30
31
|
log.info(CorretorEstruturaExtraMensagens.simular.replace('{arquivo}', arquivo).replace('{destino}', path.relative(baseDir, destino)));
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
await fs.mkdir(path.dirname(destino), {
|
|
35
|
-
recursive: true
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch (err) {
|
|
39
|
-
const msg = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);
|
|
40
|
-
logAuto.corretorErroCriarDiretorio(destino, msg);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
// Usa flag 'wx' para escrita exclusiva - falha se o arquivo já existir,
|
|
45
|
-
// eliminando a condição de corrida TOCTOU entre stat e write
|
|
46
|
-
const conteudo = await fs.readFile(origem, 'utf-8');
|
|
47
|
-
const { novoConteudo } = reescreverImports(conteudo, path.posix.normalize(arquivo.replace(/\\/g, '/')), path.posix.normalize(path.relative(baseDir, destino).replace(/\\/g, '/')));
|
|
48
|
-
// Registra o move no mapa de reversão
|
|
49
|
-
await mapaReversao.registrarMove(arquivo, path.relative(baseDir, destino), entry.motivo ?? 'Reorganização estrutural', conteudo, novoConteudo, true);
|
|
50
|
-
try {
|
|
51
|
-
await fs.writeFile(destino, novoConteudo, { encoding: 'utf-8', flag: 'wx' });
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
const code = err.code;
|
|
55
|
-
if (code === 'EEXIST') {
|
|
56
|
-
logAuto.corretorDestinoExiste(arquivo, path.relative(baseDir, destino));
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
await fs.unlink(origem);
|
|
62
|
-
log.sucesso(CorretorEstruturaExtraMensagens.movido.replace('{arquivo}', arquivo).replace('{destino}', path.relative(baseDir, destino)));
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
const msg = err && typeof err === 'object' && 'message' in err ? String((err).message) : String(err);
|
|
66
|
-
logAuto.corretorErroMover(arquivo, msg);
|
|
67
|
-
}
|
|
34
|
+
await moverArquivoComReversao(entry, origem, destino, baseDir, arquivo);
|
|
68
35
|
})));
|
|
69
36
|
for (const pluginRel of PLUGINS) {
|
|
70
37
|
try {
|
|
71
|
-
const resolvido = resolverPluginSeguro(baseDir,
|
|
38
|
+
const resolvido = resolverPluginSeguro(baseDir, pluginRel);
|
|
72
39
|
if (resolvido.erro) {
|
|
73
|
-
logAuto.pluginIgnorado(
|
|
40
|
+
logAuto.pluginIgnorado(pluginRel, resolvido.erro);
|
|
74
41
|
continue;
|
|
75
42
|
}
|
|
76
43
|
const caminhoPlugin = resolvido.caminho;
|
|
77
44
|
if (!caminhoPlugin) {
|
|
78
|
-
logAuto.caminhoNaoResolvido(
|
|
45
|
+
logAuto.caminhoNaoResolvido(pluginRel);
|
|
79
46
|
continue;
|
|
80
47
|
}
|
|
81
|
-
const pluginModule = await importarModuloSeguro(baseDir,
|
|
48
|
+
const pluginModule = await importarModuloSeguro(baseDir, pluginRel);
|
|
82
49
|
let pluginFn;
|
|
83
50
|
if (pluginModule && typeof pluginModule === 'object' && 'default' in pluginModule && typeof pluginModule.default === 'function') {
|
|
84
51
|
pluginFn = pluginModule.default;
|
|
@@ -103,7 +70,41 @@ export async function corrigirEstrutura(mapa, fileEntries, baseDir = process.cwd
|
|
|
103
70
|
else if (typeof err === 'string') {
|
|
104
71
|
msg = err;
|
|
105
72
|
}
|
|
106
|
-
logAuto.pluginFalhou(
|
|
73
|
+
logAuto.pluginFalhou(pluginRel, msg);
|
|
107
74
|
}
|
|
108
75
|
}
|
|
109
76
|
}
|
|
77
|
+
async function moverArquivoComReversao(entry, origem, destino, baseDir, arquivo) {
|
|
78
|
+
try {
|
|
79
|
+
await fs.mkdir(path.dirname(destino), {
|
|
80
|
+
recursive: true
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const msg = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);
|
|
85
|
+
logAuto.corretorErroCriarDiretorio(destino, msg);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const conteudo = await fs.readFile(origem, 'utf-8');
|
|
90
|
+
const { novoConteudo } = reescreverImports(conteudo, path.posix.normalize(arquivo.replace(/\\/g, '/')), path.posix.normalize(path.relative(baseDir, destino).replace(/\\/g, '/')));
|
|
91
|
+
await mapaReversao.registrarMove(arquivo, path.relative(baseDir, destino), entry.motivo ?? 'Reorganização estrutural', conteudo, novoConteudo, true);
|
|
92
|
+
try {
|
|
93
|
+
await fs.writeFile(destino, novoConteudo, { encoding: 'utf-8', flag: 'wx' });
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
const code = err.code;
|
|
97
|
+
if (code === 'EEXIST') {
|
|
98
|
+
logAuto.corretorDestinoExiste(arquivo, path.relative(baseDir, destino));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
await fs.unlink(origem);
|
|
104
|
+
log.sucesso(CorretorEstruturaExtraMensagens.movido.replace('{arquivo}', arquivo).replace('{destino}', path.relative(baseDir, destino)));
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const msg = err && typeof err === 'object' && 'message' in err ? String((err).message) : String(err);
|
|
108
|
+
logAuto.corretorErroMover(arquivo, msg);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -13,6 +13,15 @@ export function aplicarFixAliasImports(fileCaminho, content) {
|
|
|
13
13
|
content: out
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
+
async function processTypeFileForAlias(fileCaminho) {
|
|
17
|
+
const src = await fs.readFile(fileCaminho, 'utf8');
|
|
18
|
+
const { changed: wasChanged, content } = aplicarFixAliasImports(fileCaminho, src);
|
|
19
|
+
if (wasChanged) {
|
|
20
|
+
await fs.writeFile(fileCaminho, content, 'utf8');
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
16
25
|
export async function scanAndApplyFix(root) {
|
|
17
26
|
let changed = 0;
|
|
18
27
|
async function walk(dir) {
|
|
@@ -26,12 +35,7 @@ export async function scanAndApplyFix(root) {
|
|
|
26
35
|
await walk(fileCaminho);
|
|
27
36
|
}
|
|
28
37
|
else if (entry.isFile() && fileCaminho.endsWith('.ts')) {
|
|
29
|
-
|
|
30
|
-
const { changed: wasChanged, content } = aplicarFixAliasImports(fileCaminho, src);
|
|
31
|
-
if (wasChanged) {
|
|
32
|
-
await fs.writeFile(fileCaminho, content, 'utf8');
|
|
33
|
-
changed++;
|
|
34
|
-
}
|
|
38
|
+
changed += await processTypeFileForAlias(fileCaminho);
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
41
|
}
|
|
@@ -48,33 +48,33 @@ export function fixFences(content) {
|
|
|
48
48
|
}
|
|
49
49
|
return out.join('\n');
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (/^(node_modules|dist|coverage|pre-public|preview-mahoraga|\.git)$/i.test(entry.name)) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
out.push(...(await listMarkdown(fullCaminho)));
|
|
66
|
-
}
|
|
67
|
-
else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
|
|
68
|
-
out.push(fullCaminho);
|
|
51
|
+
async function listMarkdownFiles(dir) {
|
|
52
|
+
const out = [];
|
|
53
|
+
try {
|
|
54
|
+
const entries = await fs.readdir(dir, {
|
|
55
|
+
withFileTypes: true
|
|
56
|
+
});
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
const fullCaminho = path.join(dir, entry.name);
|
|
59
|
+
if (entry.isDirectory()) {
|
|
60
|
+
if (/^(node_modules|dist|coverage|pre-public|preview-mahoraga|\.git)$/i.test(entry.name)) {
|
|
61
|
+
continue;
|
|
69
62
|
}
|
|
63
|
+
out.push(...(await listMarkdownFiles(fullCaminho)));
|
|
64
|
+
}
|
|
65
|
+
else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
|
|
66
|
+
out.push(fullCaminho);
|
|
70
67
|
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return out;
|
|
75
68
|
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return out;
|
|
76
73
|
}
|
|
77
|
-
|
|
74
|
+
}
|
|
75
|
+
export async function scanAndApplyFixMdFences(root) {
|
|
76
|
+
let changed = 0;
|
|
77
|
+
const files = await listMarkdownFiles(root);
|
|
78
78
|
for (const fileCaminho of files) {
|
|
79
79
|
const rel = path.relative(root, fileCaminho).replace(/\\/g, '/');
|
|
80
80
|
if (rel.startsWith('pre-public/') || rel.includes('/legado/')) {
|
|
@@ -41,7 +41,7 @@ export class GerenciadorMapaReversao {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
// Validação básica
|
|
44
|
-
if (!
|
|
44
|
+
if (!Array.isArray(this.mapa.moves)) {
|
|
45
45
|
throw new Error(messages.ExcecoesMensagens.mapaReversaoCorrompido);
|
|
46
46
|
}
|
|
47
47
|
logAuto.mapaReversaoCarregado(this.mapa.moves.length);
|
|
@@ -89,7 +89,7 @@ export class GerenciadorMapaReversao {
|
|
|
89
89
|
// quando true, evita persistir o mapa no disco imediatamente (útil para chamadas em massa/tests)
|
|
90
90
|
skipSalvar) {
|
|
91
91
|
try {
|
|
92
|
-
const id = `move_${Date.now()}_${Math.random().toString(CONSTANTES_MAPA.RADIX_36).
|
|
92
|
+
const id = `move_${Date.now()}_${Math.random().toString(CONSTANTES_MAPA.RADIX_36).slice(CONSTANTES_MAPA.ID_OFFSET, CONSTANTES_MAPA.ID_OFFSET + CONSTANTES_MAPA.ID_LENGTH)}`;
|
|
93
93
|
const move = {
|
|
94
94
|
id,
|
|
95
95
|
timestamp: new Date().toISOString(),
|
|
@@ -172,57 +172,8 @@ export class GerenciadorMapaReversao {
|
|
|
172
172
|
recursive: true
|
|
173
173
|
});
|
|
174
174
|
// Move o arquivo de volta
|
|
175
|
-
if (move
|
|
176
|
-
|
|
177
|
-
// eliminando a condição de corrida TOCTOU entre stat e write
|
|
178
|
-
try {
|
|
179
|
-
await fs.writeFile(origemCaminho, move.conteudoOriginal, {
|
|
180
|
-
encoding: 'utf-8',
|
|
181
|
-
flag: 'wx'
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
const code = err.code;
|
|
186
|
-
if (code === 'EEXIST') {
|
|
187
|
-
logAuto.mapaReversaoArquivoExisteOrigem(move.origem);
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
if (err.code && err.code !== 'ENOENT') {
|
|
191
|
-
logAuto.mapaReversaoErroReverter(err.message);
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
throw err;
|
|
195
|
-
}
|
|
196
|
-
try {
|
|
197
|
-
await fs.unlink(destinoCaminho);
|
|
198
|
-
}
|
|
199
|
-
catch (err) {
|
|
200
|
-
if (err.code === 'ENOENT') {
|
|
201
|
-
logAuto.mapaReversaoArquivoDestinoNaoEncontrado(move.destino);
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
throw err;
|
|
205
|
-
}
|
|
206
|
-
log.sucesso(MapaReversaoExtraMensagens.arquivoRevertidoConteudo.replace('{destino}', move.destino).replace('{origem}', move.origem));
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
// Usa rename atômico - se destino não existir, falha com ENOENT
|
|
210
|
-
try {
|
|
211
|
-
await fs.rename(destinoCaminho, origemCaminho);
|
|
212
|
-
}
|
|
213
|
-
catch (err) {
|
|
214
|
-
const code = err.code;
|
|
215
|
-
if (code === 'ENOENT') {
|
|
216
|
-
logAuto.mapaReversaoArquivoDestinoNaoEncontrado(move.destino);
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
if (code === 'EEXIST') {
|
|
220
|
-
logAuto.mapaReversaoArquivoExisteOrigem(move.origem);
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
throw err;
|
|
224
|
-
}
|
|
225
|
-
log.sucesso(MapaReversaoExtraMensagens.arquivoRevertido.replace('{destino}', move.destino).replace('{origem}', move.origem));
|
|
175
|
+
if (!await this.reverterComConteudo(move, origemCaminho, destinoCaminho)) {
|
|
176
|
+
return false;
|
|
226
177
|
}
|
|
227
178
|
// Remove o move do mapa
|
|
228
179
|
await this.removerMove(id);
|
|
@@ -295,6 +246,58 @@ export class GerenciadorMapaReversao {
|
|
|
295
246
|
logAuto.mapaReversaoErroSalvar(err.message);
|
|
296
247
|
}
|
|
297
248
|
}
|
|
249
|
+
async reverterComConteudo(move, origemCaminho, destinoCaminho) {
|
|
250
|
+
if (move.importsReescritos && move.conteudoOriginal) {
|
|
251
|
+
try {
|
|
252
|
+
await fs.writeFile(origemCaminho, move.conteudoOriginal, {
|
|
253
|
+
encoding: 'utf-8',
|
|
254
|
+
flag: 'wx'
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
const code = err.code;
|
|
259
|
+
if (code === 'EEXIST') {
|
|
260
|
+
logAuto.mapaReversaoArquivoExisteOrigem(move.origem);
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
if (err.code && err.code !== 'ENOENT') {
|
|
264
|
+
logAuto.mapaReversaoErroReverter(err.message);
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
throw err;
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
await fs.unlink(destinoCaminho);
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
if (err.code === 'ENOENT') {
|
|
274
|
+
logAuto.mapaReversaoArquivoDestinoNaoEncontrado(move.destino);
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
throw err;
|
|
278
|
+
}
|
|
279
|
+
log.sucesso(MapaReversaoExtraMensagens.arquivoRevertidoConteudo.replace('{destino}', move.destino).replace('{origem}', move.origem));
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
try {
|
|
283
|
+
await fs.rename(destinoCaminho, origemCaminho);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
const code = err.code;
|
|
287
|
+
if (code === 'ENOENT') {
|
|
288
|
+
logAuto.mapaReversaoArquivoDestinoNaoEncontrado(move.destino);
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
if (code === 'EEXIST') {
|
|
292
|
+
logAuto.mapaReversaoArquivoExisteOrigem(move.origem);
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
throw err;
|
|
296
|
+
}
|
|
297
|
+
log.sucesso(MapaReversaoExtraMensagens.arquivoRevertido.replace('{destino}', move.destino).replace('{origem}', move.origem));
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
298
301
|
}
|
|
299
302
|
// Instância global
|
|
300
303
|
export const mapaReversao = new GerenciadorMapaReversao();
|
|
@@ -91,21 +91,24 @@ function moverArquivosSimulado(lista, base) {
|
|
|
91
91
|
async function moverArquivos(lista, base, historico) {
|
|
92
92
|
const limitar = pLimit(CONCORRENCIA);
|
|
93
93
|
await Promise.all(lista.map(pend => limitar(async () => {
|
|
94
|
-
|
|
95
|
-
const dest = path.join(base, DIR_ABANDONADOS, pend.arquivo);
|
|
96
|
-
try {
|
|
97
|
-
const fs = await import('node:fs');
|
|
98
|
-
await ensureDir(dest);
|
|
99
|
-
await fs.promises.rename(src, dest);
|
|
100
|
-
historico.push({
|
|
101
|
-
arquivo: pend.arquivo,
|
|
102
|
-
movidoEm: new Date().toISOString(),
|
|
103
|
-
motivo: pend.motivo
|
|
104
|
-
});
|
|
105
|
-
logAuto.podaArquivoMovido(pend.arquivo);
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
log.erro(`[ERRO] Falha ao mover ${pend.arquivo}: ${typeof err === 'object' && err && 'message' in err ? err.message : String(err)}`);
|
|
109
|
-
}
|
|
94
|
+
await moverArquivoIndividual(pend, base, historico);
|
|
110
95
|
})));
|
|
111
96
|
}
|
|
97
|
+
async function moverArquivoIndividual(pend, base, historico) {
|
|
98
|
+
const src = path.join(base, pend.arquivo);
|
|
99
|
+
const dest = path.join(base, DIR_ABANDONADOS, pend.arquivo);
|
|
100
|
+
try {
|
|
101
|
+
const fs = await import('node:fs');
|
|
102
|
+
await ensureDir(dest);
|
|
103
|
+
await fs.promises.rename(src, dest);
|
|
104
|
+
historico.push({
|
|
105
|
+
arquivo: pend.arquivo,
|
|
106
|
+
movidoEm: new Date().toISOString(),
|
|
107
|
+
motivo: pend.motivo
|
|
108
|
+
});
|
|
109
|
+
logAuto.podaArquivoMovido(pend.arquivo);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
log.erro(`[ERRO] Falha ao mover ${pend.arquivo}: ${typeof err === 'object' && err && 'message' in err ? err.message : String(err)}`);
|
|
113
|
+
}
|
|
114
|
+
}
|