docs: sync v3.2.6 features across 30 languages (README + FEATURES)

This commit is contained in:
diegosouzapw
2026-03-29 04:53:59 -03:00
parent dc077bc309
commit b84e79362e
89 changed files with 1137 additions and 744 deletions

View File

@@ -30,7 +30,6 @@ async function getLatestNpmVersion(): Promise<string | null> {
/** Current installed version from package.json */
function getCurrentVersion(): string {
try {
return require("../../../../../package.json").version as string;
} catch {
return "unknown";
@@ -89,27 +88,75 @@ export async function POST(req: NextRequest) {
});
}
// Run update in background — client gets immediate acknowledgment
const install = async () => {
try {
await execFileAsync("npm", ["install", "-g", `omniroute@${latest}`, "--ignore-scripts"], {
timeout: 300000, // 5 minutes
});
// Restart PM2 — non-fatal if pm2 not available (Docker/manual setups)
await execFileAsync("pm2", ["restart", "omniroute"]).catch(() => null);
console.log(`[AutoUpdate] Successfully updated to v${latest}`);
} catch (err) {
console.error(`[AutoUpdate] Update failed:`, err);
}
};
// Stream progress events so the frontend can show real-time status
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
const send = (data: Record<string, unknown>) => {
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`));
};
// Fire-and-forget
install();
try {
// Step 1: Install
send({ step: "install", status: "running", message: `Installing omniroute@${latest}...` });
await execFileAsync("npm", ["install", "-g", `omniroute@${latest}`, "--ignore-scripts"], {
timeout: 300000,
});
send({ step: "install", status: "done", message: `Installed omniroute@${latest}` });
return NextResponse.json({
success: true,
message: `Update to v${latest} started. Restarting in ~30 seconds.`,
from: current,
to: latest,
// Step 2: Rebuild native modules (critical for better-sqlite3)
send({
step: "rebuild",
status: "running",
message: "Rebuilding native modules (better-sqlite3)...",
});
const globalRoot = (
await execFileAsync("npm", ["root", "-g"], { timeout: 10000 })
).stdout.trim();
const omniPath = `${globalRoot}/omniroute/app`;
await execFileAsync("npm", ["rebuild", "better-sqlite3"], {
cwd: omniPath,
timeout: 120000,
});
send({ step: "rebuild", status: "done", message: "Native modules rebuilt" });
// Step 3: Restart PM2
send({ step: "restart", status: "running", message: "Restarting service via PM2..." });
try {
await execFileAsync("pm2", ["restart", "omniroute", "--update-env"], { timeout: 30000 });
send({ step: "restart", status: "done", message: "Service restarted" });
} catch {
// PM2 may not be available (Docker/manual setups)
send({
step: "restart",
status: "skipped",
message: "PM2 not available — manual restart needed",
});
}
send({
step: "complete",
status: "done",
from: current,
to: latest,
message: `Update to v${latest} complete!`,
});
console.log(`[AutoUpdate] Successfully updated to v${latest}`);
} catch (err: any) {
const errMsg = err?.stderr || err?.message || String(err);
send({ step: "error", status: "failed", message: errMsg });
console.error(`[AutoUpdate] Update failed:`, err);
} finally {
controller.close();
}
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
});
}