import chalk from 'chalk'; import ora from 'ora'; import Table from 'cli-table3'; import { analisarSite } from '../../core/pipeline.js'; import type { Report } from '../../core/types.js'; export interface OpcoesComparar { completo?: boolean; } export async function comandoComparar( urlA: string, urlB: string, opcoes: OpcoesComparar, ): Promise { const modo = opcoes.completo ? 'completo' : 'rapido'; const spinner = ora({ text: 'analisando os dois sites…', stream: process.stderr }).start(); const [a, b] = await Promise.all([ analisarSite(urlA, { modo }), analisarSite(urlB, { modo }), ]); spinner.stop(); const categorias = [ 'CMS', 'Web frameworks', 'JavaScript frameworks', 'UI frameworks', 'Ecommerce', 'Web servers', 'CDN', 'PaaS', 'Analytics', ]; const tabela = new Table({ head: [chalk.bold('Categoria'), chalk.bold(dominio(a)), chalk.bold(dominio(b))], style: { head: [], border: [] }, wordWrap: true, colWidths: [22, 27, 27], }); for (const cat of categorias) { const va = tecnologiasDe(a, cat); const vb = tecnologiasDe(b, cat); if (!va && !vb) continue; tabela.push([cat, va ?? chalk.dim('—'), vb ?? chalk.dim('—')]); } const saida = [ chalk.bold.red('COMPARAÇÃO DE STACKS'), `${chalk.dim('A:')} ${a.alvo.urlFinal}`, `${chalk.dim('B:')} ${b.alvo.urlFinal}`, '', tabela.toString(), ].join('\n'); process.stdout.write(saida + '\n'); } function dominio(rep: Report): string { try { return new URL(rep.alvo.urlFinal).hostname; } catch { return rep.alvo.urlSolicitada; } } function tecnologiasDe(rep: Report, categoria: string): string | undefined { const nomes = rep.deteccoes .filter((d) => d.categorias.includes(categoria)) .map((d) => (d.versao ? `${d.nome} v${d.versao}` : d.nome)); return nomes.length ? nomes.join(', ') : undefined; }