feat(docs): added multi-doc command

This commit is contained in:
jb
2026-04-17 14:27:59 -03:00
parent 4a306fa042
commit 017d6d2d5b
+221 -19
View File
@@ -2,14 +2,203 @@
var path = require('path'); var path = require('path');
var fs = require('fs'); var fs = require('fs');
var os = require('os');
var { exec } = require('child_process'); var { exec } = require('child_process');
var { getPlatformDir } = require('../utils/platform'); var { getPlatformDir } = require('../utils/platform');
var DOCS = {
desktop: { label: 'Desktop (Java)', subpath: path.join('docs', 'java', 'index.html') },
mobile: { label: 'Mobile (React Native)', subpath: path.join('docs', 'react-native', 'index.html') },
};
function openUrl(filePath) {
var cmd = process.platform === 'win32'
? 'start "" "' + filePath + '"'
: 'xdg-open "' + filePath + '"';
exec(cmd, function (err) {
if (err) {
console.error('Erro ao abrir o navegador: ' + err.message);
console.error('Abra manualmente: ' + filePath);
process.exit(1);
}
});
}
function buildSelectionPage(javaPath, reactNativePath) {
return `<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vitruvio Documentação</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background: #fdf5f2;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #2d2d2d;
}
.card {
background: #fff;
border-radius: 20px;
padding: 48px 56px;
max-width: 540px;
width: 100%;
box-shadow: 0 8px 40px rgba(247, 130, 89, 0.12);
text-align: center;
}
.logo {
width: 56px;
height: 56px;
background: #F78259;
border-radius: 14px;
display: inline-flex;
align-items: center;
justify-content: center;
margin-bottom: 28px;
}
.logo svg { width: 32px; height: 32px; fill: #fff; }
h1 {
font-size: 1.6rem;
font-weight: 700;
color: #1a1a1a;
margin-bottom: 10px;
}
p.subtitle {
font-size: 0.97rem;
color: #666;
margin-bottom: 36px;
line-height: 1.55;
}
.buttons {
display: flex;
flex-direction: column;
gap: 14px;
}
.btn {
display: flex;
align-items: center;
gap: 14px;
padding: 18px 22px;
border-radius: 12px;
text-decoration: none;
font-weight: 600;
font-size: 1rem;
transition: transform 0.15s, box-shadow 0.15s;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(247, 130, 89, 0.25);
}
.btn-primary {
background: #F78259;
color: #fff;
}
.btn-secondary {
background: #fff3ef;
color: #c05a30;
border: 2px solid #f7c2ad;
}
.btn-icon {
width: 38px;
height: 38px;
border-radius: 8px;
background: rgba(255,255,255,0.25);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.btn-secondary .btn-icon {
background: rgba(247, 130, 89, 0.12);
}
.btn-icon svg { width: 20px; height: 20px; }
.btn-primary .btn-icon svg { fill: #fff; }
.btn-secondary .btn-icon svg { fill: #F78259; }
.btn-text { text-align: left; }
.btn-text small {
display: block;
font-weight: 400;
font-size: 0.8rem;
opacity: 0.75;
margin-top: 2px;
}
footer {
margin-top: 32px;
font-size: 0.78rem;
color: #bbb;
}
</style>
</head>
<body>
<div class="card">
<div class="logo">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7v10l10 5 10-5V7L12 2zm0 2.18L20 8.5v7L12 19.82 4 15.5v-7l8-4.32z"/>
</svg>
</div>
<h1>Documentação Vitruvio</h1>
<p class="subtitle">Selecione abaixo qual documentação você deseja consultar.</p>
<div class="buttons">
<a class="btn btn-primary" href="file://${javaPath}">
<span class="btn-icon">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M20 3H4a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm-1 16H5V5h14v14zM7 12h2v5H7zm4-3h2v8h-2zm4-3h2v11h-2z"/>
</svg>
</span>
<span class="btn-text">
Desktop (Java)
<small>API do módulo desktop / back-end</small>
</span>
</a>
<a class="btn btn-secondary" href="file://${reactNativePath}">
<span class="btn-icon">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M17 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15H7V5h10v12zm-4 3h-2v-1h2v1z"/>
</svg>
</span>
<span class="btn-text">
Mobile (React Native)
<small>API do módulo mobile</small>
</span>
</a>
</div>
<footer>Vitruvio CLI &mdash; documentação local</footer>
</div>
</body>
</html>`;
}
function register(program) { function register(program) {
program program
.command('docs') .command('docs [tipo]')
.description('Abre a documentação Java do Vitruvio no navegador padrão') .description('Abre a documentação do Vitruvio no navegador (tipo: desktop | mobile)')
.action(function () { .action(function (tipo) {
var platformDir; var platformDir;
try { try {
platformDir = getPlatformDir(); platformDir = getPlatformDir();
@@ -18,32 +207,45 @@ function register(program) {
process.exit(1); process.exit(1);
} }
var docsPath = path.join(platformDir, 'docs', 'java', 'index.html'); if (tipo) {
var key = tipo.toLowerCase();
if (!fs.existsSync(docsPath)) { if (!DOCS[key]) {
console.error('Tipo inválido: "' + tipo + '". Use "desktop" ou "mobile".');
process.exit(1);
}
var docPath = path.join(platformDir, DOCS[key].subpath);
if (!fs.existsSync(docPath)) {
console.error('Erro: documentação não encontrada em:'); console.error('Erro: documentação não encontrada em:');
console.error(' ' + docsPath); console.error(' ' + docPath);
console.error(''); console.error('');
console.error('Execute "vitruvio update-base" para baixar os arquivos de plataforma.'); console.error('Execute "vitruvio update-base" para baixar os arquivos de plataforma.');
process.exit(1); process.exit(1);
} }
console.log('Abrindo documentação ' + DOCS[key].label + '...');
var cmd; openUrl(docPath);
if (process.platform === 'win32') { return;
cmd = 'start "" "' + docsPath + '"';
} else {
cmd = 'xdg-open "' + docsPath + '"';
} }
exec(cmd, function (err) { // No argument — generate and open selection page
if (err) { var javaPath = path.join(platformDir, DOCS.desktop.subpath);
console.error('Erro ao abrir o navegador: ' + err.message); var reactNativePath = path.join(platformDir, DOCS.mobile.subpath);
console.error('Abra manualmente: ' + docsPath);
var missingDocs = [];
if (!fs.existsSync(javaPath)) missingDocs.push('desktop (Java)');
if (!fs.existsSync(reactNativePath)) missingDocs.push('mobile (React Native)');
if (missingDocs.length === 2) {
console.error('Erro: nenhuma documentação encontrada em: ' + platformDir);
console.error('Execute "vitruvio update-base" para baixar os arquivos de plataforma.');
process.exit(1); process.exit(1);
} }
});
console.log('Abrindo documentação...'); var html = buildSelectionPage(javaPath, reactNativePath);
var tmpFile = path.join(os.tmpdir(), 'vitruvio-docs-selector.html');
fs.writeFileSync(tmpFile, html, 'utf8');
console.log('Abrindo seletor de documentação...');
openUrl(tmpFile);
}); });
} }