@oalacea/daemon 0.6.4 → 0.7.0
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 +268 -58
- package/bin/Dockerfile +158 -16
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +22 -2
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/commands/command.types.d.ts +216 -0
- package/dist/cli/commands/command.types.d.ts.map +1 -0
- package/dist/cli/commands/command.types.js +64 -0
- package/dist/cli/commands/command.types.js.map +1 -0
- package/dist/cli/commands/history.command.d.ts +91 -0
- package/dist/cli/commands/history.command.d.ts.map +1 -0
- package/dist/cli/commands/history.command.js +336 -0
- package/dist/cli/commands/history.command.js.map +1 -0
- package/dist/cli/commands/index.d.ts +14 -3
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +7 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/optimize.command.d.ts +110 -0
- package/dist/cli/commands/optimize.command.d.ts.map +1 -0
- package/dist/cli/commands/optimize.command.js +497 -0
- package/dist/cli/commands/optimize.command.js.map +1 -0
- package/dist/cli/commands/report.command.d.ts +110 -0
- package/dist/cli/commands/report.command.d.ts.map +1 -0
- package/dist/cli/commands/report.command.js +532 -0
- package/dist/cli/commands/report.command.js.map +1 -0
- package/dist/cli/commands/review.command.d.ts +110 -0
- package/dist/cli/commands/review.command.d.ts.map +1 -0
- package/dist/cli/commands/review.command.js +520 -0
- package/dist/cli/commands/review.command.js.map +1 -0
- package/dist/cli/commands/score.command.d.ts +47 -0
- package/dist/cli/commands/score.command.d.ts.map +1 -0
- package/dist/cli/commands/score.command.js +261 -0
- package/dist/cli/commands/score.command.js.map +1 -0
- package/dist/cli/utils/index.d.ts +10 -0
- package/dist/cli/utils/index.d.ts.map +1 -0
- package/dist/cli/utils/index.js +10 -0
- package/dist/cli/utils/index.js.map +1 -0
- package/dist/cli/utils/output.d.ts +192 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +411 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/cli/utils/progress.d.ts +204 -0
- package/dist/cli/utils/progress.d.ts.map +1 -0
- package/dist/cli/utils/progress.js +396 -0
- package/dist/cli/utils/progress.js.map +1 -0
- package/dist/core/types/index.d.ts +1 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/project.types.d.ts +3 -3
- package/dist/core/types/project.types.d.ts.map +1 -1
- package/dist/core/types/scoring.types.d.ts +301 -0
- package/dist/core/types/scoring.types.d.ts.map +1 -0
- package/dist/core/types/scoring.types.js +8 -0
- package/dist/core/types/scoring.types.js.map +1 -0
- package/dist/services/detection/framework-detector.d.ts.map +1 -1
- package/dist/services/detection/framework-detector.js +74 -5
- package/dist/services/detection/framework-detector.js.map +1 -1
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +14 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/optimization/detectors/bug-detector.d.ts +82 -0
- package/dist/services/optimization/detectors/bug-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/bug-detector.js +443 -0
- package/dist/services/optimization/detectors/bug-detector.js.map +1 -0
- package/dist/services/optimization/detectors/code-smell-detector.d.ts +108 -0
- package/dist/services/optimization/detectors/code-smell-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/code-smell-detector.js +569 -0
- package/dist/services/optimization/detectors/code-smell-detector.js.map +1 -0
- package/dist/services/optimization/detectors/index.d.ts +7 -0
- package/dist/services/optimization/detectors/index.d.ts.map +1 -0
- package/dist/services/optimization/detectors/index.js +7 -0
- package/dist/services/optimization/detectors/index.js.map +1 -0
- package/dist/services/optimization/detectors/perf-detector.d.ts +80 -0
- package/dist/services/optimization/detectors/perf-detector.d.ts.map +1 -0
- package/dist/services/optimization/detectors/perf-detector.js +451 -0
- package/dist/services/optimization/detectors/perf-detector.js.map +1 -0
- package/dist/services/optimization/index.d.ts +61 -0
- package/dist/services/optimization/index.d.ts.map +1 -0
- package/dist/services/optimization/index.js +69 -0
- package/dist/services/optimization/index.js.map +1 -0
- package/dist/services/optimization/optimization.service.d.ts +65 -0
- package/dist/services/optimization/optimization.service.d.ts.map +1 -0
- package/dist/services/optimization/optimization.service.js +511 -0
- package/dist/services/optimization/optimization.service.js.map +1 -0
- package/dist/services/optimization/optimization.types.d.ts +343 -0
- package/dist/services/optimization/optimization.types.d.ts.map +1 -0
- package/dist/services/optimization/optimization.types.js +8 -0
- package/dist/services/optimization/optimization.types.js.map +1 -0
- package/dist/services/optimization/optimizers/code-optimizer.d.ts +87 -0
- package/dist/services/optimization/optimizers/code-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/code-optimizer.js +436 -0
- package/dist/services/optimization/optimizers/code-optimizer.js.map +1 -0
- package/dist/services/optimization/optimizers/index.d.ts +7 -0
- package/dist/services/optimization/optimizers/index.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/index.js +7 -0
- package/dist/services/optimization/optimizers/index.js.map +1 -0
- package/dist/services/optimization/optimizers/perf-optimizer.d.ts +64 -0
- package/dist/services/optimization/optimizers/perf-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/perf-optimizer.js +330 -0
- package/dist/services/optimization/optimizers/perf-optimizer.js.map +1 -0
- package/dist/services/optimization/optimizers/refact-optimizer.d.ts +82 -0
- package/dist/services/optimization/optimizers/refact-optimizer.d.ts.map +1 -0
- package/dist/services/optimization/optimizers/refact-optimizer.js +354 -0
- package/dist/services/optimization/optimizers/refact-optimizer.js.map +1 -0
- package/dist/services/optimization/patterns/anti-patterns.d.ts +31 -0
- package/dist/services/optimization/patterns/anti-patterns.d.ts.map +1 -0
- package/dist/services/optimization/patterns/anti-patterns.js +501 -0
- package/dist/services/optimization/patterns/anti-patterns.js.map +1 -0
- package/dist/services/optimization/patterns/index.d.ts +5 -0
- package/dist/services/optimization/patterns/index.d.ts.map +1 -0
- package/dist/services/optimization/patterns/index.js +5 -0
- package/dist/services/optimization/patterns/index.js.map +1 -0
- package/dist/services/reporting/export/chart.exporter.d.ts +59 -0
- package/dist/services/reporting/export/chart.exporter.d.ts.map +1 -0
- package/dist/services/reporting/export/chart.exporter.js +350 -0
- package/dist/services/reporting/export/chart.exporter.js.map +1 -0
- package/dist/services/reporting/export/index.d.ts +9 -0
- package/dist/services/reporting/export/index.d.ts.map +1 -0
- package/dist/services/reporting/export/index.js +10 -0
- package/dist/services/reporting/export/index.js.map +1 -0
- package/dist/services/reporting/export/pdf.exporter.d.ts +133 -0
- package/dist/services/reporting/export/pdf.exporter.d.ts.map +1 -0
- package/dist/services/reporting/export/pdf.exporter.js +270 -0
- package/dist/services/reporting/export/pdf.exporter.js.map +1 -0
- package/dist/services/reporting/history.service.d.ts +93 -0
- package/dist/services/reporting/history.service.d.ts.map +1 -0
- package/dist/services/reporting/history.service.js +285 -0
- package/dist/services/reporting/history.service.js.map +1 -0
- package/dist/services/reporting/index.d.ts +15 -0
- package/dist/services/reporting/index.d.ts.map +1 -0
- package/dist/services/reporting/index.js +16 -0
- package/dist/services/reporting/index.js.map +1 -0
- package/dist/services/reporting/report.service.d.ts +102 -0
- package/dist/services/reporting/report.service.d.ts.map +1 -0
- package/dist/services/reporting/report.service.js +240 -0
- package/dist/services/reporting/report.service.js.map +1 -0
- package/dist/services/reporting/reporting.types.d.ts +329 -0
- package/dist/services/reporting/reporting.types.d.ts.map +1 -0
- package/dist/services/reporting/reporting.types.js +8 -0
- package/dist/services/reporting/reporting.types.js.map +1 -0
- package/dist/services/reporting/templates/html.template.d.ts +81 -0
- package/dist/services/reporting/templates/html.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/html.template.js +741 -0
- package/dist/services/reporting/templates/html.template.js.map +1 -0
- package/dist/services/reporting/templates/json.template.d.ts +85 -0
- package/dist/services/reporting/templates/json.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/json.template.js +308 -0
- package/dist/services/reporting/templates/json.template.js.map +1 -0
- package/dist/services/reporting/templates/markdown.template.d.ts +69 -0
- package/dist/services/reporting/templates/markdown.template.d.ts.map +1 -0
- package/dist/services/reporting/templates/markdown.template.js +311 -0
- package/dist/services/reporting/templates/markdown.template.js.map +1 -0
- package/dist/services/reporting/trend-analyzer.d.ts +73 -0
- package/dist/services/reporting/trend-analyzer.d.ts.map +1 -0
- package/dist/services/reporting/trend-analyzer.js +291 -0
- package/dist/services/reporting/trend-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/dependency-analyzer.d.ts +87 -0
- package/dist/services/review/analyzers/dependency-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/dependency-analyzer.js +458 -0
- package/dist/services/review/analyzers/dependency-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/index.d.ts +13 -0
- package/dist/services/review/analyzers/index.d.ts.map +1 -0
- package/dist/services/review/analyzers/index.js +13 -0
- package/dist/services/review/analyzers/index.js.map +1 -0
- package/dist/services/review/analyzers/nestjs-analyzer.d.ts +210 -0
- package/dist/services/review/analyzers/nestjs-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/nestjs-analyzer.js +571 -0
- package/dist/services/review/analyzers/nestjs-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/performance-analyzer.d.ts +91 -0
- package/dist/services/review/analyzers/performance-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/performance-analyzer.js +589 -0
- package/dist/services/review/analyzers/performance-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/security-analyzer.d.ts +96 -0
- package/dist/services/review/analyzers/security-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/security-analyzer.js +512 -0
- package/dist/services/review/analyzers/security-analyzer.js.map +1 -0
- package/dist/services/review/analyzers/static-analyzer.d.ts +90 -0
- package/dist/services/review/analyzers/static-analyzer.d.ts.map +1 -0
- package/dist/services/review/analyzers/static-analyzer.js +423 -0
- package/dist/services/review/analyzers/static-analyzer.js.map +1 -0
- package/dist/services/review/fixers/auto-fixer.d.ts +94 -0
- package/dist/services/review/fixers/auto-fixer.d.ts.map +1 -0
- package/dist/services/review/fixers/auto-fixer.js +404 -0
- package/dist/services/review/fixers/auto-fixer.js.map +1 -0
- package/dist/services/review/fixers/index.d.ts +11 -0
- package/dist/services/review/fixers/index.d.ts.map +1 -0
- package/dist/services/review/fixers/index.js +11 -0
- package/dist/services/review/fixers/index.js.map +1 -0
- package/dist/services/review/fixers/refactor-suggester.d.ts +100 -0
- package/dist/services/review/fixers/refactor-suggester.d.ts.map +1 -0
- package/dist/services/review/fixers/refactor-suggester.js +555 -0
- package/dist/services/review/fixers/refactor-suggester.js.map +1 -0
- package/dist/services/review/fixers/test-generator.d.ts +99 -0
- package/dist/services/review/fixers/test-generator.d.ts.map +1 -0
- package/dist/services/review/fixers/test-generator.js +458 -0
- package/dist/services/review/fixers/test-generator.js.map +1 -0
- package/dist/services/review/index.d.ts +14 -0
- package/dist/services/review/index.d.ts.map +1 -0
- package/dist/services/review/index.js +14 -0
- package/dist/services/review/index.js.map +1 -0
- package/dist/services/review/reporters/fix-reporter.d.ts +67 -0
- package/dist/services/review/reporters/fix-reporter.d.ts.map +1 -0
- package/dist/services/review/reporters/fix-reporter.js +437 -0
- package/dist/services/review/reporters/fix-reporter.js.map +1 -0
- package/dist/services/review/reporters/index.d.ts +10 -0
- package/dist/services/review/reporters/index.d.ts.map +1 -0
- package/dist/services/review/reporters/index.js +10 -0
- package/dist/services/review/reporters/index.js.map +1 -0
- package/dist/services/review/reporters/score-reporter.d.ts +84 -0
- package/dist/services/review/reporters/score-reporter.d.ts.map +1 -0
- package/dist/services/review/reporters/score-reporter.js +560 -0
- package/dist/services/review/reporters/score-reporter.js.map +1 -0
- package/dist/services/review/review.service.d.ts +129 -0
- package/dist/services/review/review.service.d.ts.map +1 -0
- package/dist/services/review/review.service.js +396 -0
- package/dist/services/review/review.service.js.map +1 -0
- package/dist/services/review/review.types.d.ts +443 -0
- package/dist/services/review/review.types.d.ts.map +1 -0
- package/dist/services/review/review.types.js +11 -0
- package/dist/services/review/review.types.js.map +1 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.d.ts +53 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.js +260 -0
- package/dist/services/scoring/dimensions/accessibility.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.d.ts +138 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.js +713 -0
- package/dist/services/scoring/dimensions/backend-logic.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.d.ts +142 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.js +747 -0
- package/dist/services/scoring/dimensions/business-logic.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.d.ts +142 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.js +685 -0
- package/dist/services/scoring/dimensions/code-quality.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/index.d.ts +18 -0
- package/dist/services/scoring/dimensions/index.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/index.js +27 -0
- package/dist/services/scoring/dimensions/index.js.map +1 -0
- package/dist/services/scoring/dimensions/performance.analyzer.d.ts +125 -0
- package/dist/services/scoring/dimensions/performance.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/performance.analyzer.js +615 -0
- package/dist/services/scoring/dimensions/performance.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/security.analyzer.d.ts +53 -0
- package/dist/services/scoring/dimensions/security.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/security.analyzer.js +327 -0
- package/dist/services/scoring/dimensions/security.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/seo.analyzer.d.ts +77 -0
- package/dist/services/scoring/dimensions/seo.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/seo.analyzer.js +502 -0
- package/dist/services/scoring/dimensions/seo.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.d.ts +106 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.js +496 -0
- package/dist/services/scoring/dimensions/test-coverage.analyzer.js.map +1 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.d.ts +126 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.d.ts.map +1 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.js +665 -0
- package/dist/services/scoring/dimensions/ui-ux.analyzer.js.map +1 -0
- package/dist/services/scoring/index.d.ts +10 -0
- package/dist/services/scoring/index.d.ts.map +1 -0
- package/dist/services/scoring/index.js +10 -0
- package/dist/services/scoring/index.js.map +1 -0
- package/dist/services/scoring/scoring-service.d.ts +222 -0
- package/dist/services/scoring/scoring-service.d.ts.map +1 -0
- package/dist/services/scoring/scoring-service.js +636 -0
- package/dist/services/scoring/scoring-service.js.map +1 -0
- package/package.json +11 -3
- package/templates/README.md +183 -0
- package/templates/nestjs/controller.spec.ts +203 -0
- package/templates/nestjs/e2e/api.e2e-spec.ts +451 -0
- package/templates/nestjs/e2e/auth.e2e-spec.ts +533 -0
- package/templates/nestjs/fixtures/test-module.ts +311 -0
- package/templates/nestjs/guard.spec.ts +314 -0
- package/templates/nestjs/interceptor.spec.ts +458 -0
- package/templates/nestjs/module.spec.ts +173 -0
- package/templates/nestjs/pipe.spec.ts +474 -0
- package/templates/nestjs/service.spec.ts +296 -0
- package/templates/rust/Cargo.toml +72 -0
- package/templates/rust/actix-controller.test.rs +114 -0
- package/templates/rust/axum-handler.test.rs +117 -0
- package/templates/rust/integration.test.rs +63 -0
- package/templates/rust/rocket-route.test.rs +106 -0
- package/templates/rust/unit.test.rs +38 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anti-Patterns Catalog
|
|
3
|
+
*
|
|
4
|
+
* Collection of known anti-patterns with detection rules,
|
|
5
|
+
* severity levels, and recommended solutions.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* React/Hooks Anti-Patterns
|
|
9
|
+
*/
|
|
10
|
+
const reactAntiPatterns = [
|
|
11
|
+
{
|
|
12
|
+
id: 'react-missing-deps',
|
|
13
|
+
name: 'Missing useEffect Dependencies',
|
|
14
|
+
category: 'bug',
|
|
15
|
+
description: 'useEffect is missing dependencies in its dependency array, which can cause stale closures or infinite loops',
|
|
16
|
+
severity: 'high',
|
|
17
|
+
pattern: /useEffect\s*\(\s*\(\)\s*=>\s*{[^}]*}\s*,\s*\[\s*\]\s*\)/gs,
|
|
18
|
+
fix: 'Add all external values used inside the effect to the dependency array',
|
|
19
|
+
badExample: `useEffect(() => {
|
|
20
|
+
console.log(userId);
|
|
21
|
+
}, []);`,
|
|
22
|
+
goodExample: `useEffect(() => {
|
|
23
|
+
console.log(userId);
|
|
24
|
+
}, [userId]);`,
|
|
25
|
+
resources: ['https://react.dev/reference/react/useEffect'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 'react-setstate-in-render',
|
|
29
|
+
name: 'setState During Render',
|
|
30
|
+
category: 'bug',
|
|
31
|
+
description: 'Calling setState during render can cause infinite loops',
|
|
32
|
+
severity: 'critical',
|
|
33
|
+
pattern: /(?:useState|setState)\([^)]*\)\s*\([^)]*\)/s,
|
|
34
|
+
fix: 'Move state update to useEffect or event handler',
|
|
35
|
+
badExample: `function Component() {
|
|
36
|
+
const [count, setCount] = useState(0);
|
|
37
|
+
setCount(count + 1); // Infinite loop!
|
|
38
|
+
return <div>{count}</div>;
|
|
39
|
+
}`,
|
|
40
|
+
goodExample: `function Component() {
|
|
41
|
+
const [count, setCount] = useState(0);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
setCount(count + 1);
|
|
44
|
+
}, []);
|
|
45
|
+
return <div>{count}</div>;
|
|
46
|
+
}`,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'react-missing-memo',
|
|
50
|
+
name: 'Missing React.memo on Expensive Component',
|
|
51
|
+
category: 'performance',
|
|
52
|
+
description: 'Component performs expensive computations on every render without memoization',
|
|
53
|
+
severity: 'medium',
|
|
54
|
+
pattern: /export\s+function\s+\w+\s*\([^)]*\)\s*{[\s\S]{500,}/s,
|
|
55
|
+
fix: 'Wrap component in React.memo or use useMemo for expensive calculations',
|
|
56
|
+
badExample: `export function ExpensiveList({ items }) {
|
|
57
|
+
const sorted = items.sort((a, b) => a.value - b.value);
|
|
58
|
+
const filtered = sorted.filter(i => i.active);
|
|
59
|
+
return filtered.map(i => <Item key={i.id} {...i} />);
|
|
60
|
+
}`,
|
|
61
|
+
goodExample: `export const ExpensiveList = React.memo(({ items }) => {
|
|
62
|
+
const sorted = useMemo(() => [...items].sort((a, b) => a.value - b.value), [items]);
|
|
63
|
+
const filtered = useMemo(() => sorted.filter(i => i.active), [sorted]);
|
|
64
|
+
return filtered.map(i => <Item key={i.id} {...i} />);
|
|
65
|
+
});`,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'react-inline-function-in-loop',
|
|
69
|
+
name: 'Inline Function in Loop',
|
|
70
|
+
category: 'performance',
|
|
71
|
+
description: 'Creating new functions on every iteration causes child re-renders',
|
|
72
|
+
severity: 'medium',
|
|
73
|
+
pattern: /{.*\.map\s*\([^)]*\)\s*=>\s*<[^>]+onClick={\s*\([^)]*\)\s*=>/s,
|
|
74
|
+
fix: 'Move function outside component or use useCallback',
|
|
75
|
+
badExample: `{items.map(item => (
|
|
76
|
+
<Button onClick={() => handleClick(item.id)}>{item.name}</Button>
|
|
77
|
+
))}`,
|
|
78
|
+
goodExample: `const handleItemClick = useCallback((id) => {
|
|
79
|
+
handleClick(id);
|
|
80
|
+
}, [handleClick]);
|
|
81
|
+
|
|
82
|
+
{items.map(item => (
|
|
83
|
+
<Button onClick={() => handleItemClick(item.id)}>{item.name}</Button>
|
|
84
|
+
))}`,
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
/**
|
|
88
|
+
* Security Anti-Patterns
|
|
89
|
+
*/
|
|
90
|
+
const securityAntiPatterns = [
|
|
91
|
+
{
|
|
92
|
+
id: 'xss-innerhtml',
|
|
93
|
+
name: 'XSS via innerHTML',
|
|
94
|
+
category: 'bug',
|
|
95
|
+
description: 'Using innerHTML with user input can lead to XSS attacks',
|
|
96
|
+
severity: 'critical',
|
|
97
|
+
pattern: /innerHTML\s*=\s*[^;]+/s,
|
|
98
|
+
fix: 'Use textContent or sanitize input with DOMPurify',
|
|
99
|
+
badExample: `element.innerHTML = userInput;`,
|
|
100
|
+
goodExample: `element.textContent = userInput;
|
|
101
|
+
// OR
|
|
102
|
+
import DOMPurify from 'dompurify';
|
|
103
|
+
element.innerHTML = DOMPurify.sanitize(userInput);`,
|
|
104
|
+
resources: ['https://owasp.org/www-community/attacks/xss/'],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'xss-dangerouslysetinnerhtml',
|
|
108
|
+
name: 'React dangerouslySetInnerHTML',
|
|
109
|
+
category: 'bug',
|
|
110
|
+
description: 'Using dangerouslySetInnerHTML with unsanitized data',
|
|
111
|
+
severity: 'high',
|
|
112
|
+
pattern: /dangerouslySetInnerHTML\s*=\s*{\s*__html:\s*[^}]+\s*}/s,
|
|
113
|
+
fix: 'Sanitize HTML with DOMPurify or use safe alternatives',
|
|
114
|
+
badExample: `<div dangerouslySetInnerHTML={{ __html: userContent }} />`,
|
|
115
|
+
goodExample: `import DOMPurify from 'dompurify';
|
|
116
|
+
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />`,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'sql-injection-string-concat',
|
|
120
|
+
name: 'SQL Injection via String Concatenation',
|
|
121
|
+
category: 'bug',
|
|
122
|
+
description: 'Building SQL queries with string concatenation is vulnerable to injection',
|
|
123
|
+
severity: 'critical',
|
|
124
|
+
pattern: /(?:SELECT|INSERT|UPDATE|DELETE)\s+.*?\+\s*[^;\s]+/gis,
|
|
125
|
+
fix: 'Use parameterized queries or prepared statements',
|
|
126
|
+
badExample: `const query = "SELECT * FROM users WHERE id = " + userId;`,
|
|
127
|
+
goodExample: `const query = "SELECT * FROM users WHERE id = $1";
|
|
128
|
+
await db.query(query, [userId]);`,
|
|
129
|
+
resources: ['https://owasp.org/www-community/attacks/SQL_Injection'],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: 'missing-input-validation',
|
|
133
|
+
name: 'Missing Input Validation',
|
|
134
|
+
category: 'bug',
|
|
135
|
+
description: 'User input is used without validation',
|
|
136
|
+
severity: 'high',
|
|
137
|
+
pattern: /(?:req\.body|req\.query|req\.params|formData|URLSearchParams)\.[^;]+(?!\s*\.|!|\?|&&|\|\||typeof|instanceof)/s,
|
|
138
|
+
fix: 'Validate input with a schema validator like Zod',
|
|
139
|
+
badExample: `const email = req.body.email;
|
|
140
|
+
await sendEmail(email);`,
|
|
141
|
+
goodExample: `const schema = z.object({ email: z.string().email() });
|
|
142
|
+
const { email } = schema.parse(req.body);
|
|
143
|
+
await sendEmail(email);`,
|
|
144
|
+
},
|
|
145
|
+
];
|
|
146
|
+
/**
|
|
147
|
+
* Memory Leak Anti-Patterns
|
|
148
|
+
*/
|
|
149
|
+
const memoryLeakPatterns = [
|
|
150
|
+
{
|
|
151
|
+
id: 'missing-cleanup-useeffect',
|
|
152
|
+
name: 'Missing useEffect Cleanup',
|
|
153
|
+
category: 'bug',
|
|
154
|
+
description: 'useEffect with subscriptions or timers lacks cleanup function',
|
|
155
|
+
severity: 'high',
|
|
156
|
+
pattern: /addEventListener\s*\([^)]*\)\s*(?!.*return\s*\(\s*=>\s*.*removeEventListener)|setInterval\s*\([^)]*\)\s*(?!.*return\s*\(\s*=>\s*.*clearInterval)|setTimeout\s*\([^)]*\)\s*(?!.*return\s*\(\s*=>\s*.*clearTimeout)/s,
|
|
157
|
+
fix: 'Return a cleanup function from useEffect',
|
|
158
|
+
badExample: `useEffect(() => {
|
|
159
|
+
window.addEventListener('resize', handleResize);
|
|
160
|
+
}, []);`,
|
|
161
|
+
goodExample: `useEffect(() => {
|
|
162
|
+
window.addEventListener('resize', handleResize);
|
|
163
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
164
|
+
}, []);`,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: 'closure-in-setinterval',
|
|
168
|
+
name: 'Stale Closure in setInterval',
|
|
169
|
+
category: 'bug',
|
|
170
|
+
description: 'setInterval captures stale state values due to closure',
|
|
171
|
+
severity: 'high',
|
|
172
|
+
pattern: /setInterval\s*\(\s*\(\)\s*=>\s*{[^}]*state[^}]*}\s*,/s,
|
|
173
|
+
fix: 'Use useRef for state that needs to be accessed in intervals, or use setInterval with state updater function',
|
|
174
|
+
badExample: `const [count, setCount] = useState(0);
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
const id = setInterval(() => {
|
|
177
|
+
console.log(count); // Always 0
|
|
178
|
+
}, 1000);
|
|
179
|
+
return () => clearInterval(id);
|
|
180
|
+
}, []);`,
|
|
181
|
+
goodExample: `const [count, setCount] = useState(0);
|
|
182
|
+
const countRef = useRef(count);
|
|
183
|
+
countRef.current = count;
|
|
184
|
+
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
const id = setInterval(() => {
|
|
187
|
+
console.log(countRef.current);
|
|
188
|
+
}, 1000);
|
|
189
|
+
return () => clearInterval(id);
|
|
190
|
+
}, []);`,
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
/**
|
|
194
|
+
* Performance Anti-Patterns
|
|
195
|
+
*/
|
|
196
|
+
const performanceAntiPatterns = [
|
|
197
|
+
{
|
|
198
|
+
id: 'n-plus-1-query',
|
|
199
|
+
name: 'N+1 Query Problem',
|
|
200
|
+
category: 'performance',
|
|
201
|
+
description: 'Querying related data inside a loop causes N+1 database queries',
|
|
202
|
+
severity: 'high',
|
|
203
|
+
pattern: /for\s*\(?:(?:const|let|var)\s+\w+\s+of\s+[^)]+\)\s*{[\s\S]*?(?:await|\.then|exec|query)\s*\(/s,
|
|
204
|
+
fix: 'Use eager loading, joins, or batch queries',
|
|
205
|
+
badExample: `const posts = await db.post.findMany();
|
|
206
|
+
for (const post of posts) {
|
|
207
|
+
post.author = await db.user.findUnique({ where: { id: post.authorId } });
|
|
208
|
+
}`,
|
|
209
|
+
goodExample: `const posts = await db.post.findMany({
|
|
210
|
+
include: { author: true }
|
|
211
|
+
});`,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: 'missing-usememo-computation',
|
|
215
|
+
name: 'Expensive Computation Without useMemo',
|
|
216
|
+
category: 'performance',
|
|
217
|
+
description: 'Expensive calculation recalculates on every render',
|
|
218
|
+
severity: 'medium',
|
|
219
|
+
pattern: /const\s+\w+\s*=\s*(?:array|object)?\.?(?:sort|filter|reduce|map)\s*\([^)]+\)\s*(?:\.sort|\.filter|\.reduce|\.map)\s*\([^)]+\)/s,
|
|
220
|
+
fix: 'Wrap expensive calculations in useMemo',
|
|
221
|
+
badExample: `const sortedFiltered = items.filter(i => i.active).sort((a, b) => a.value - b.value);`,
|
|
222
|
+
goodExample: `const sortedFiltered = useMemo(
|
|
223
|
+
() => items.filter(i => i.active).sort((a, b) => a.value - b.value),
|
|
224
|
+
[items]
|
|
225
|
+
);`,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: 'unnecessary-rerender-prop-change',
|
|
229
|
+
name: 'Unnecessary Re-render from Prop Change',
|
|
230
|
+
category: 'performance',
|
|
231
|
+
description: 'Component re-renders because prop reference changes on every parent render',
|
|
232
|
+
severity: 'medium',
|
|
233
|
+
pattern: /<\w+\s+(?:on\w+|data-\w+)={\s*\([^)]*\)\s*=>/s,
|
|
234
|
+
fix: 'Use useCallback for event handlers passed as props',
|
|
235
|
+
badExample: `function Parent() {
|
|
236
|
+
const [count, setCount] = useState(0);
|
|
237
|
+
return <Child onClick={() => console.log(count)} />;
|
|
238
|
+
}`,
|
|
239
|
+
goodExample: `function Parent() {
|
|
240
|
+
const [count, setCount] = useState(0);
|
|
241
|
+
const handleClick = useCallback(() => console.log(count), [count]);
|
|
242
|
+
return <Child onClick={handleClick} />;
|
|
243
|
+
}`,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: 'large-bundle-chunk',
|
|
247
|
+
name: 'Large Bundle Chunk',
|
|
248
|
+
category: 'performance',
|
|
249
|
+
description: 'Bundle contains large chunks that could be code-split',
|
|
250
|
+
severity: 'medium',
|
|
251
|
+
pattern: /{[\s\S]{500,}}/s, // General indicator, needs analysis
|
|
252
|
+
fix: 'Use dynamic import for code splitting',
|
|
253
|
+
badExample: `import { HeavyComponent } from './HeavyComponent';
|
|
254
|
+
<HeavyComponent />`,
|
|
255
|
+
goodExample: `const HeavyComponent = lazy(() => import('./HeavyComponent'));
|
|
256
|
+
<Suspense fallback={<Loading />}>
|
|
257
|
+
<HeavyComponent />
|
|
258
|
+
</Suspense>`,
|
|
259
|
+
},
|
|
260
|
+
];
|
|
261
|
+
/**
|
|
262
|
+
* Code Smell Anti-Patterns
|
|
263
|
+
*/
|
|
264
|
+
const codeSmellPatterns = [
|
|
265
|
+
{
|
|
266
|
+
id: 'long-function',
|
|
267
|
+
name: 'Long Function',
|
|
268
|
+
category: 'code-smell',
|
|
269
|
+
description: 'Function is too long and does too many things',
|
|
270
|
+
severity: 'low',
|
|
271
|
+
pattern: /function\s+\w+\s*\([^)]*\)\s*{[\s\S]{1000,}}/s,
|
|
272
|
+
fix: 'Break function into smaller, single-purpose functions',
|
|
273
|
+
badExample: `function processUserData(data) {
|
|
274
|
+
// 50+ lines of processing...
|
|
275
|
+
}`,
|
|
276
|
+
goodExample: `function processUserData(data) {
|
|
277
|
+
const validated = validateData(data);
|
|
278
|
+
const transformed = transformData(validated);
|
|
279
|
+
return saveData(transformed);
|
|
280
|
+
}`,
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
id: 'magic-number',
|
|
284
|
+
name: 'Magic Number',
|
|
285
|
+
category: 'code-smell',
|
|
286
|
+
description: 'Unnamed numeric literal obscures meaning',
|
|
287
|
+
severity: 'low',
|
|
288
|
+
pattern: /[^a-zA-Z0-9](?:\d{2,}|0x[0-9A-Fa-f]+)[^a-zA-Z0-9]/s,
|
|
289
|
+
fix: 'Extract to named constant',
|
|
290
|
+
badExample: `if (status === 2) { ... }
|
|
291
|
+
setTimeout(callback, 86400000);`,
|
|
292
|
+
goodExample: `const STATUS_ACTIVE = 2;
|
|
293
|
+
const MILLISECONDS_PER_DAY = 86400000;
|
|
294
|
+
if (status === STATUS_ACTIVE) { ... }
|
|
295
|
+
setTimeout(callback, MILLISECONDS_PER_DAY);`,
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
id: 'deep-nesting',
|
|
299
|
+
name: 'Deep Nesting',
|
|
300
|
+
category: 'code-smell',
|
|
301
|
+
description: 'Code is nested too deeply (arrow code)',
|
|
302
|
+
severity: 'medium',
|
|
303
|
+
pattern: /(?:if|for|while|try|function|=>)\s*\([^)]*\)\s*{[^}]{50}(?:if|for|while|try|function|=>)\s*\([^)]*\)\s*{[^}]{50}(?:if|for|while|try|function|=>)\s*\([^)]*\)\s*{/s,
|
|
304
|
+
fix: 'Use early returns and guard clauses',
|
|
305
|
+
badExample: `function process(data) {
|
|
306
|
+
if (data) {
|
|
307
|
+
if (data.items) {
|
|
308
|
+
for (const item of data.items) {
|
|
309
|
+
if (item.active) {
|
|
310
|
+
if (item.valid) {
|
|
311
|
+
// Process item
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}`,
|
|
318
|
+
goodExample: `function process(data) {
|
|
319
|
+
if (!data?.items) return;
|
|
320
|
+
for (const item of data.items) {
|
|
321
|
+
if (!item.active || !item.valid) continue;
|
|
322
|
+
// Process item
|
|
323
|
+
}
|
|
324
|
+
}`,
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
id: 'god-object',
|
|
328
|
+
name: 'God Object',
|
|
329
|
+
category: 'code-smell',
|
|
330
|
+
description: 'Class/object knows too much or does too much',
|
|
331
|
+
severity: 'medium',
|
|
332
|
+
pattern: /class\s+\w+\s*{[\s\S]{1000,}(?:public|private|protected)\s+\w+\s*\([^)]*\)[\s\S]{200,}(?:public|private|protected)\s+\w+\s*\([^)]*\)[\s\S]{200,}(?:public|private|protected)\s+\w+\s*\([^)]*\)/s,
|
|
333
|
+
fix: 'Split into smaller, focused classes with single responsibility',
|
|
334
|
+
badExample: `class UserManager {
|
|
335
|
+
createUser() { /* ... */ }
|
|
336
|
+
updateUser() { /* ... */ }
|
|
337
|
+
deleteUser() { /* ... */ }
|
|
338
|
+
sendEmail() { /* ... */ }
|
|
339
|
+
generateReport() { /* ... */ }
|
|
340
|
+
handlePayments() { /* ... */ }
|
|
341
|
+
// 20+ more methods...
|
|
342
|
+
}`,
|
|
343
|
+
goodExample: `class UserService {
|
|
344
|
+
create() { /* ... */ }
|
|
345
|
+
update() { /* ... */ }
|
|
346
|
+
delete() { /* ... */ }
|
|
347
|
+
}
|
|
348
|
+
class EmailService {
|
|
349
|
+
send() { /* ... */ }
|
|
350
|
+
}
|
|
351
|
+
class ReportService {
|
|
352
|
+
generate() { /* ... */ }
|
|
353
|
+
}`,
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
id: 'duplicated-code',
|
|
357
|
+
name: 'Duplicated Code',
|
|
358
|
+
category: 'code-smell',
|
|
359
|
+
description: 'Same or very similar code appears in multiple places',
|
|
360
|
+
severity: 'medium',
|
|
361
|
+
pattern: '', // Requires cross-file analysis (detected separately)
|
|
362
|
+
fix: 'Extract to a reusable function or component',
|
|
363
|
+
badExample: `// File A
|
|
364
|
+
function validateEmail(email) {
|
|
365
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
366
|
+
return regex.test(email);
|
|
367
|
+
}
|
|
368
|
+
// File B
|
|
369
|
+
function checkEmail(email) {
|
|
370
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
371
|
+
return regex.test(email);
|
|
372
|
+
}`,
|
|
373
|
+
goodExample: `// utils/validation.js
|
|
374
|
+
export function isValidEmail(email) {
|
|
375
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
376
|
+
return regex.test(email);
|
|
377
|
+
}
|
|
378
|
+
// Both files import and use isValidEmail`,
|
|
379
|
+
},
|
|
380
|
+
];
|
|
381
|
+
/**
|
|
382
|
+
* Async/Await Anti-Patterns
|
|
383
|
+
*/
|
|
384
|
+
const asyncAntiPatterns = [
|
|
385
|
+
{
|
|
386
|
+
id: 'missing-await-promise',
|
|
387
|
+
name: 'Missing await on Promise',
|
|
388
|
+
category: 'bug',
|
|
389
|
+
description: 'Promise is not awaited, potentially causing unhandled rejections',
|
|
390
|
+
severity: 'high',
|
|
391
|
+
pattern: /(?:const|let|var)\s+\w+\s*=\s*(?!await)(?:fetch|axios|request|\.query|\.exec|\.find)[(\s]/s,
|
|
392
|
+
fix: 'Add await keyword or handle the Promise properly',
|
|
393
|
+
badExample: `const data = fetchData();
|
|
394
|
+
console.log(data.results); // undefined!`,
|
|
395
|
+
goodExample: `const data = await fetchData();
|
|
396
|
+
console.log(data.results);`,
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
id: 'race-condition-state-update',
|
|
400
|
+
name: 'Race Condition in State Update',
|
|
401
|
+
category: 'bug',
|
|
402
|
+
description: 'State update based on previous state without using updater function',
|
|
403
|
+
severity: 'high',
|
|
404
|
+
pattern: /setState\s*\(\s*\w+\s*\+\s*1\s*\)/s,
|
|
405
|
+
fix: 'Use functional state updates',
|
|
406
|
+
badExample: `const [count, setCount] = useState(0);
|
|
407
|
+
setCount(count + 1);
|
|
408
|
+
setCount(count + 1); // Both use same count value!`,
|
|
409
|
+
goodExample: `const [count, setCount] = useState(0);
|
|
410
|
+
setCount(c => c + 1);
|
|
411
|
+
setCount(c => c + 1); // Correct sequential updates`,
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: 'fire-and-forget-async',
|
|
415
|
+
name: 'Fire and Forget Async',
|
|
416
|
+
category: 'bug',
|
|
417
|
+
description: 'Async function called without await, errors are silently ignored',
|
|
418
|
+
severity: 'medium',
|
|
419
|
+
pattern: /[a-zA-Z]\w*\s*\([^)]*\)\s*(?!.*(?:await|\.then|\.catch)\s*;)\s*;/s,
|
|
420
|
+
fix: 'Await the promise or add error handling',
|
|
421
|
+
badExample: `async function saveData() {
|
|
422
|
+
await db.save(data);
|
|
423
|
+
}
|
|
424
|
+
saveData(); // Errors are ignored!`,
|
|
425
|
+
goodExample: `async function saveData() {
|
|
426
|
+
await db.save(data);
|
|
427
|
+
}
|
|
428
|
+
await saveData();
|
|
429
|
+
// OR
|
|
430
|
+
saveData().catch(console.error);`,
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
id: 'missing-error-handling',
|
|
434
|
+
name: 'Missing Error Handling',
|
|
435
|
+
category: 'bug',
|
|
436
|
+
description: 'Async operation lacks try/catch or .catch()',
|
|
437
|
+
severity: 'high',
|
|
438
|
+
pattern: /await\s+[\w\[\].]+(?:\([^)]*\))?(?!\s*(?:\?\s*\.|\.catch|try\s*{))/s,
|
|
439
|
+
fix: 'Wrap in try/catch or add .catch()',
|
|
440
|
+
badExample: `const data = await fetch(url);
|
|
441
|
+
const json = await data.json();`,
|
|
442
|
+
goodExample: `try {
|
|
443
|
+
const data = await fetch(url);
|
|
444
|
+
const json = await data.json();
|
|
445
|
+
} catch (error) {
|
|
446
|
+
console.error('Failed to fetch:', error);
|
|
447
|
+
}`,
|
|
448
|
+
},
|
|
449
|
+
];
|
|
450
|
+
/**
|
|
451
|
+
* All anti-patterns catalog
|
|
452
|
+
*/
|
|
453
|
+
export const ANTI_PATTERNS = [
|
|
454
|
+
...reactAntiPatterns,
|
|
455
|
+
...securityAntiPatterns,
|
|
456
|
+
...memoryLeakPatterns,
|
|
457
|
+
...performanceAntiPatterns,
|
|
458
|
+
...codeSmellPatterns,
|
|
459
|
+
...asyncAntiPatterns,
|
|
460
|
+
];
|
|
461
|
+
/**
|
|
462
|
+
* Get anti-patterns by category
|
|
463
|
+
*/
|
|
464
|
+
export function getAntiPatternsByCategory(category) {
|
|
465
|
+
return ANTI_PATTERNS.filter(p => p.category === category);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Get anti-pattern by ID
|
|
469
|
+
*/
|
|
470
|
+
export function getAntiPatternById(id) {
|
|
471
|
+
return ANTI_PATTERNS.find(p => p.id === id);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get anti-patterns by severity
|
|
475
|
+
*/
|
|
476
|
+
export function getAntiPatternsBySeverity(severity) {
|
|
477
|
+
return ANTI_PATTERNS.filter(p => p.severity === severity);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Check if code matches any anti-pattern
|
|
481
|
+
*/
|
|
482
|
+
export function findMatchingAntiPatterns(code, language) {
|
|
483
|
+
const results = [];
|
|
484
|
+
for (const pattern of ANTI_PATTERNS) {
|
|
485
|
+
if (typeof pattern.pattern === 'string' && pattern.pattern) {
|
|
486
|
+
const regex = new RegExp(pattern.pattern);
|
|
487
|
+
const matches = code.match(regex);
|
|
488
|
+
if (matches) {
|
|
489
|
+
results.push({ pattern, matches: matches.filter(m => m) });
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
else if (pattern.pattern instanceof RegExp) {
|
|
493
|
+
const matches = code.match(pattern.pattern);
|
|
494
|
+
if (matches) {
|
|
495
|
+
results.push({ pattern, matches: matches.filter(m => m) });
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return results;
|
|
500
|
+
}
|
|
501
|
+
//# sourceMappingURL=anti-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anti-patterns.js","sourceRoot":"","sources":["../../../../src/services/optimization/patterns/anti-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/optimization/patterns/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/optimization/patterns/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart Exporter
|
|
3
|
+
*
|
|
4
|
+
* Generates SVG charts for reports without external dependencies.
|
|
5
|
+
*/
|
|
6
|
+
import type { ChartConfig, GaugeOptions, TrendDataPoint, BarChartData } from '../reporting.types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Chart exporter for SVG generation
|
|
9
|
+
*/
|
|
10
|
+
export declare class ChartExporter {
|
|
11
|
+
/**
|
|
12
|
+
* Generate a gauge chart SVG
|
|
13
|
+
*
|
|
14
|
+
* @param options - Gauge options
|
|
15
|
+
* @returns SVG string
|
|
16
|
+
*/
|
|
17
|
+
static generateGauge(options: GaugeOptions): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generate a trend line chart SVG
|
|
20
|
+
*
|
|
21
|
+
* @param data - Trend data points
|
|
22
|
+
* @param config - Chart configuration
|
|
23
|
+
* @returns SVG string
|
|
24
|
+
*/
|
|
25
|
+
static generateTrendChart(data: TrendDataPoint[], config?: Partial<ChartConfig>): string;
|
|
26
|
+
/**
|
|
27
|
+
* Generate a bar chart SVG
|
|
28
|
+
*
|
|
29
|
+
* @param data - Bar chart data
|
|
30
|
+
* @param config - Chart configuration
|
|
31
|
+
* @returns SVG string
|
|
32
|
+
*/
|
|
33
|
+
static generateBarChart(data: BarChartData[], config?: Partial<ChartConfig>): string;
|
|
34
|
+
/**
|
|
35
|
+
* Generate a donut chart SVG
|
|
36
|
+
*
|
|
37
|
+
* @param data - Data segments with labels and values
|
|
38
|
+
* @param config - Chart configuration
|
|
39
|
+
* @returns SVG string
|
|
40
|
+
*/
|
|
41
|
+
static generateDonutChart(data: Array<{
|
|
42
|
+
label: string;
|
|
43
|
+
value: number;
|
|
44
|
+
color?: string;
|
|
45
|
+
}>, config?: Partial<ChartConfig>): string;
|
|
46
|
+
/**
|
|
47
|
+
* Get color based on bar value
|
|
48
|
+
*/
|
|
49
|
+
private static getBarColor;
|
|
50
|
+
/**
|
|
51
|
+
* Get default color for chart segments
|
|
52
|
+
*/
|
|
53
|
+
private static getDefaultColor;
|
|
54
|
+
/**
|
|
55
|
+
* Truncate label for display
|
|
56
|
+
*/
|
|
57
|
+
private static truncateLabel;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=chart.exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.exporter.d.ts","sourceRoot":"","sources":["../../../../src/services/reporting/export/chart.exporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,YAAY,EACb,MAAM,uBAAuB,CAAC;AAkC/B;;GAEG;AACH,qBAAa,aAAa;IACxB;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;IAkFnD;;;;;;OAMG;IACH,MAAM,CAAC,kBAAkB,CACvB,IAAI,EAAE,cAAc,EAAE,EACtB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,MAAM;IAiHT;;;;;;OAMG;IACH,MAAM,CAAC,gBAAgB,CACrB,IAAI,EAAE,YAAY,EAAE,EACpB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,MAAM;IA2ET;;;;;;OAMG;IACH,MAAM,CAAC,kBAAkB,CACvB,IAAI,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7D,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,MAAM;IA6ET;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAQ1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAY9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;CAI7B"}
|