all repos — red-anatomia @ main

red-anatomia

src/cli/commands/comparar.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
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<void> {
  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;
}