feat(compat): added mac OS compat
This commit is contained in:
+85
-44
@@ -2,29 +2,94 @@
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var http = require('http');
|
||||
var { exec } = require('child_process');
|
||||
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') },
|
||||
desktop: { label: 'Desktop (Java)', subpath: 'docs/java/index.html' },
|
||||
mobile: { label: 'Mobile (React Native)', subpath: 'docs/react-native/index.html' },
|
||||
};
|
||||
|
||||
function openUrl(filePath) {
|
||||
var cmd;
|
||||
if (process.platform === 'win32') cmd = 'start "" "' + filePath + '"';
|
||||
else if (process.platform === 'darwin') cmd = 'open "' + filePath + '"';
|
||||
else cmd = 'xdg-open "' + filePath + '"';
|
||||
var MIME = {
|
||||
'.html': 'text/html; charset=utf-8',
|
||||
'.css': 'text/css',
|
||||
'.js': 'application/javascript',
|
||||
'.json': 'application/json',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.ico': 'image/x-icon',
|
||||
'.woff': 'font/woff',
|
||||
'.woff2':'font/woff2',
|
||||
'.ttf': 'font/ttf',
|
||||
};
|
||||
|
||||
function getMime(filePath) {
|
||||
return MIME[path.extname(filePath).toLowerCase()] || 'application/octet-stream';
|
||||
}
|
||||
|
||||
function openBrowser(url) {
|
||||
var cmd;
|
||||
if (process.platform === 'win32') cmd = 'start "" "' + url + '"';
|
||||
else if (process.platform === 'darwin') cmd = 'open "' + url + '"';
|
||||
else cmd = 'xdg-open "' + url + '"';
|
||||
exec(cmd, function (err) {
|
||||
if (err) {
|
||||
console.error('Erro ao abrir o navegador: ' + err.message);
|
||||
console.error('Abra manualmente: ' + filePath);
|
||||
process.exit(1);
|
||||
console.error('Acesse manualmente: ' + url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serve(platformDir, entryUrl, selectorHtml) {
|
||||
var server = http.createServer(function (req, res) {
|
||||
var urlPath = req.url.split('?')[0];
|
||||
|
||||
if (urlPath === '/' || urlPath === '/index.html') {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||
res.end(selectorHtml);
|
||||
return;
|
||||
}
|
||||
|
||||
// Normalize URL path separators for Windows
|
||||
var relative = urlPath.replace(/\//g, path.sep).replace(/^\\/, '');
|
||||
var filePath = path.join(platformDir, relative);
|
||||
|
||||
// Prevent path traversal
|
||||
if (!filePath.startsWith(platformDir + path.sep) && filePath !== platformDir) {
|
||||
res.writeHead(403);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Serve directory index
|
||||
try {
|
||||
if (fs.statSync(filePath).isDirectory()) {
|
||||
filePath = path.join(filePath, 'index.html');
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
fs.readFile(filePath, function (err, data) {
|
||||
if (err) { res.writeHead(404); res.end(); return; }
|
||||
res.writeHead(200, { 'Content-Type': getMime(filePath) });
|
||||
res.end(data);
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
var port = server.address().port;
|
||||
var url = 'http://127.0.0.1:' + port + entryUrl;
|
||||
console.log('Servidor local em ' + url);
|
||||
console.log('Pressione Ctrl+C para encerrar.');
|
||||
openBrowser(url);
|
||||
});
|
||||
|
||||
process.on('SIGINT', function () { server.close(function () { process.exit(0); }); });
|
||||
process.on('SIGTERM', function () { server.close(function () { process.exit(0); }); });
|
||||
}
|
||||
|
||||
function buildSelectionPage() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
@@ -105,16 +170,8 @@ function buildSelectionPage() {
|
||||
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-primary { background: #F78259; color: #fff; }
|
||||
.btn-secondary { background: #fff3ef; color: #c05a30; border: 2px solid #f7c2ad; }
|
||||
|
||||
.btn-icon {
|
||||
width: 38px;
|
||||
@@ -127,10 +184,7 @@ function buildSelectionPage() {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.btn-secondary .btn-icon {
|
||||
background: rgba(247, 130, 89, 0.12);
|
||||
}
|
||||
|
||||
.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; }
|
||||
@@ -144,11 +198,7 @@ function buildSelectionPage() {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 32px;
|
||||
font-size: 0.78rem;
|
||||
color: #bbb;
|
||||
}
|
||||
footer { margin-top: 32px; font-size: 0.78rem; color: #bbb; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -163,7 +213,7 @@ function buildSelectionPage() {
|
||||
<p class="subtitle">Selecione abaixo qual documentação você deseja consultar.</p>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="btn btn-primary" href="docs/java/index.html">
|
||||
<a class="btn btn-primary" href="/docs/java/index.html">
|
||||
<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"/>
|
||||
@@ -175,7 +225,7 @@ function buildSelectionPage() {
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="btn btn-secondary" href="docs/react-native/index.html">
|
||||
<a class="btn btn-secondary" href="/docs/react-native/index.html">
|
||||
<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"/>
|
||||
@@ -218,34 +268,25 @@ function register(program) {
|
||||
console.error('Erro: documentação não encontrada em:');
|
||||
console.error(' ' + docPath);
|
||||
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);
|
||||
}
|
||||
console.log('Abrindo documentação ' + DOCS[key].label + '...');
|
||||
openUrl(docPath);
|
||||
serve(platformDir, '/' + DOCS[key].subpath, buildSelectionPage());
|
||||
return;
|
||||
}
|
||||
|
||||
// No argument — generate and open selection page
|
||||
var javaPath = path.join(platformDir, DOCS.desktop.subpath);
|
||||
var reactNativePath = path.join(platformDir, DOCS.mobile.subpath);
|
||||
|
||||
var missingDocs = [];
|
||||
if (!fs.existsSync(javaPath)) missingDocs.push('desktop (Java)');
|
||||
if (!fs.existsSync(reactNativePath)) missingDocs.push('mobile (React Native)');
|
||||
|
||||
if (missingDocs.length === 2) {
|
||||
if (!fs.existsSync(javaPath) && !fs.existsSync(reactNativePath)) {
|
||||
console.error('Erro: nenhuma documentação encontrada em: ' + platformDir);
|
||||
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);
|
||||
}
|
||||
|
||||
var html = buildSelectionPage();
|
||||
var tmpFile = path.join(platformDir, 'docs-selector.html');
|
||||
fs.writeFileSync(tmpFile, html, 'utf8');
|
||||
|
||||
console.log('Abrindo seletor de documentação...');
|
||||
openUrl(tmpFile);
|
||||
serve(platformDir, '/', buildSelectionPage());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ var HTTPS_URL = 'https://git.davinti.com.br/davinTI/ide-config.git';
|
||||
* Linux base: ~/. Windows base: %APPDATA%\
|
||||
*/
|
||||
function resolveSnippetsDir(ideEntry) {
|
||||
var platform = process.platform === 'win32' ? 'win32' : 'linux';
|
||||
var platform = process.platform === 'win32' ? 'win32' : process.platform === 'darwin' ? 'darwin' : 'linux';
|
||||
var rel = ideEntry.snippetsDir[platform];
|
||||
if (!rel) throw new Error('snippetsDir not defined for platform ' + platform);
|
||||
if (platform === 'win32') {
|
||||
@@ -91,7 +91,7 @@ function promptIde(ideKeys, manifest) {
|
||||
// ── Installers ────────────────────────────────────────────────────────────────
|
||||
|
||||
function installVscodeFork(ideEntry, repoRoot) {
|
||||
var platform = process.platform === 'win32' ? 'win32' : 'linux';
|
||||
var platform = process.platform === 'win32' ? 'win32' : process.platform === 'darwin' ? 'darwin' : 'linux';
|
||||
var bin = ideEntry.bin[platform];
|
||||
|
||||
// Extension
|
||||
|
||||
Reference in New Issue
Block a user