@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,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Dimension Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes Search Engine Optimization factors for web applications.
|
|
5
|
+
* Checks meta tags, structured data, sitemap, robots.txt, and more.
|
|
6
|
+
*
|
|
7
|
+
* @module services/scoring/dimensions/seo-analyzer
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { createLogger } from '../../../shared/utils/logger.js';
|
|
13
|
+
/**
|
|
14
|
+
* Required and recommended meta tags
|
|
15
|
+
*/
|
|
16
|
+
const META_TAGS = [
|
|
17
|
+
{ name: 'title', required: true, weight: 15, description: 'Page title' },
|
|
18
|
+
{ name: 'description', required: true, weight: 15, description: 'Meta description' },
|
|
19
|
+
{ name: 'viewport', required: true, weight: 10, description: 'Viewport for mobile' },
|
|
20
|
+
{ name: 'charset', required: true, weight: 5, description: 'Character encoding' },
|
|
21
|
+
{ name: 'robots', required: false, weight: 5, description: 'Robots directive' },
|
|
22
|
+
{ name: 'canonical', required: false, weight: 10, description: 'Canonical URL' },
|
|
23
|
+
{ name: 'og:title', required: false, weight: 8, description: 'Open Graph title' },
|
|
24
|
+
{ name: 'og:description', required: false, weight: 8, description: 'Open Graph description' },
|
|
25
|
+
{ name: 'og:image', required: false, weight: 8, description: 'Open Graph image' },
|
|
26
|
+
{ name: 'og:type', required: false, weight: 5, description: 'Open Graph type' },
|
|
27
|
+
{ name: 'og:url', required: false, weight: 5, description: 'Open Graph URL' },
|
|
28
|
+
{ name: 'twitter:card', required: false, weight: 6, description: 'Twitter card type' },
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* SEO Dimension Analyzer
|
|
32
|
+
*
|
|
33
|
+
* Evaluates SEO quality across multiple dimensions:
|
|
34
|
+
* - Meta tags (title, description, Open Graph, Twitter Cards)
|
|
35
|
+
* - Structured data (JSON-LD, Microdata)
|
|
36
|
+
* - Sitemap.xml
|
|
37
|
+
* - Robots.txt
|
|
38
|
+
* - Heading structure
|
|
39
|
+
* - Image alt attributes
|
|
40
|
+
* - Semantic HTML
|
|
41
|
+
* - Core Web Vitals (indirect SEO factor)
|
|
42
|
+
*/
|
|
43
|
+
export class SeoAnalyzer {
|
|
44
|
+
/** Analyzer configuration */
|
|
45
|
+
config = {
|
|
46
|
+
dimension: 'seo',
|
|
47
|
+
defaultWeight: 0.09,
|
|
48
|
+
estimatedDuration: 15000,
|
|
49
|
+
supportedFrameworks: ['Next.js', 'React', 'Vue', 'Nuxt', 'Svelte', 'Angular', 'Remix', 'SvelteKit', 'Astro', 'Gatsby'],
|
|
50
|
+
};
|
|
51
|
+
logger;
|
|
52
|
+
constructor() {
|
|
53
|
+
this.logger = createLogger('SeoAnalyzer');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Analyze SEO for a project
|
|
57
|
+
*/
|
|
58
|
+
async analyze(projectPath, _framework, _options) {
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
this.logger.info(`Analyzing SEO for: ${projectPath}`);
|
|
61
|
+
const issues = [];
|
|
62
|
+
const improvements = [];
|
|
63
|
+
let score = 0;
|
|
64
|
+
// Run all SEO checks
|
|
65
|
+
const checkResults = await this.runAllSeoChecks(projectPath);
|
|
66
|
+
// Calculate base score from checks
|
|
67
|
+
score = this.calculateScore(checkResults);
|
|
68
|
+
// Generate issues from failed checks
|
|
69
|
+
issues.push(...this.generateIssues(checkResults));
|
|
70
|
+
// Generate improvements
|
|
71
|
+
improvements.push(...this.generateImprovements(checkResults));
|
|
72
|
+
// Additional metadata analysis
|
|
73
|
+
const metadata = await this.analyzeSeoMetadata(projectPath);
|
|
74
|
+
const duration = Date.now() - startTime;
|
|
75
|
+
return {
|
|
76
|
+
dimension: 'seo',
|
|
77
|
+
score: Math.min(100, Math.max(0, score)),
|
|
78
|
+
weight: 0.10, // 10% weight in overall score
|
|
79
|
+
weightedScore: (Math.min(100, Math.max(0, score)) * 0.10),
|
|
80
|
+
issues,
|
|
81
|
+
improvements,
|
|
82
|
+
metadata: {
|
|
83
|
+
itemsChecked: checkResults.total,
|
|
84
|
+
itemsPassed: checkResults.passed,
|
|
85
|
+
metrics: {
|
|
86
|
+
...metadata,
|
|
87
|
+
analysisDuration: duration,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Run all SEO checks
|
|
94
|
+
*/
|
|
95
|
+
async runAllSeoChecks(projectPath) {
|
|
96
|
+
const results = new Map();
|
|
97
|
+
// Check 1: HTML file exists
|
|
98
|
+
const hasHtml = await this.checkHtmlFile(projectPath);
|
|
99
|
+
results.set('html-file', {
|
|
100
|
+
passed: hasHtml,
|
|
101
|
+
weight: 10,
|
|
102
|
+
description: 'HTML entry point exists',
|
|
103
|
+
});
|
|
104
|
+
// Check 2: Meta tags
|
|
105
|
+
const metaTagsResult = await this.checkMetaTags(projectPath);
|
|
106
|
+
results.set('meta-tags', {
|
|
107
|
+
passed: metaTagsResult.score >= 50,
|
|
108
|
+
weight: 30,
|
|
109
|
+
description: `Meta tags: ${metaTagsResult.found.length}/${META_TAGS.filter(t => t.required).length} required`,
|
|
110
|
+
});
|
|
111
|
+
// Check 3: Title tag
|
|
112
|
+
const hasTitle = await this.checkTitleTag(projectPath);
|
|
113
|
+
results.set('title-tag', {
|
|
114
|
+
passed: hasTitle,
|
|
115
|
+
weight: 15,
|
|
116
|
+
description: 'Title tag present and proper length',
|
|
117
|
+
});
|
|
118
|
+
// Check 4: Meta description
|
|
119
|
+
const hasDescription = await this.checkMetaDescription(projectPath);
|
|
120
|
+
results.set('meta-description', {
|
|
121
|
+
passed: hasDescription,
|
|
122
|
+
weight: 15,
|
|
123
|
+
description: 'Meta description present and proper length',
|
|
124
|
+
});
|
|
125
|
+
// Check 5: Heading structure
|
|
126
|
+
const headingsResult = await this.checkHeadingStructure(projectPath);
|
|
127
|
+
results.set('heading-structure', {
|
|
128
|
+
passed: headingsResult.hasH1 && headingsResult.hasProperHierarchy,
|
|
129
|
+
weight: 10,
|
|
130
|
+
description: `Headings: ${headingsResult.h1Count} H1, ${headingsResult.totalHeadings} total`,
|
|
131
|
+
});
|
|
132
|
+
// Check 6: Sitemap.xml
|
|
133
|
+
const hasSitemap = await this.checkSitemap(projectPath);
|
|
134
|
+
results.set('sitemap', {
|
|
135
|
+
passed: hasSitemap,
|
|
136
|
+
weight: 5,
|
|
137
|
+
description: 'Sitemap.xml exists',
|
|
138
|
+
});
|
|
139
|
+
// Check 7: Robots.txt
|
|
140
|
+
const hasRobots = await this.checkRobotsTxt(projectPath);
|
|
141
|
+
results.set('robots-txt', {
|
|
142
|
+
passed: hasRobots,
|
|
143
|
+
weight: 5,
|
|
144
|
+
description: 'Robots.txt exists',
|
|
145
|
+
});
|
|
146
|
+
// Check 8: Structured data
|
|
147
|
+
const hasStructuredData = await this.checkStructuredData(projectPath);
|
|
148
|
+
results.set('structured-data', {
|
|
149
|
+
passed: hasStructuredData,
|
|
150
|
+
weight: 10,
|
|
151
|
+
description: 'Structured data (JSON-LD) present',
|
|
152
|
+
});
|
|
153
|
+
// Check 9: Open Graph tags
|
|
154
|
+
const ogResult = await this.checkOpenGraph(projectPath);
|
|
155
|
+
results.set('open-graph', {
|
|
156
|
+
passed: ogResult.score >= 50,
|
|
157
|
+
weight: 10,
|
|
158
|
+
description: `Open Graph: ${ogResult.found}/${ogResult.total} tags`,
|
|
159
|
+
});
|
|
160
|
+
// Check 10: Semantic HTML
|
|
161
|
+
const semanticResult = await this.checkSemanticHtml(projectPath);
|
|
162
|
+
results.set('semantic-html', {
|
|
163
|
+
passed: semanticResult.score >= 50,
|
|
164
|
+
weight: 10,
|
|
165
|
+
description: `Semantic HTML elements: ${semanticResult.count}`,
|
|
166
|
+
});
|
|
167
|
+
// Calculate totals
|
|
168
|
+
let total = 0;
|
|
169
|
+
let passed = 0;
|
|
170
|
+
for (const [_, result] of Array.from(results.entries())) {
|
|
171
|
+
total += result.weight;
|
|
172
|
+
if (result.passed)
|
|
173
|
+
passed += result.weight;
|
|
174
|
+
}
|
|
175
|
+
return { results, total, passed };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Calculate SEO score from check results
|
|
179
|
+
*/
|
|
180
|
+
calculateScore(checkResults) {
|
|
181
|
+
return Math.round((checkResults.passed / checkResults.total) * 100);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Generate issues from failed checks
|
|
185
|
+
*/
|
|
186
|
+
generateIssues(checkResults) {
|
|
187
|
+
const issues = [];
|
|
188
|
+
for (const [name, result] of Array.from(checkResults.results.entries())) {
|
|
189
|
+
if (!result.passed) {
|
|
190
|
+
let severity = 'medium';
|
|
191
|
+
let fixable = true;
|
|
192
|
+
switch (name) {
|
|
193
|
+
case 'html-file':
|
|
194
|
+
severity = 'critical';
|
|
195
|
+
break;
|
|
196
|
+
case 'title-tag':
|
|
197
|
+
severity = 'critical';
|
|
198
|
+
break;
|
|
199
|
+
case 'meta-description':
|
|
200
|
+
severity = 'high';
|
|
201
|
+
break;
|
|
202
|
+
case 'meta-tags':
|
|
203
|
+
severity = 'high';
|
|
204
|
+
break;
|
|
205
|
+
case 'heading-structure':
|
|
206
|
+
severity = 'medium';
|
|
207
|
+
break;
|
|
208
|
+
case 'sitemap':
|
|
209
|
+
case 'robots-txt':
|
|
210
|
+
severity = 'medium';
|
|
211
|
+
fixable = true;
|
|
212
|
+
break;
|
|
213
|
+
case 'structured-data':
|
|
214
|
+
severity = 'low';
|
|
215
|
+
break;
|
|
216
|
+
case 'open-graph':
|
|
217
|
+
severity = 'medium';
|
|
218
|
+
break;
|
|
219
|
+
case 'semantic-html':
|
|
220
|
+
severity = 'low';
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
issues.push({
|
|
224
|
+
severity,
|
|
225
|
+
category: 'seo',
|
|
226
|
+
description: result.description,
|
|
227
|
+
fixable,
|
|
228
|
+
suggestion: this.getFixSuggestion(name),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return issues;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get fix suggestion for an issue
|
|
236
|
+
*/
|
|
237
|
+
getFixSuggestion(checkName) {
|
|
238
|
+
const suggestions = {
|
|
239
|
+
'html-file': 'Create an index.html file in the public or root directory',
|
|
240
|
+
'title-tag': 'Add a unique, descriptive title tag (50-60 characters) to each page',
|
|
241
|
+
'meta-description': 'Add a meta description tag (150-160 characters) to each page',
|
|
242
|
+
'meta-tags': 'Ensure all required meta tags are present (title, description, viewport)',
|
|
243
|
+
'heading-structure': 'Use proper heading hierarchy with one H1 per page',
|
|
244
|
+
'sitemap': 'Generate and submit a sitemap.xml to search engines',
|
|
245
|
+
'robots-txt': 'Create a robots.txt file to control crawler access',
|
|
246
|
+
'structured-data': 'Add JSON-LD structured data for rich snippets',
|
|
247
|
+
'open-graph': 'Add Open Graph tags for better social media sharing',
|
|
248
|
+
'semantic-html': 'Use semantic HTML5 elements (header, nav, main, article, footer)',
|
|
249
|
+
};
|
|
250
|
+
return suggestions[checkName] || 'Review and fix the identified SEO issue';
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Generate SEO improvements
|
|
254
|
+
*/
|
|
255
|
+
generateImprovements(checkResults) {
|
|
256
|
+
const improvements = [];
|
|
257
|
+
// Check for performance-related SEO factors
|
|
258
|
+
improvements.push({
|
|
259
|
+
type: 'seo',
|
|
260
|
+
description: 'Implement Core Web Vitals optimization for better search rankings',
|
|
261
|
+
effort: 'moderate',
|
|
262
|
+
impact: 'high',
|
|
263
|
+
});
|
|
264
|
+
// Mobile optimization
|
|
265
|
+
improvements.push({
|
|
266
|
+
type: 'seo',
|
|
267
|
+
description: 'Ensure mobile-first responsive design for mobile-first indexing',
|
|
268
|
+
effort: 'moderate',
|
|
269
|
+
impact: 'high',
|
|
270
|
+
});
|
|
271
|
+
// HTTPS
|
|
272
|
+
improvements.push({
|
|
273
|
+
type: 'seo',
|
|
274
|
+
description: 'Use HTTPS for security and SEO ranking signal',
|
|
275
|
+
effort: 'quick',
|
|
276
|
+
impact: 'high',
|
|
277
|
+
});
|
|
278
|
+
// Content quality
|
|
279
|
+
improvements.push({
|
|
280
|
+
type: 'seo',
|
|
281
|
+
description: 'Create unique, descriptive page titles and meta descriptions',
|
|
282
|
+
effort: 'quick',
|
|
283
|
+
impact: 'medium',
|
|
284
|
+
});
|
|
285
|
+
// Image optimization
|
|
286
|
+
improvements.push({
|
|
287
|
+
type: 'seo',
|
|
288
|
+
description: 'Add alt text to all images and use descriptive file names',
|
|
289
|
+
effort: 'moderate',
|
|
290
|
+
impact: 'medium',
|
|
291
|
+
});
|
|
292
|
+
// URL structure
|
|
293
|
+
improvements.push({
|
|
294
|
+
type: 'seo',
|
|
295
|
+
description: 'Use clean, descriptive URL structures with keywords',
|
|
296
|
+
effort: 'moderate',
|
|
297
|
+
impact: 'medium',
|
|
298
|
+
});
|
|
299
|
+
// Internal linking
|
|
300
|
+
improvements.push({
|
|
301
|
+
type: 'seo',
|
|
302
|
+
description: 'Improve internal linking structure for better crawlability',
|
|
303
|
+
effort: 'moderate',
|
|
304
|
+
impact: 'medium',
|
|
305
|
+
});
|
|
306
|
+
// Schema markup
|
|
307
|
+
improvements.push({
|
|
308
|
+
type: 'seo',
|
|
309
|
+
description: 'Add schema.org markup for rich snippets in search results',
|
|
310
|
+
effort: 'significant',
|
|
311
|
+
impact: 'high',
|
|
312
|
+
});
|
|
313
|
+
return improvements;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Analyze SEO metadata
|
|
317
|
+
*/
|
|
318
|
+
async analyzeSeoMetadata(projectPath) {
|
|
319
|
+
const metadata = {};
|
|
320
|
+
// Check for common SEO files
|
|
321
|
+
metadata.hasSitemapXml = existsSync(join(projectPath, 'public', 'sitemap.xml')) ||
|
|
322
|
+
existsSync(join(projectPath, 'sitemap.xml'));
|
|
323
|
+
metadata.hasRobotsTxt = existsSync(join(projectPath, 'public', 'robots.txt')) ||
|
|
324
|
+
existsSync(join(projectPath, 'robots.txt'));
|
|
325
|
+
metadata.hasFavicon = existsSync(join(projectPath, 'public', 'favicon.ico')) ||
|
|
326
|
+
existsSync(join(projectPath, 'favicon.ico'));
|
|
327
|
+
// Check for manifest.json (PWA)
|
|
328
|
+
metadata.hasManifest = existsSync(join(projectPath, 'public', 'manifest.json')) ||
|
|
329
|
+
existsSync(join(projectPath, 'manifest.json'));
|
|
330
|
+
// Check for robots.txt in public or root
|
|
331
|
+
const robotsPaths = [
|
|
332
|
+
join(projectPath, 'public', 'robots.txt'),
|
|
333
|
+
join(projectPath, 'robots.txt'),
|
|
334
|
+
];
|
|
335
|
+
for (const robotsPath of robotsPaths) {
|
|
336
|
+
if (existsSync(robotsPath)) {
|
|
337
|
+
try {
|
|
338
|
+
const robotsContent = await readFile(robotsPath, 'utf-8');
|
|
339
|
+
metadata.robotsTxtSize = robotsContent.length;
|
|
340
|
+
metadata.robotsHasSitemap = robotsContent.includes('Sitemap:');
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
catch { }
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return metadata;
|
|
347
|
+
}
|
|
348
|
+
// Individual check methods
|
|
349
|
+
async checkHtmlFile(projectPath) {
|
|
350
|
+
const paths = [
|
|
351
|
+
join(projectPath, 'index.html'),
|
|
352
|
+
join(projectPath, 'public', 'index.html'),
|
|
353
|
+
join(projectPath, 'src', 'index.html'),
|
|
354
|
+
join(projectPath, 'app.html'),
|
|
355
|
+
];
|
|
356
|
+
for (const path of paths) {
|
|
357
|
+
if (existsSync(path)) {
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
async checkMetaTags(projectPath) {
|
|
364
|
+
const found = [];
|
|
365
|
+
let score = 0;
|
|
366
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
367
|
+
if (!htmlContent)
|
|
368
|
+
return { score: 0, found: [] };
|
|
369
|
+
for (const tag of META_TAGS) {
|
|
370
|
+
const regex = new RegExp(`<meta[^>]+name=["']${tag.name}["']|<meta[^>]+property=["']${tag.name}["']`, 'i');
|
|
371
|
+
if (regex.test(htmlContent) || (tag.name === 'title' && /<title[^>]*>.*<\/title>/i.test(htmlContent))) {
|
|
372
|
+
found.push(tag.name);
|
|
373
|
+
score += tag.weight;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return { score, found };
|
|
377
|
+
}
|
|
378
|
+
async checkTitleTag(projectPath) {
|
|
379
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
380
|
+
if (!htmlContent)
|
|
381
|
+
return false;
|
|
382
|
+
const titleMatch = htmlContent.match(/<title[^>]*>(.*?)<\/title>/i);
|
|
383
|
+
if (!titleMatch)
|
|
384
|
+
return false;
|
|
385
|
+
const title = titleMatch[1].trim();
|
|
386
|
+
// Title should be between 30 and 60 characters
|
|
387
|
+
return title.length >= 30 && title.length <= 60;
|
|
388
|
+
}
|
|
389
|
+
async checkMetaDescription(projectPath) {
|
|
390
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
391
|
+
if (!htmlContent)
|
|
392
|
+
return false;
|
|
393
|
+
const descMatch = htmlContent.match(/<meta[^>]+name=["']description["'][^>]*content=["']([^"']+)["']/i);
|
|
394
|
+
if (!descMatch)
|
|
395
|
+
return false;
|
|
396
|
+
const description = descMatch[1].trim();
|
|
397
|
+
// Description should be between 120 and 160 characters
|
|
398
|
+
return description.length >= 120 && description.length <= 160;
|
|
399
|
+
}
|
|
400
|
+
async checkHeadingStructure(projectPath) {
|
|
401
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
402
|
+
if (!htmlContent)
|
|
403
|
+
return { hasH1: false, hasProperHierarchy: false, h1Count: 0, totalHeadings: 0 };
|
|
404
|
+
const h1Matches = htmlContent.match(/<h1[^>]*>/gi);
|
|
405
|
+
const h1Count = h1Matches ? h1Matches.length : 0;
|
|
406
|
+
const allHeadings = htmlContent.match(/<h[1-6][^>]*>/gi);
|
|
407
|
+
const totalHeadings = allHeadings ? allHeadings.length : 0;
|
|
408
|
+
return {
|
|
409
|
+
hasH1: h1Count === 1,
|
|
410
|
+
hasProperHierarchy: h1Count === 1,
|
|
411
|
+
h1Count,
|
|
412
|
+
totalHeadings,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
async checkSitemap(projectPath) {
|
|
416
|
+
const paths = [
|
|
417
|
+
join(projectPath, 'public', 'sitemap.xml'),
|
|
418
|
+
join(projectPath, 'sitemap.xml'),
|
|
419
|
+
join(projectPath, 'out', 'sitemap.xml'),
|
|
420
|
+
join(projectPath, '.next', 'sitemap.xml'),
|
|
421
|
+
];
|
|
422
|
+
for (const path of paths) {
|
|
423
|
+
if (existsSync(path)) {
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
async checkRobotsTxt(projectPath) {
|
|
430
|
+
const paths = [
|
|
431
|
+
join(projectPath, 'public', 'robots.txt'),
|
|
432
|
+
join(projectPath, 'robots.txt'),
|
|
433
|
+
];
|
|
434
|
+
for (const path of paths) {
|
|
435
|
+
if (existsSync(path)) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
async checkStructuredData(projectPath) {
|
|
442
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
443
|
+
if (!htmlContent)
|
|
444
|
+
return false;
|
|
445
|
+
// Check for JSON-LD structured data
|
|
446
|
+
return /<script[^>]+type=["']application\/ld\+json["']/.test(htmlContent);
|
|
447
|
+
}
|
|
448
|
+
async checkOpenGraph(projectPath) {
|
|
449
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
450
|
+
if (!htmlContent)
|
|
451
|
+
return { score: 0, found: 0, total: 6 };
|
|
452
|
+
const ogTags = ['og:title', 'og:description', 'og:image', 'og:type', 'og:url'];
|
|
453
|
+
let found = 0;
|
|
454
|
+
for (const tag of ogTags) {
|
|
455
|
+
if (new RegExp(`<meta[^>]+property=["']${tag}["']`, 'i').test(htmlContent)) {
|
|
456
|
+
found++;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return { score: (found / ogTags.length) * 100, found, total: ogTags.length };
|
|
460
|
+
}
|
|
461
|
+
async checkSemanticHtml(projectPath) {
|
|
462
|
+
const htmlContent = await this.getHtmlContent(projectPath);
|
|
463
|
+
if (!htmlContent)
|
|
464
|
+
return { score: 0, count: 0 };
|
|
465
|
+
const semanticElements = [
|
|
466
|
+
'header', 'nav', 'main', 'article', 'section', 'aside', 'footer',
|
|
467
|
+
'figure', 'figcaption', 'details', 'summary', 'time', 'mark',
|
|
468
|
+
];
|
|
469
|
+
let count = 0;
|
|
470
|
+
for (const element of semanticElements) {
|
|
471
|
+
const regex = new RegExp(`<${element}[\\s>`, 'gi');
|
|
472
|
+
const matches = htmlContent.match(regex);
|
|
473
|
+
if (matches)
|
|
474
|
+
count += matches.length;
|
|
475
|
+
}
|
|
476
|
+
// Score based on having at least 5 semantic elements
|
|
477
|
+
const score = Math.min(100, (count / 5) * 100);
|
|
478
|
+
return { score, count };
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get HTML content from the project
|
|
482
|
+
*/
|
|
483
|
+
async getHtmlContent(projectPath) {
|
|
484
|
+
const paths = [
|
|
485
|
+
join(projectPath, 'index.html'),
|
|
486
|
+
join(projectPath, 'public', 'index.html'),
|
|
487
|
+
join(projectPath, 'src', 'index.html'),
|
|
488
|
+
];
|
|
489
|
+
for (const path of paths) {
|
|
490
|
+
try {
|
|
491
|
+
return await readFile(path, 'utf-8');
|
|
492
|
+
}
|
|
493
|
+
catch { }
|
|
494
|
+
}
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Default SEO analyzer instance
|
|
500
|
+
*/
|
|
501
|
+
export const seoAnalyzer = new SeoAnalyzer();
|
|
502
|
+
//# sourceMappingURL=seo.analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo.analyzer.js","sourceRoot":"","sources":["../../../../src/services/scoring/dimensions/seo.analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAe,MAAM,iCAAiC,CAAC;AAsB5E;;GAEG;AACH,MAAM,SAAS,GAAkB;IAC/B,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE;IACxE,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACpF,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACpF,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAC/E,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE;IAChF,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACjF,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,wBAAwB,EAAE;IAC7F,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACjF,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE;IAC/E,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE;IAC7E,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE;CACvF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,WAAW;IACtB,6BAA6B;IACpB,MAAM,GAA4B;QACzC,SAAS,EAAE,KAAsB;QACjC,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,KAAK;QACxB,mBAAmB,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC;KACvH,CAAC;IAEe,MAAM,CAAS;IAEhC;QACE,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,UAAsB,EAAE,QAAyB;QAClF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,WAAW,EAAE,CAAC,CAAC;QAEtD,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAkB,EAAE,CAAC;QACvC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,qBAAqB;QACrB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAE7D,mCAAmC;QACnC,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAE1C,qCAAqC;QACrC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;QAElD,wBAAwB;QACxB,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC;QAE9D,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,OAAO;YACL,SAAS,EAAE,KAAsB;YACjC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACxC,MAAM,EAAE,IAAI,EAAE,8BAA8B;YAC5C,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;YACzD,MAAM;YACN,YAAY;YACZ,QAAQ,EAAE;gBACR,YAAY,EAAE,YAAY,CAAC,KAAK;gBAChC,WAAW,EAAE,YAAY,CAAC,MAAM;gBAChC,OAAO,EAAE;oBACP,GAAG,QAAQ;oBACX,gBAAgB,EAAE,QAAQ;iBAC3B;aACF;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAAC,WAAmB;QAK/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAE1B,4BAA4B;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;YACvB,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,yBAAyB;SACvC,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;YACvB,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,cAAc,cAAc,CAAC,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,WAAW;SAC9G,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;YACvB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,qCAAqC;SACnD,CAAC,CAAC;QAEH,4BAA4B;QAC5B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE;YAC9B,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,4CAA4C;SAC1D,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE;YAC/B,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,cAAc,CAAC,kBAAkB;YACjE,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,aAAa,cAAc,CAAC,OAAO,QAAQ,cAAc,CAAC,aAAa,QAAQ;SAC7F,CAAC,CAAC;QAEH,uBAAuB;QACvB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;YACrB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,oBAAoB;SAClC,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE;YACxB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,mBAAmB;SACjC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YAC7B,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,mCAAmC;SACjD,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE;YACxB,MAAM,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE;YAC5B,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,eAAe,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,OAAO;SACpE,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE;YAC3B,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,2BAA2B,cAAc,CAAC,KAAK,EAAE;SAC/D,CAAC,CAAC;QAEH,mBAAmB;QACnB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACxD,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC;YACvB,IAAI,MAAM,CAAC,MAAM;gBAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;QAC7C,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,YAA0E;QAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,YAA0E;QAC/F,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,IAAI,QAAQ,GAAoD,QAAQ,CAAC;gBACzE,IAAI,OAAO,GAAG,IAAI,CAAC;gBAEnB,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,WAAW;wBACd,QAAQ,GAAG,UAAU,CAAC;wBACtB,MAAM;oBACR,KAAK,WAAW;wBACd,QAAQ,GAAG,UAAU,CAAC;wBACtB,MAAM;oBACR,KAAK,kBAAkB;wBACrB,QAAQ,GAAG,MAAM,CAAC;wBAClB,MAAM;oBACR,KAAK,WAAW;wBACd,QAAQ,GAAG,MAAM,CAAC;wBAClB,MAAM;oBACR,KAAK,mBAAmB;wBACtB,QAAQ,GAAG,QAAQ,CAAC;wBACpB,MAAM;oBACR,KAAK,SAAS,CAAC;oBACf,KAAK,YAAY;wBACf,QAAQ,GAAG,QAAQ,CAAC;wBACpB,OAAO,GAAG,IAAI,CAAC;wBACf,MAAM;oBACR,KAAK,iBAAiB;wBACpB,QAAQ,GAAG,KAAK,CAAC;wBACjB,MAAM;oBACR,KAAK,YAAY;wBACf,QAAQ,GAAG,QAAQ,CAAC;wBACpB,MAAM;oBACR,KAAK,eAAe;wBAClB,QAAQ,GAAG,KAAK,CAAC;wBACjB,MAAM;gBACV,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC;oBACV,QAAQ;oBACR,QAAQ,EAAE,KAAK;oBACf,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,OAAO;oBACP,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;iBACxC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,SAAiB;QACxC,MAAM,WAAW,GAA2B;YAC1C,WAAW,EAAE,2DAA2D;YACxE,WAAW,EAAE,qEAAqE;YAClF,kBAAkB,EAAE,8DAA8D;YAClF,WAAW,EAAE,0EAA0E;YACvF,mBAAmB,EAAE,mDAAmD;YACxE,SAAS,EAAE,qDAAqD;YAChE,YAAY,EAAE,oDAAoD;YAClE,iBAAiB,EAAE,+CAA+C;YAClE,YAAY,EAAE,qDAAqD;YACnE,eAAe,EAAE,kEAAkE;SACpF,CAAC;QAEF,OAAO,WAAW,CAAC,SAAS,CAAC,IAAI,yCAAyC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,YAA2C;QACtE,MAAM,YAAY,GAAkB,EAAE,CAAC;QAEvC,4CAA4C;QAC5C,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,mEAAmE;YAChF,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,sBAAsB;QACtB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,iEAAiE;YAC9E,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,QAAQ;QACR,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,+CAA+C;YAC5D,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,kBAAkB;QAClB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,8DAA8D;YAC3E,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,qBAAqB;QACrB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,2DAA2D;YACxE,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,gBAAgB;QAChB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,qDAAqD;YAClE,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,mBAAmB;QACnB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,4DAA4D;YACzE,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,gBAAgB;QAChB,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,2DAA2D;YACxE,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAAC,WAAmB;QAClD,MAAM,QAAQ,GAAwB,EAAE,CAAC;QAEzC,6BAA6B;QAC7B,QAAQ,CAAC,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACxD,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;QACpE,QAAQ,CAAC,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;YACvD,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QAClE,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACxD,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;QAEjE,gCAAgC;QAChC,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YACzD,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC;QAErE,yCAAyC;QACzC,MAAM,WAAW,GAAG;YAClB,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC;YACzC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;SAChC,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAC1D,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC;oBAC9C,QAAQ,CAAC,gBAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAC/D,MAAM;gBACR,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,2BAA2B;IAEnB,KAAK,CAAC,aAAa,CAAC,WAAmB;QAC7C,MAAM,KAAK,GAAG;YACZ,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;YAC/B,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC;YACzC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC;YACtC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC;SAC9B,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,WAAmB;QAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAEjD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,sBAAsB,GAAG,CAAC,IAAI,+BAA+B,GAAG,CAAC,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;YAC3G,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;gBACtG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrB,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC;YACtB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,WAAmB;QAC7C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAE/B,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACpE,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAE9B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,+CAA+C;QAC/C,OAAO,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,WAAmB;QACpD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAE/B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACxG,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QAE7B,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,uDAAuD;QACvD,OAAO,WAAW,CAAC,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,MAAM,IAAI,GAAG,CAAC;IAChE,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,WAAmB;QAMrD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAEnG,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzD,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3D,OAAO;YACL,KAAK,EAAE,OAAO,KAAK,CAAC;YACpB,kBAAkB,EAAE,OAAO,KAAK,CAAC;YACjC,OAAO;YACP,aAAa;SACd,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,WAAmB;QAC5C,MAAM,KAAK,GAAG;YACZ,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC;YAC1C,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;YAChC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,aAAa,CAAC;YACvC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC;SAC1C,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAmB;QAC9C,MAAM,KAAK,GAAG;YACZ,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC;YACzC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;SAChC,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,WAAmB;QACnD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAE/B,oCAAoC;QACpC,OAAO,gDAAgD,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5E,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAmB;QAC9C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAE1D,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC/E,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,IAAI,MAAM,CAAC,0BAA0B,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3E,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,WAAmB;QACjD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAEhD,MAAM,gBAAgB,GAAG;YACvB,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ;YAChE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;SAC7D,CAAC;QAEF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,OAAO;gBAAE,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;QACvC,CAAC;QAED,qDAAqD;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAE/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,WAAmB;QAC9C,MAAM,KAAK,GAAG;YACZ,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;YAC/B,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC;YACzC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC;SACvC,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Coverage Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes test coverage for a project by parsing Vitest/Jest coverage reports.
|
|
5
|
+
* Evaluates lines, branches, functions, and statements coverage.
|
|
6
|
+
*
|
|
7
|
+
* @module services/scoring/dimensions/test-coverage
|
|
8
|
+
*/
|
|
9
|
+
import type { DimensionScore, CodeDimension, DimensionAnalyzerConfig } from '../../../core/types/scoring.types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Test coverage analyzer configuration
|
|
12
|
+
*/
|
|
13
|
+
export interface TestCoverageAnalyzerOptions {
|
|
14
|
+
/** Target coverage percentage (default: 80) */
|
|
15
|
+
targetCoverage?: number;
|
|
16
|
+
/** Minimum acceptable coverage (default: 50) */
|
|
17
|
+
minCoverage?: number;
|
|
18
|
+
/** Coverage file paths to check */
|
|
19
|
+
coveragePaths?: string[];
|
|
20
|
+
/** Custom test runner command */
|
|
21
|
+
testCommand?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Test Coverage Analyzer
|
|
25
|
+
*
|
|
26
|
+
* Evaluates test coverage across multiple metrics:
|
|
27
|
+
* - Line coverage
|
|
28
|
+
* - Branch coverage
|
|
29
|
+
* - Function coverage
|
|
30
|
+
* - Statement coverage
|
|
31
|
+
*/
|
|
32
|
+
export declare class TestCoverageAnalyzer {
|
|
33
|
+
/** Analyzer configuration */
|
|
34
|
+
readonly config: DimensionAnalyzerConfig;
|
|
35
|
+
private readonly logger;
|
|
36
|
+
private readonly executor;
|
|
37
|
+
private readonly targetCoverage;
|
|
38
|
+
private readonly minCoverage;
|
|
39
|
+
private readonly coveragePaths;
|
|
40
|
+
private readonly testCommand;
|
|
41
|
+
constructor(options?: TestCoverageAnalyzerOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Get default coverage file paths
|
|
44
|
+
*/
|
|
45
|
+
private getDefaultCoveragePaths;
|
|
46
|
+
/**
|
|
47
|
+
* Get the dimension this analyzer handles
|
|
48
|
+
*/
|
|
49
|
+
getDimension(): CodeDimension;
|
|
50
|
+
/**
|
|
51
|
+
* Get the default weight for this dimension
|
|
52
|
+
*/
|
|
53
|
+
getWeight(): number;
|
|
54
|
+
/**
|
|
55
|
+
* Analyze test coverage for a project
|
|
56
|
+
*
|
|
57
|
+
* @param projectPath - Path to the project root
|
|
58
|
+
* @returns Dimension score with coverage metrics
|
|
59
|
+
*/
|
|
60
|
+
analyze(projectPath: string): Promise<DimensionScore>;
|
|
61
|
+
/**
|
|
62
|
+
* Read coverage report from standard locations
|
|
63
|
+
*/
|
|
64
|
+
private readCoverageReport;
|
|
65
|
+
/**
|
|
66
|
+
* Parse lcov.info format to coverage summary
|
|
67
|
+
*/
|
|
68
|
+
private parseLcovInfo;
|
|
69
|
+
/**
|
|
70
|
+
* Generate coverage report by running tests
|
|
71
|
+
*/
|
|
72
|
+
private generateCoverageReport;
|
|
73
|
+
/**
|
|
74
|
+
* Extract coverage metrics from report
|
|
75
|
+
*/
|
|
76
|
+
private extractCoverageMetrics;
|
|
77
|
+
/**
|
|
78
|
+
* Find files with low or no coverage
|
|
79
|
+
*/
|
|
80
|
+
private findUncoveredFiles;
|
|
81
|
+
/**
|
|
82
|
+
* Recursively scan directory for source files
|
|
83
|
+
*/
|
|
84
|
+
private scanDirectoryForCoverage;
|
|
85
|
+
/**
|
|
86
|
+
* Identify coverage issues
|
|
87
|
+
*/
|
|
88
|
+
private identifyCoverageIssues;
|
|
89
|
+
/**
|
|
90
|
+
* Generate improvement suggestions
|
|
91
|
+
*/
|
|
92
|
+
private generateCoverageImprovements;
|
|
93
|
+
/**
|
|
94
|
+
* Calculate final coverage score
|
|
95
|
+
*/
|
|
96
|
+
private calculateCoverageScore;
|
|
97
|
+
/**
|
|
98
|
+
* Create result when no coverage data is available
|
|
99
|
+
*/
|
|
100
|
+
private createNoCoverageResult;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Default analyzer instance
|
|
104
|
+
*/
|
|
105
|
+
export declare const testCoverageAnalyzer: TestCoverageAnalyzer;
|
|
106
|
+
//# sourceMappingURL=test-coverage.analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-coverage.analyzer.d.ts","sourceRoot":"","sources":["../../../../src/services/scoring/dimensions/test-coverage.analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,cAAc,EAGd,aAAa,EAMb,uBAAuB,EACxB,MAAM,sCAAsC,CAAC;AA6B9C;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;IAC/B,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAKtC;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,GAAE,2BAAgC;IASrD;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAS/B;;OAEG;IACH,YAAY,IAAI,aAAa;IAI7B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;;;;OAKG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyF3D;;OAEG;YACW,kBAAkB;IAyBhC;;OAEG;IACH,OAAO,CAAC,aAAa;IAqDrB;;OAEG;YACW,sBAAsB;IAepC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;OAEG;YACW,kBAAkB;IAsBhC;;OAEG;YACW,wBAAwB;IA0CtC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6E9B;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA6DpC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgC9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAkC/B;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
|