@drowlink/aeo-linter-core 0.1.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/dist/__tests__/audit-contract.test.d.ts +2 -0
- package/dist/__tests__/audit-contract.test.d.ts.map +1 -0
- package/dist/__tests__/audit-contract.test.js +120 -0
- package/dist/__tests__/audit-contract.test.js.map +1 -0
- package/dist/__tests__/gatherers.test.d.ts +2 -0
- package/dist/__tests__/gatherers.test.d.ts.map +1 -0
- package/dist/__tests__/gatherers.test.js +139 -0
- package/dist/__tests__/gatherers.test.js.map +1 -0
- package/dist/__tests__/runner.test.d.ts +2 -0
- package/dist/__tests__/runner.test.d.ts.map +1 -0
- package/dist/__tests__/runner.test.js +77 -0
- package/dist/__tests__/runner.test.js.map +1 -0
- package/dist/audits/ai-accessibility/ai-bot-sitemap.d.ts +10 -0
- package/dist/audits/ai-accessibility/ai-bot-sitemap.d.ts.map +1 -0
- package/dist/audits/ai-accessibility/ai-bot-sitemap.js +27 -0
- package/dist/audits/ai-accessibility/ai-bot-sitemap.js.map +1 -0
- package/dist/audits/ai-accessibility/ai-robots-txt.d.ts +10 -0
- package/dist/audits/ai-accessibility/ai-robots-txt.d.ts.map +1 -0
- package/dist/audits/ai-accessibility/ai-robots-txt.js +54 -0
- package/dist/audits/ai-accessibility/ai-robots-txt.js.map +1 -0
- package/dist/audits/ai-accessibility/ai-x-robots-tag.d.ts +10 -0
- package/dist/audits/ai-accessibility/ai-x-robots-tag.d.ts.map +1 -0
- package/dist/audits/ai-accessibility/ai-x-robots-tag.js +36 -0
- package/dist/audits/ai-accessibility/ai-x-robots-tag.js.map +1 -0
- package/dist/audits/audit.d.ts +56 -0
- package/dist/audits/audit.d.ts.map +1 -0
- package/dist/audits/audit.js +86 -0
- package/dist/audits/audit.js.map +1 -0
- package/dist/audits/content-chunking/chunk-token-density.d.ts +10 -0
- package/dist/audits/content-chunking/chunk-token-density.d.ts.map +1 -0
- package/dist/audits/content-chunking/chunk-token-density.js +44 -0
- package/dist/audits/content-chunking/chunk-token-density.js.map +1 -0
- package/dist/audits/content-chunking/heading-hierarchy.d.ts +10 -0
- package/dist/audits/content-chunking/heading-hierarchy.d.ts.map +1 -0
- package/dist/audits/content-chunking/heading-hierarchy.js +54 -0
- package/dist/audits/content-chunking/heading-hierarchy.js.map +1 -0
- package/dist/audits/content-chunking/semantic-containers.d.ts +10 -0
- package/dist/audits/content-chunking/semantic-containers.d.ts.map +1 -0
- package/dist/audits/content-chunking/semantic-containers.js +34 -0
- package/dist/audits/content-chunking/semantic-containers.js.map +1 -0
- package/dist/audits/direct-answer-density/concise-answer-wordcount.d.ts +10 -0
- package/dist/audits/direct-answer-density/concise-answer-wordcount.d.ts.map +1 -0
- package/dist/audits/direct-answer-density/concise-answer-wordcount.js +42 -0
- package/dist/audits/direct-answer-density/concise-answer-wordcount.js.map +1 -0
- package/dist/audits/direct-answer-density/direct-definition-answering.d.ts +10 -0
- package/dist/audits/direct-answer-density/direct-definition-answering.d.ts.map +1 -0
- package/dist/audits/direct-answer-density/direct-definition-answering.js +43 -0
- package/dist/audits/direct-answer-density/direct-definition-answering.js.map +1 -0
- package/dist/audits/direct-answer-density/question-heading-alignment.d.ts +10 -0
- package/dist/audits/direct-answer-density/question-heading-alignment.d.ts.map +1 -0
- package/dist/audits/direct-answer-density/question-heading-alignment.js +35 -0
- package/dist/audits/direct-answer-density/question-heading-alignment.js.map +1 -0
- package/dist/audits/index.d.ts +19 -0
- package/dist/audits/index.d.ts.map +1 -0
- package/dist/audits/index.js +36 -0
- package/dist/audits/index.js.map +1 -0
- package/dist/audits/structured-data/entity-sameas-links.d.ts +10 -0
- package/dist/audits/structured-data/entity-sameas-links.d.ts.map +1 -0
- package/dist/audits/structured-data/entity-sameas-links.js +43 -0
- package/dist/audits/structured-data/entity-sameas-links.js.map +1 -0
- package/dist/audits/structured-data/jsonld-syntax-validity.d.ts +10 -0
- package/dist/audits/structured-data/jsonld-syntax-validity.d.ts.map +1 -0
- package/dist/audits/structured-data/jsonld-syntax-validity.js +43 -0
- package/dist/audits/structured-data/jsonld-syntax-validity.js.map +1 -0
- package/dist/audits/structured-data/rag-schema-presence.d.ts +10 -0
- package/dist/audits/structured-data/rag-schema-presence.d.ts.map +1 -0
- package/dist/audits/structured-data/rag-schema-presence.js +48 -0
- package/dist/audits/structured-data/rag-schema-presence.js.map +1 -0
- package/dist/config/default-config.d.ts +7 -0
- package/dist/config/default-config.d.ts.map +1 -0
- package/dist/config/default-config.js +71 -0
- package/dist/config/default-config.js.map +1 -0
- package/dist/gather/driver/cheerio-driver.d.ts +27 -0
- package/dist/gather/driver/cheerio-driver.d.ts.map +1 -0
- package/dist/gather/driver/cheerio-driver.js +64 -0
- package/dist/gather/driver/cheerio-driver.js.map +1 -0
- package/dist/gather/gatherer.d.ts +12 -0
- package/dist/gather/gatherer.d.ts.map +1 -0
- package/dist/gather/gatherer.js +6 -0
- package/dist/gather/gatherer.js.map +1 -0
- package/dist/gather/gatherers/content-chunks-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/content-chunks-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/content-chunks-gatherer.js +100 -0
- package/dist/gather/gatherers/content-chunks-gatherer.js.map +1 -0
- package/dist/gather/gatherers/direct-answers-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/direct-answers-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/direct-answers-gatherer.js +58 -0
- package/dist/gather/gatherers/direct-answers-gatherer.js.map +1 -0
- package/dist/gather/gatherers/headings-hierarchy-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/headings-hierarchy-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/headings-hierarchy-gatherer.js +60 -0
- package/dist/gather/gatherers/headings-hierarchy-gatherer.js.map +1 -0
- package/dist/gather/gatherers/http-headers-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/http-headers-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/http-headers-gatherer.js +25 -0
- package/dist/gather/gatherers/http-headers-gatherer.js.map +1 -0
- package/dist/gather/gatherers/jsonld-gatherer.d.ts +11 -0
- package/dist/gather/gatherers/jsonld-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/jsonld-gatherer.js +110 -0
- package/dist/gather/gatherers/jsonld-gatherer.js.map +1 -0
- package/dist/gather/gatherers/meta-tags-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/meta-tags-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/meta-tags-gatherer.js +45 -0
- package/dist/gather/gatherers/meta-tags-gatherer.js.map +1 -0
- package/dist/gather/gatherers/robots-txt-gatherer.d.ts +12 -0
- package/dist/gather/gatherers/robots-txt-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/robots-txt-gatherer.js +139 -0
- package/dist/gather/gatherers/robots-txt-gatherer.js.map +1 -0
- package/dist/gather/gatherers/url-gatherer.d.ts +10 -0
- package/dist/gather/gatherers/url-gatherer.d.ts.map +1 -0
- package/dist/gather/gatherers/url-gatherer.js +19 -0
- package/dist/gather/gatherers/url-gatherer.js.map +1 -0
- package/dist/gather/index.d.ts +14 -0
- package/dist/gather/index.d.ts.map +1 -0
- package/dist/gather/index.js +14 -0
- package/dist/gather/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/report/html-reporter.d.ts +11 -0
- package/dist/report/html-reporter.d.ts.map +1 -0
- package/dist/report/html-reporter.js +285 -0
- package/dist/report/html-reporter.js.map +1 -0
- package/dist/report/index.d.ts +6 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +6 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/terminal-reporter.d.ts +8 -0
- package/dist/report/terminal-reporter.d.ts.map +1 -0
- package/dist/report/terminal-reporter.js +50 -0
- package/dist/report/terminal-reporter.js.map +1 -0
- package/dist/runner/aggregator.d.ts +17 -0
- package/dist/runner/aggregator.d.ts.map +1 -0
- package/dist/runner/aggregator.js +59 -0
- package/dist/runner/aggregator.js.map +1 -0
- package/dist/runner/runner.d.ts +29 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +125 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/types/artifacts.d.ts +188 -0
- package/dist/types/artifacts.d.ts.map +1 -0
- package/dist/types/artifacts.js +7 -0
- package/dist/types/artifacts.js.map +1 -0
- package/dist/types/audit.d.ts +122 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +6 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/config.d.ts +74 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/gatherer.d.ts +32 -0
- package/dist/types/gatherer.d.ts.map +1 -0
- package/dist/types/gatherer.js +5 -0
- package/dist/types/gatherer.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generador de reportes HTML interactivos con diseño visual inspirado en Google Lighthouse.
|
|
3
|
+
*/
|
|
4
|
+
export class HtmlReporter {
|
|
5
|
+
/**
|
|
6
|
+
* Genera un documento HTML standalone autocontenido con diseño moderno, gauges de puntuación y tablas interactivas.
|
|
7
|
+
*/
|
|
8
|
+
static generate(report) {
|
|
9
|
+
const getScoreColor = (score) => {
|
|
10
|
+
if (score === null)
|
|
11
|
+
return '#9e9e9e';
|
|
12
|
+
if (score >= 0.9 || score >= 90)
|
|
13
|
+
return '#0cce6b'; // Verde Lighthouse
|
|
14
|
+
if (score >= 0.5 || score >= 50)
|
|
15
|
+
return '#ffa400'; // Naranja Lighthouse
|
|
16
|
+
return '#ff4e42'; // Rojo Lighthouse
|
|
17
|
+
};
|
|
18
|
+
const getScoreCategoryClass = (score) => {
|
|
19
|
+
if (score === null)
|
|
20
|
+
return 'score-na';
|
|
21
|
+
const s = score <= 1 ? score * 100 : score;
|
|
22
|
+
if (s >= 90)
|
|
23
|
+
return 'score-pass';
|
|
24
|
+
if (s >= 50)
|
|
25
|
+
return 'score-average';
|
|
26
|
+
return 'score-fail';
|
|
27
|
+
};
|
|
28
|
+
const renderGauge = (score, title) => {
|
|
29
|
+
const color = getScoreColor(score);
|
|
30
|
+
const strokeDashoffset = 283 - (283 * score) / 100;
|
|
31
|
+
return `
|
|
32
|
+
<div class="gauge-container">
|
|
33
|
+
<svg class="gauge" viewBox="0 0 100 100">
|
|
34
|
+
<circle class="gauge-bg" cx="50" cy="50" r="45" />
|
|
35
|
+
<circle class="gauge-fill" cx="50" cy="50" r="45"
|
|
36
|
+
style="stroke: ${color}; stroke-dasharray: 283; stroke-dashoffset: ${strokeDashoffset};" />
|
|
37
|
+
</svg>
|
|
38
|
+
<div class="gauge-score" style="color: ${color};">${score}</div>
|
|
39
|
+
<div class="gauge-title">${title}</div>
|
|
40
|
+
</div>
|
|
41
|
+
`;
|
|
42
|
+
};
|
|
43
|
+
const renderAuditItem = (audit) => {
|
|
44
|
+
const scoreVal = audit.score !== null ? Math.round(audit.score * 100) : null;
|
|
45
|
+
const badgeClass = getScoreCategoryClass(audit.score);
|
|
46
|
+
const isPass = audit.score !== null && audit.score >= 0.8;
|
|
47
|
+
let detailsHtml = '';
|
|
48
|
+
if (audit.details) {
|
|
49
|
+
if (audit.details.type === 'table') {
|
|
50
|
+
const headings = audit.details.headings;
|
|
51
|
+
const rows = audit.details.items;
|
|
52
|
+
detailsHtml = `
|
|
53
|
+
<div class="table-container">
|
|
54
|
+
<table class="audit-table">
|
|
55
|
+
<thead>
|
|
56
|
+
<tr>${headings.map((h) => `<th>${h.label}</th>`).join('')}</tr>
|
|
57
|
+
</thead>
|
|
58
|
+
<tbody>
|
|
59
|
+
${rows
|
|
60
|
+
.map((row) => `<tr>${headings
|
|
61
|
+
.map((h) => `<td>${row[h.key] !== undefined ? String(row[h.key]) : '-'}</td>`)
|
|
62
|
+
.join('')}</tr>`)
|
|
63
|
+
.join('')}
|
|
64
|
+
</tbody>
|
|
65
|
+
</table>
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
else if (audit.details.type === 'list') {
|
|
70
|
+
detailsHtml = `
|
|
71
|
+
<ul class="audit-list">
|
|
72
|
+
${audit.details.items
|
|
73
|
+
.map((item) => `<li>${typeof item === 'string' ? item : item.text}</li>`)
|
|
74
|
+
.join('')}
|
|
75
|
+
</ul>
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return `
|
|
80
|
+
<details class="audit-card ${isPass ? 'pass' : 'fail'}">
|
|
81
|
+
<summary class="audit-summary">
|
|
82
|
+
<span class="status-indicator ${badgeClass}"></span>
|
|
83
|
+
<div class="audit-info">
|
|
84
|
+
<span class="audit-title">${audit.title}</span>
|
|
85
|
+
${audit.displayValue ? `<span class="audit-display-val">${audit.displayValue}</span>` : ''}
|
|
86
|
+
</div>
|
|
87
|
+
<span class="audit-score-badge ${badgeClass}">${scoreVal !== null ? `${scoreVal}` : 'N/A'}</span>
|
|
88
|
+
</summary>
|
|
89
|
+
<div class="audit-body">
|
|
90
|
+
<p class="audit-desc">${audit.description}</p>
|
|
91
|
+
${audit.explanation ? `<p class="audit-explanation"><strong>Diagnóstico:</strong> ${audit.explanation}</p>` : ''}
|
|
92
|
+
${detailsHtml}
|
|
93
|
+
</div>
|
|
94
|
+
</details>
|
|
95
|
+
`;
|
|
96
|
+
};
|
|
97
|
+
const renderCategory = (cat) => {
|
|
98
|
+
const catScore = cat.score !== null ? Math.round(cat.score * 100) : 0;
|
|
99
|
+
return `
|
|
100
|
+
<section class="category-section" id="cat-${cat.id}">
|
|
101
|
+
<div class="category-header">
|
|
102
|
+
<div class="cat-title-wrap">
|
|
103
|
+
<h2>${cat.title}</h2>
|
|
104
|
+
<p class="cat-desc">${cat.description}</p>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="cat-score-badge ${getScoreCategoryClass(cat.score)}">
|
|
107
|
+
${catScore} / 100
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="audits-list">
|
|
111
|
+
${cat.auditRefs.map((ref) => renderAuditItem(ref.result)).join('')}
|
|
112
|
+
</div>
|
|
113
|
+
</section>
|
|
114
|
+
`;
|
|
115
|
+
};
|
|
116
|
+
return `<!DOCTYPE html>
|
|
117
|
+
<html lang="es">
|
|
118
|
+
<head>
|
|
119
|
+
<meta charset="UTF-8">
|
|
120
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
121
|
+
<title>AEO Linter Report - ${report.url}</title>
|
|
122
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
123
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
124
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
125
|
+
<style>
|
|
126
|
+
:root {
|
|
127
|
+
--bg: #0b0f19;
|
|
128
|
+
--surface: #131b2e;
|
|
129
|
+
--surface-border: #1e293b;
|
|
130
|
+
--text: #f8fafc;
|
|
131
|
+
--text-muted: #94a3b8;
|
|
132
|
+
--pass: #0cce6b;
|
|
133
|
+
--average: #ffa400;
|
|
134
|
+
--fail: #ff4e42;
|
|
135
|
+
--accent: #3b82f6;
|
|
136
|
+
}
|
|
137
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
138
|
+
body {
|
|
139
|
+
font-family: 'Inter', sans-serif;
|
|
140
|
+
background-color: var(--bg);
|
|
141
|
+
color: var(--text);
|
|
142
|
+
line-height: 1.6;
|
|
143
|
+
padding-bottom: 80px;
|
|
144
|
+
}
|
|
145
|
+
.header {
|
|
146
|
+
background: linear-gradient(180deg, #162038 0%, var(--bg) 100%);
|
|
147
|
+
border-bottom: 1px solid var(--surface-border);
|
|
148
|
+
padding: 40px 24px;
|
|
149
|
+
text-align: center;
|
|
150
|
+
}
|
|
151
|
+
.container { max-width: 1000px; margin: 0 auto; padding: 0 20px; }
|
|
152
|
+
.brand { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 2px; color: var(--accent); font-weight: 700; margin-bottom: 8px; }
|
|
153
|
+
h1 { font-size: 2rem; font-weight: 800; margin-bottom: 8px; word-break: break-all; }
|
|
154
|
+
.meta { font-size: 0.9rem; color: var(--text-muted); }
|
|
155
|
+
|
|
156
|
+
/* Gauges Grid */
|
|
157
|
+
.gauges-grid {
|
|
158
|
+
display: grid;
|
|
159
|
+
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
|
160
|
+
gap: 20px;
|
|
161
|
+
margin: 40px 0;
|
|
162
|
+
}
|
|
163
|
+
.gauge-container {
|
|
164
|
+
background: var(--surface);
|
|
165
|
+
border: 1px solid var(--surface-border);
|
|
166
|
+
border-radius: 16px;
|
|
167
|
+
padding: 24px 16px;
|
|
168
|
+
text-align: center;
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
align-items: center;
|
|
172
|
+
transition: transform 0.2s ease;
|
|
173
|
+
}
|
|
174
|
+
.gauge-container:hover { transform: translateY(-4px); }
|
|
175
|
+
.gauge { width: 100px; height: 100px; transform: rotate(-90deg); }
|
|
176
|
+
.gauge-bg { fill: none; stroke: #1e293b; stroke-width: 8; }
|
|
177
|
+
.gauge-fill { fill: none; stroke-width: 8; stroke-linecap: round; transition: stroke-dashoffset 0.8s ease; }
|
|
178
|
+
.gauge-score { font-size: 1.8rem; font-weight: 800; margin-top: -70px; margin-bottom: 35px; }
|
|
179
|
+
.gauge-title { font-size: 0.85rem; font-weight: 600; color: var(--text); }
|
|
180
|
+
|
|
181
|
+
/* Category Section */
|
|
182
|
+
.category-section {
|
|
183
|
+
background: var(--surface);
|
|
184
|
+
border: 1px solid var(--surface-border);
|
|
185
|
+
border-radius: 16px;
|
|
186
|
+
padding: 28px;
|
|
187
|
+
margin-bottom: 32px;
|
|
188
|
+
}
|
|
189
|
+
.category-header {
|
|
190
|
+
display: flex;
|
|
191
|
+
justify-content: space-between;
|
|
192
|
+
align-items: flex-start;
|
|
193
|
+
border-bottom: 1px solid var(--surface-border);
|
|
194
|
+
padding-bottom: 20px;
|
|
195
|
+
margin-bottom: 20px;
|
|
196
|
+
}
|
|
197
|
+
.category-header h2 { font-size: 1.4rem; font-weight: 700; margin-bottom: 4px; }
|
|
198
|
+
.cat-desc { font-size: 0.9rem; color: var(--text-muted); max-width: 700px; }
|
|
199
|
+
.cat-score-badge {
|
|
200
|
+
font-size: 1.1rem;
|
|
201
|
+
font-weight: 700;
|
|
202
|
+
padding: 6px 14px;
|
|
203
|
+
border-radius: 20px;
|
|
204
|
+
}
|
|
205
|
+
.score-pass { background: rgba(12, 206, 107, 0.15); color: var(--pass); }
|
|
206
|
+
.score-average { background: rgba(255, 164, 0, 0.15); color: var(--average); }
|
|
207
|
+
.score-fail { background: rgba(255, 78, 66, 0.15); color: var(--fail); }
|
|
208
|
+
.score-na { background: rgba(148, 163, 184, 0.15); color: var(--text-muted); }
|
|
209
|
+
|
|
210
|
+
/* Audits */
|
|
211
|
+
.audits-list { display: flex; flex-direction: column; gap: 12px; }
|
|
212
|
+
.audit-card {
|
|
213
|
+
border: 1px solid var(--surface-border);
|
|
214
|
+
border-radius: 10px;
|
|
215
|
+
background: #0e1626;
|
|
216
|
+
overflow: hidden;
|
|
217
|
+
}
|
|
218
|
+
.audit-summary {
|
|
219
|
+
padding: 14px 18px;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
gap: 14px;
|
|
224
|
+
list-style: none;
|
|
225
|
+
user-select: none;
|
|
226
|
+
}
|
|
227
|
+
.audit-summary::-webkit-details-marker { display: none; }
|
|
228
|
+
.status-indicator {
|
|
229
|
+
width: 10px;
|
|
230
|
+
height: 10px;
|
|
231
|
+
border-radius: 50%;
|
|
232
|
+
flex-shrink: 0;
|
|
233
|
+
}
|
|
234
|
+
.status-indicator.score-pass { background: var(--pass); }
|
|
235
|
+
.status-indicator.score-average { background: var(--average); }
|
|
236
|
+
.status-indicator.score-fail { background: var(--fail); }
|
|
237
|
+
.status-indicator.score-na { background: var(--text-muted); }
|
|
238
|
+
|
|
239
|
+
.audit-info { flex: 1; display: flex; justify-content: space-between; align-items: center; }
|
|
240
|
+
.audit-title { font-weight: 600; font-size: 0.95rem; }
|
|
241
|
+
.audit-display-val { font-size: 0.85rem; color: var(--text-muted); margin-left: 12px; }
|
|
242
|
+
.audit-score-badge { font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; font-weight: 700; padding: 2px 8px; border-radius: 6px; }
|
|
243
|
+
|
|
244
|
+
.audit-body {
|
|
245
|
+
padding: 16px 20px;
|
|
246
|
+
border-top: 1px solid var(--surface-border);
|
|
247
|
+
background: #090e1a;
|
|
248
|
+
font-size: 0.9rem;
|
|
249
|
+
}
|
|
250
|
+
.audit-desc { color: var(--text-muted); margin-bottom: 12px; }
|
|
251
|
+
.audit-explanation { margin-bottom: 16px; color: #cbd5e1; }
|
|
252
|
+
|
|
253
|
+
/* Tables */
|
|
254
|
+
.table-container { overflow-x: auto; margin-top: 12px; }
|
|
255
|
+
.audit-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
|
|
256
|
+
.audit-table th { background: #131d31; color: var(--text-muted); text-align: left; padding: 8px 12px; border: 1px solid var(--surface-border); }
|
|
257
|
+
.audit-table td { padding: 8px 12px; border: 1px solid var(--surface-border); font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; }
|
|
258
|
+
.audit-list { margin-left: 20px; color: #cbd5e1; }
|
|
259
|
+
.audit-list li { margin-bottom: 6px; }
|
|
260
|
+
</style>
|
|
261
|
+
</head>
|
|
262
|
+
<body>
|
|
263
|
+
<header class="header">
|
|
264
|
+
<div class="container">
|
|
265
|
+
<div class="brand">AEO Linter Engine • Lighthouse Architecture</div>
|
|
266
|
+
<h1>${report.url}</h1>
|
|
267
|
+
<p class="meta">Analizado el ${new Date(report.fetchTime).toLocaleString()} | AEO v${report.aeoVersion}</p>
|
|
268
|
+
</div>
|
|
269
|
+
</header>
|
|
270
|
+
|
|
271
|
+
<main class="container">
|
|
272
|
+
<div class="gauges-grid">
|
|
273
|
+
${renderGauge(report.overallScore, 'Score General AEO')}
|
|
274
|
+
${Object.values(report.categories)
|
|
275
|
+
.map((cat) => renderGauge(cat.score !== null ? Math.round(cat.score * 100) : 0, cat.title))
|
|
276
|
+
.join('')}
|
|
277
|
+
</div>
|
|
278
|
+
|
|
279
|
+
${Object.values(report.categories).map((cat) => renderCategory(cat)).join('')}
|
|
280
|
+
</main>
|
|
281
|
+
</body>
|
|
282
|
+
</html>`;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=html-reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-reporter.js","sourceRoot":"","sources":["../../src/report/html-reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Formateador de resultados para la salida estándar en terminal (CLI).
|
|
3
|
+
*/
|
|
4
|
+
import type { AeoReportResult } from '../types/index.js';
|
|
5
|
+
export declare class TerminalReporter {
|
|
6
|
+
static generate(report: AeoReportResult): string;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=terminal-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-reporter.d.ts","sourceRoot":"","sources":["../../src/report/terminal-reporter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,qBAAa,gBAAgB;WACb,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;CA+CxD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Formateador de resultados para la salida estándar en terminal (CLI).
|
|
3
|
+
*/
|
|
4
|
+
export class TerminalReporter {
|
|
5
|
+
static generate(report) {
|
|
6
|
+
const lines = [];
|
|
7
|
+
const formatScore = (score) => {
|
|
8
|
+
if (score === null)
|
|
9
|
+
return '\x1b[90mN/A\x1b[0m';
|
|
10
|
+
const s = score <= 1 ? Math.round(score * 100) : Math.round(score);
|
|
11
|
+
if (s >= 90)
|
|
12
|
+
return `\x1b[32m${s}\x1b[0m`;
|
|
13
|
+
if (s >= 50)
|
|
14
|
+
return `\x1b[33m${s}\x1b[0m`;
|
|
15
|
+
return `\x1b[31m${s}\x1b[0m`;
|
|
16
|
+
};
|
|
17
|
+
lines.push('');
|
|
18
|
+
lines.push('\x1b[1m\x1b[36m============================================================\x1b[0m');
|
|
19
|
+
lines.push(`\x1b[1m AEO Linter Report - Answer Engine Optimization\x1b[0m`);
|
|
20
|
+
lines.push(` URL: \x1b[4m${report.url}\x1b[0m`);
|
|
21
|
+
lines.push(` Fecha: ${new Date(report.fetchTime).toLocaleString()}`);
|
|
22
|
+
lines.push('\x1b[1m\x1b[36m============================================================\x1b[0m');
|
|
23
|
+
lines.push('');
|
|
24
|
+
lines.push(`\x1b[1m Score General AEO: ${formatScore(report.overallScore)} / 100\x1b[0m`);
|
|
25
|
+
lines.push('');
|
|
26
|
+
for (const cat of Object.values(report.categories)) {
|
|
27
|
+
const catScore = cat.score !== null ? Math.round(cat.score * 100) : null;
|
|
28
|
+
lines.push(`\x1b[1m------------------------------------------------------------\x1b[0m`);
|
|
29
|
+
lines.push(`\x1b[1m\x1b[35m[ ${cat.title} ]\x1b[0m - Score: ${formatScore(catScore)} / 100`);
|
|
30
|
+
lines.push(` \x1b[90m${cat.description}\x1b[0m`);
|
|
31
|
+
lines.push('');
|
|
32
|
+
for (const ref of cat.auditRefs) {
|
|
33
|
+
const audit = ref.result;
|
|
34
|
+
const icon = audit.score !== null && audit.score >= 0.8 ? '\x1b[32m✔\x1b[0m' : '\x1b[31m✖\x1b[0m';
|
|
35
|
+
lines.push(` ${icon} \x1b[1m${audit.title}\x1b[0m (${formatScore(audit.score)})`);
|
|
36
|
+
if (audit.displayValue) {
|
|
37
|
+
lines.push(` \x1b[90m↳ ${audit.displayValue}\x1b[0m`);
|
|
38
|
+
}
|
|
39
|
+
if (audit.explanation) {
|
|
40
|
+
lines.push(` \x1b[33m! ${audit.explanation}\x1b[0m`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
lines.push('');
|
|
44
|
+
}
|
|
45
|
+
lines.push('\x1b[1m\x1b[36m============================================================\x1b[0m');
|
|
46
|
+
lines.push('');
|
|
47
|
+
return lines.join('\n');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=terminal-reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-reporter.js","sourceRoot":"","sources":["../../src/report/terminal-reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agregador ponderado de resultados de auditorías en categorías y cálculo del score general AEO.
|
|
3
|
+
* Sigue fielmente la fórmula de ponderación de Google Lighthouse.
|
|
4
|
+
*/
|
|
5
|
+
import type { LinterConfig, AuditResult, AeoReportResult } from '../types/index.js';
|
|
6
|
+
export declare class Aggregator {
|
|
7
|
+
/**
|
|
8
|
+
* Agrupa los resultados de auditorías en sus categorías y calcula puntuaciones ponderadas.
|
|
9
|
+
*/
|
|
10
|
+
static aggregate(options: {
|
|
11
|
+
url: string;
|
|
12
|
+
config: LinterConfig;
|
|
13
|
+
auditResults: Record<string, AuditResult>;
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
}): AeoReportResult;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../../src/runner/aggregator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAEX,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACrB;;OAEG;WACW,SAAS,CAAC,OAAO,EAAE;QAC/B,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,YAAY,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,eAAe;CA2DpB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agregador ponderado de resultados de auditorías en categorías y cálculo del score general AEO.
|
|
3
|
+
* Sigue fielmente la fórmula de ponderación de Google Lighthouse.
|
|
4
|
+
*/
|
|
5
|
+
export class Aggregator {
|
|
6
|
+
/**
|
|
7
|
+
* Agrupa los resultados de auditorías en sus categorías y calcula puntuaciones ponderadas.
|
|
8
|
+
*/
|
|
9
|
+
static aggregate(options) {
|
|
10
|
+
const { url, config, auditResults, userAgent = 'AEO Linter Engine' } = options;
|
|
11
|
+
const categories = {};
|
|
12
|
+
let totalGlobalWeightedScore = 0;
|
|
13
|
+
let totalGlobalWeight = 0;
|
|
14
|
+
for (const [catId, catConfig] of Object.entries(config.categories)) {
|
|
15
|
+
let catWeightedSum = 0;
|
|
16
|
+
let catTotalWeight = 0;
|
|
17
|
+
const evaluatedAuditRefs = [];
|
|
18
|
+
for (const auditRef of catConfig.auditRefs) {
|
|
19
|
+
const result = auditResults[auditRef.id];
|
|
20
|
+
if (!result)
|
|
21
|
+
continue;
|
|
22
|
+
evaluatedAuditRefs.push({
|
|
23
|
+
...auditRef,
|
|
24
|
+
result,
|
|
25
|
+
});
|
|
26
|
+
// Solo sumamos al score si tiene un puntaje numérico (ignora notApplicable / informative)
|
|
27
|
+
if (typeof result.score === 'number') {
|
|
28
|
+
catWeightedSum += result.score * auditRef.weight;
|
|
29
|
+
catTotalWeight += auditRef.weight;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const catScore = catTotalWeight > 0 ? Number((catWeightedSum / catTotalWeight).toFixed(2)) : null;
|
|
33
|
+
categories[catId] = {
|
|
34
|
+
id: catId,
|
|
35
|
+
title: catConfig.title,
|
|
36
|
+
description: catConfig.description,
|
|
37
|
+
score: catScore,
|
|
38
|
+
auditRefs: evaluatedAuditRefs,
|
|
39
|
+
};
|
|
40
|
+
const globalWeight = catConfig.weight ?? 1;
|
|
41
|
+
if (catScore !== null) {
|
|
42
|
+
totalGlobalWeightedScore += catScore * globalWeight;
|
|
43
|
+
totalGlobalWeight += globalWeight;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const rawOverall = totalGlobalWeight > 0 ? (totalGlobalWeightedScore / totalGlobalWeight) * 100 : 0;
|
|
47
|
+
const overallScore = Math.round(rawOverall);
|
|
48
|
+
return {
|
|
49
|
+
url,
|
|
50
|
+
fetchTime: new Date().toISOString(),
|
|
51
|
+
aeoVersion: '0.1.0',
|
|
52
|
+
userAgent,
|
|
53
|
+
overallScore,
|
|
54
|
+
categories,
|
|
55
|
+
audits: auditResults,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.js","sourceRoot":"","sources":["../../src/runner/aggregator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,OAAO,UAAU;IACrB;;OAEG;IACI,MAAM,CAAC,SAAS,CAAC,OAKvB;QACC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,GAAG,mBAAmB,EAAE,GAAG,OAAO,CAAC;QAC/E,MAAM,UAAU,GAAmC,EAAE,CAAC;QAEtD,IAAI,wBAAwB,GAAG,CAAC,CAAC;QACjC,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAE1B,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACnE,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,cAAc,GAAG,CAAC,CAAC;YAEvB,MAAM,kBAAkB,GAAgC,EAAE,CAAC;YAE3D,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACzC,IAAI,CAAC,MAAM;oBAAE,SAAS;gBAEtB,kBAAkB,CAAC,IAAI,CAAC;oBACtB,GAAG,QAAQ;oBACX,MAAM;iBACP,CAAC,CAAC;gBAEH,0FAA0F;gBAC1F,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACrC,cAAc,IAAI,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;oBACjD,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,GAAG,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAElG,UAAU,CAAC,KAAK,CAAC,GAAG;gBAClB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,WAAW,EAAE,SAAS,CAAC,WAAW;gBAClC,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,kBAAkB;aAC9B,CAAC;YAEF,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC;YAC3C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,wBAAwB,IAAI,QAAQ,GAAG,YAAY,CAAC;gBACpD,iBAAiB,IAAI,YAAY,CAAC;YACpC,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACpG,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAE5C,OAAO;YACL,GAAG;YACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,OAAO;YACnB,SAAS;YACT,YAAY;YACZ,UAAU;YACV,MAAM,EAAE,YAAY;SACrB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runner principal de AEO Linter. Orquesta el pipeline de 3 fases:
|
|
3
|
+
* 1. Gather (recolección de artefactos)
|
|
4
|
+
* 2. Audit (ejecución de auditorías puras)
|
|
5
|
+
* 3. Aggregate (agregación y cálculo de scores)
|
|
6
|
+
*/
|
|
7
|
+
import type { Driver, Artifacts, AuditResult, LinterConfig, AeoReportResult } from '../types/index.js';
|
|
8
|
+
export interface RunnerOptions {
|
|
9
|
+
config?: LinterConfig;
|
|
10
|
+
driver?: Driver;
|
|
11
|
+
fetchFn?: typeof fetch;
|
|
12
|
+
userAgent?: string;
|
|
13
|
+
onProgress?: (phase: 'gather' | 'audit' | 'aggregate', message: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare class Runner {
|
|
16
|
+
/**
|
|
17
|
+
* Ejecuta el pipeline completo de auditoría AEO para una URL o HTML provisto
|
|
18
|
+
*/
|
|
19
|
+
static run(targetUrl: string, options?: RunnerOptions): Promise<AeoReportResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Ejecuta los Gatherers para construir el objeto global Artifacts
|
|
22
|
+
*/
|
|
23
|
+
static gatherArtifacts(url: string, driver: Driver): Promise<Artifacts>;
|
|
24
|
+
/**
|
|
25
|
+
* Ejecuta las auditorías declaradas en la configuración
|
|
26
|
+
*/
|
|
27
|
+
static runAudits(artifacts: Artifacts, config: LinterConfig): Promise<Record<string, AuditResult>>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAiBvG,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjF;AAED,qBAAa,MAAM;IACjB;;OAEG;WACiB,GAAG,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,eAAe,CAAC;IAgC3B;;OAEG;WACiB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IA4CpF;;OAEG;WACiB,SAAS,CAC3B,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CA0CxC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runner principal de AEO Linter. Orquesta el pipeline de 3 fases:
|
|
3
|
+
* 1. Gather (recolección de artefactos)
|
|
4
|
+
* 2. Audit (ejecución de auditorías puras)
|
|
5
|
+
* 3. Aggregate (agregación y cálculo de scores)
|
|
6
|
+
*/
|
|
7
|
+
import { CheerioDriver } from '../gather/driver/cheerio-driver.js';
|
|
8
|
+
import { defaultConfig } from '../config/default-config.js';
|
|
9
|
+
// Gatherers
|
|
10
|
+
import { URLGatherer } from '../gather/gatherers/url-gatherer.js';
|
|
11
|
+
import { RobotsTxtGatherer } from '../gather/gatherers/robots-txt-gatherer.js';
|
|
12
|
+
import { HttpHeadersGatherer } from '../gather/gatherers/http-headers-gatherer.js';
|
|
13
|
+
import { JSONLDGatherer } from '../gather/gatherers/jsonld-gatherer.js';
|
|
14
|
+
import { MetaTagsGatherer } from '../gather/gatherers/meta-tags-gatherer.js';
|
|
15
|
+
import { HeadingsHierarchyGatherer } from '../gather/gatherers/headings-hierarchy-gatherer.js';
|
|
16
|
+
import { ContentChunksGatherer } from '../gather/gatherers/content-chunks-gatherer.js';
|
|
17
|
+
import { DirectAnswersGatherer } from '../gather/gatherers/direct-answers-gatherer.js';
|
|
18
|
+
// Audits & Aggregator
|
|
19
|
+
import { auditRegistry } from '../audits/index.js';
|
|
20
|
+
import { Aggregator } from './aggregator.js';
|
|
21
|
+
export class Runner {
|
|
22
|
+
/**
|
|
23
|
+
* Ejecuta el pipeline completo de auditoría AEO para una URL o HTML provisto
|
|
24
|
+
*/
|
|
25
|
+
static async run(targetUrl, options = {}) {
|
|
26
|
+
const config = options.config || defaultConfig;
|
|
27
|
+
const progress = options.onProgress || (() => { });
|
|
28
|
+
// 1. Inicializar Driver si no fue provisto
|
|
29
|
+
progress('gather', `Conectando y cargando ${targetUrl}...`);
|
|
30
|
+
const driver = options.driver ||
|
|
31
|
+
(await CheerioDriver.createFromUrl(targetUrl, options.fetchFn, {
|
|
32
|
+
userAgent: options.userAgent,
|
|
33
|
+
}));
|
|
34
|
+
// 2. Fase de Gatherers
|
|
35
|
+
progress('gather', 'Extrayendo artefactos crudos del DOM y red...');
|
|
36
|
+
const artifacts = await this.gatherArtifacts(targetUrl, driver);
|
|
37
|
+
// 3. Fase de Auditorías
|
|
38
|
+
progress('audit', 'Ejecutando auditorías independientes...');
|
|
39
|
+
const auditResults = await this.runAudits(artifacts, config);
|
|
40
|
+
// 4. Fase de Agregación
|
|
41
|
+
progress('aggregate', 'Calculando ponderaciones y score global AEO...');
|
|
42
|
+
const report = Aggregator.aggregate({
|
|
43
|
+
url: artifacts.URL.finalUrl || targetUrl,
|
|
44
|
+
config,
|
|
45
|
+
auditResults,
|
|
46
|
+
userAgent: options.userAgent,
|
|
47
|
+
});
|
|
48
|
+
return report;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Ejecuta los Gatherers para construir el objeto global Artifacts
|
|
52
|
+
*/
|
|
53
|
+
static async gatherArtifacts(url, driver) {
|
|
54
|
+
const context = { url, driver };
|
|
55
|
+
const urlGatherer = new URLGatherer();
|
|
56
|
+
const robotsGatherer = new RobotsTxtGatherer();
|
|
57
|
+
const headersGatherer = new HttpHeadersGatherer();
|
|
58
|
+
const jsonldGatherer = new JSONLDGatherer();
|
|
59
|
+
const metaGatherer = new MetaTagsGatherer();
|
|
60
|
+
const headingsGatherer = new HeadingsHierarchyGatherer();
|
|
61
|
+
const contentGatherer = new ContentChunksGatherer();
|
|
62
|
+
const directAnswersGatherer = new DirectAnswersGatherer();
|
|
63
|
+
const [urlArtifact, robotsArtifact, headersArtifact, jsonldArtifact, metaArtifact, headingsArtifact, contentArtifact, directAnswersArtifact,] = await Promise.all([
|
|
64
|
+
urlGatherer.getArtifact(context),
|
|
65
|
+
robotsGatherer.getArtifact(context),
|
|
66
|
+
headersGatherer.getArtifact(context),
|
|
67
|
+
jsonldGatherer.getArtifact(context),
|
|
68
|
+
metaGatherer.getArtifact(context),
|
|
69
|
+
headingsGatherer.getArtifact(context),
|
|
70
|
+
contentGatherer.getArtifact(context),
|
|
71
|
+
directAnswersGatherer.getArtifact(context),
|
|
72
|
+
]);
|
|
73
|
+
return {
|
|
74
|
+
URL: urlArtifact,
|
|
75
|
+
RobotsTxt: robotsArtifact,
|
|
76
|
+
HttpHeaders: headersArtifact,
|
|
77
|
+
JSONLD: jsonldArtifact,
|
|
78
|
+
MetaTags: metaArtifact,
|
|
79
|
+
HeadingsHierarchy: headingsArtifact,
|
|
80
|
+
ContentChunks: contentArtifact,
|
|
81
|
+
DirectAnswers: directAnswersArtifact,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Ejecuta las auditorías declaradas en la configuración
|
|
86
|
+
*/
|
|
87
|
+
static async runAudits(artifacts, config) {
|
|
88
|
+
const auditResults = {};
|
|
89
|
+
// Obtener lista única de IDs de auditoría a partir de la configuración
|
|
90
|
+
const auditIdsToRun = new Set();
|
|
91
|
+
if (config.audits) {
|
|
92
|
+
for (const a of config.audits) {
|
|
93
|
+
auditIdsToRun.add(typeof a === 'string' ? a : a.id);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const category of Object.values(config.categories)) {
|
|
97
|
+
for (const ref of category.auditRefs) {
|
|
98
|
+
auditIdsToRun.add(ref.id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const auditId of auditIdsToRun) {
|
|
102
|
+
const AuditClass = auditRegistry[auditId];
|
|
103
|
+
if (!AuditClass) {
|
|
104
|
+
console.warn(`[AEO Runner] Auditoría no registrada: ${auditId}`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const result = await AuditClass.audit(artifacts);
|
|
109
|
+
auditResults[auditId] = result;
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
auditResults[auditId] = {
|
|
113
|
+
id: auditId,
|
|
114
|
+
score: 0,
|
|
115
|
+
scoreDisplayMode: 'error',
|
|
116
|
+
title: `Error al ejecutar auditoría ${auditId}`,
|
|
117
|
+
description: '',
|
|
118
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return auditResults;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"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"}
|