UNPKG

idioma-cli

Version:

CLI for Idioma - Internationalization engine with smart defaults

97 lines (94 loc) 11.7 kB
// src/cli/background.ts import { spawn as nodeSpawn } from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; var __dirname = "/Users/ryanwaits/Code/projects/idioma/packages/cli/src/cli"; var STATUS_DIR = path.join(os.tmpdir(), "idioma-translations"); var STATUS_FILE = path.join(STATUS_DIR, "status.json"); var PID_FILE = path.join(STATUS_DIR, "process.pid"); async function startBackgroundTranslation(args) { await fs.mkdir(STATUS_DIR, { recursive: true }); const isRunning = await isTranslationRunning(); if (isRunning) { console.log("❌ A translation is already running in the background."); console.log('Run "idioma status" to check progress or "idioma stop" to cancel it.'); return; } const isBun = typeof Bun !== "undefined"; const runtime = isBun ? "bun" : "node"; const scriptPath = path.join(__dirname, "worker.js"); const proc = nodeSpawn(runtime, [scriptPath, ...args], { cwd: process.cwd(), env: process.env, detached: true, stdio: "ignore" }); proc.unref(); await fs.writeFile(PID_FILE, proc.pid.toString()); const initialStatus = { status: "running", startTime: new Date().toISOString(), totalFiles: 0, processedFiles: 0, errors: [], pid: proc.pid }; await fs.writeFile(STATUS_FILE, JSON.stringify(initialStatus, null, 2)); console.log(`✅ Translation started in background (PID: ${proc.pid})`); console.log('Run "idioma status" to check progress.'); } async function getTranslationStatus() { try { const statusData = await fs.readFile(STATUS_FILE, "utf-8"); return JSON.parse(statusData); } catch { return null; } } async function stopBackgroundTranslation() { try { const pidData = await fs.readFile(PID_FILE, "utf-8"); const pid = parseInt(pidData, 10); process.kill(pid, "SIGTERM"); await fs.unlink(PID_FILE).catch(() => {}); await fs.unlink(STATUS_FILE).catch(() => {}); console.log("✅ Background translation stopped."); return true; } catch (_error) { console.log("❌ No background translation running."); return false; } } async function isTranslationRunning() { try { const pidData = await fs.readFile(PID_FILE, "utf-8"); const pid = parseInt(pidData, 10); try { process.kill(pid, 0); return true; } catch { await fs.unlink(PID_FILE).catch(() => {}); return false; } } catch { return false; } } async function updateStatus(updates) { const current = await getTranslationStatus() || { status: "running", startTime: new Date().toISOString(), totalFiles: 0, processedFiles: 0, errors: [] }; const updated = { ...current, ...updates }; if (updates.errors && Array.isArray(updates.errors)) { updated.errors = [...current.errors || [], ...updates.errors]; } await fs.writeFile(STATUS_FILE, JSON.stringify(updated, null, 2)); } export { startBackgroundTranslation, getTranslationStatus, stopBackgroundTranslation, updateStatus }; //# debugId=E20AC452E3FF854464756E2164756E21 //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NsaS9iYWNrZ3JvdW5kLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgImltcG9ydCB7IHNwYXduIGFzIG5vZGVTcGF3biB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgb3MgZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5jb25zdCBTVEFUVVNfRElSID0gcGF0aC5qb2luKG9zLnRtcGRpcigpLCAnaWRpb21hLXRyYW5zbGF0aW9ucycpO1xuY29uc3QgU1RBVFVTX0ZJTEUgPSBwYXRoLmpvaW4oU1RBVFVTX0RJUiwgJ3N0YXR1cy5qc29uJyk7XG5jb25zdCBQSURfRklMRSA9IHBhdGguam9pbihTVEFUVVNfRElSLCAncHJvY2Vzcy5waWQnKTtcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvblN0YXR1cyB7XG4gIHN0YXR1czogJ3J1bm5pbmcnIHwgJ2NvbXBsZXRlZCcgfCAnZmFpbGVkJztcbiAgc3RhcnRUaW1lOiBzdHJpbmc7XG4gIGVuZFRpbWU/OiBzdHJpbmc7XG4gIHRvdGFsRmlsZXM6IG51bWJlcjtcbiAgcHJvY2Vzc2VkRmlsZXM6IG51bWJlcjtcbiAgY3VycmVudEZpbGU/OiBzdHJpbmc7XG4gIGVycm9yczogc3RyaW5nW107XG4gIHBpZD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0QmFja2dyb3VuZFRyYW5zbGF0aW9uKGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIEVuc3VyZSBzdGF0dXMgZGlyZWN0b3J5IGV4aXN0c1xuICBhd2FpdCBmcy5ta2RpcihTVEFUVVNfRElSLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAvLyBDaGVjayBpZiB0cmFuc2xhdGlvbiBpcyBhbHJlYWR5IHJ1bm5pbmdcbiAgY29uc3QgaXNSdW5uaW5nID0gYXdhaXQgaXNUcmFuc2xhdGlvblJ1bm5pbmcoKTtcbiAgaWYgKGlzUnVubmluZykge1xuICAgIGNvbnNvbGUubG9nKCfinYwgQSB0cmFuc2xhdGlvbiBpcyBhbHJlYWR5IHJ1bm5pbmcgaW4gdGhlIGJhY2tncm91bmQuJyk7XG4gICAgY29uc29sZS5sb2coJ1J1biBcImlkaW9tYSBzdGF0dXNcIiB0byBjaGVjayBwcm9ncmVzcyBvciBcImlkaW9tYSBzdG9wXCIgdG8gY2FuY2VsIGl0LicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFByZXBhcmUgdGhlIGNvbW1hbmQgLSBkZXRlY3QgcnVudGltZVxuICBjb25zdCBpc0J1biA9IHR5cGVvZiBCdW4gIT09ICd1bmRlZmluZWQnO1xuICBjb25zdCBydW50aW1lID0gaXNCdW4gPyAnYnVuJyA6ICdub2RlJztcbiAgY29uc3Qgc2NyaXB0UGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICd3b3JrZXIuanMnKTsgLy8gVXNlIC5qcyBmb3IgY29tcGF0aWJpbGl0eVxuXG4gIC8vIFNwYXduIHRoZSBiYWNrZ3JvdW5kIHByb2Nlc3MgdXNpbmcgTm9kZSdzIGNoaWxkX3Byb2Nlc3NcbiAgY29uc3QgcHJvYyA9IG5vZGVTcGF3bihydW50aW1lLCBbc2NyaXB0UGF0aCwgLi4uYXJnc10sIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgZW52OiBwcm9jZXNzLmVudixcbiAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICBzdGRpbzogJ2lnbm9yZScsXG4gIH0pO1xuXG4gIC8vIERldGFjaCB0aGUgcHJvY2VzcyBzbyBpdCBydW5zIGluZGVwZW5kZW50bHlcbiAgcHJvYy51bnJlZigpO1xuXG4gIC8vIFNhdmUgdGhlIFBJRFxuICBhd2FpdCBmcy53cml0ZUZpbGUoUElEX0ZJTEUsIHByb2MucGlkLnRvU3RyaW5nKCkpO1xuXG4gIC8vIEluaXRpYWxpemUgc3RhdHVzIGZpbGVcbiAgY29uc3QgaW5pdGlhbFN0YXR1czogVHJhbnNsYXRpb25TdGF0dXMgPSB7XG4gICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgc3RhcnRUaW1lOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgdG90YWxGaWxlczogMCxcbiAgICBwcm9jZXNzZWRGaWxlczogMCxcbiAgICBlcnJvcnM6IFtdLFxuICAgIHBpZDogcHJvYy5waWQsXG4gIH07XG4gIGF3YWl0IGZzLndyaXRlRmlsZShTVEFUVVNfRklMRSwgSlNPTi5zdHJpbmdpZnkoaW5pdGlhbFN0YXR1cywgbnVsbCwgMikpO1xuXG4gIGNvbnNvbGUubG9nKGDinIUgVHJhbnNsYXRpb24gc3RhcnRlZCBpbiBiYWNrZ3JvdW5kIChQSUQ6ICR7cHJvYy5waWR9KWApO1xuICBjb25zb2xlLmxvZygnUnVuIFwiaWRpb21hIHN0YXR1c1wiIHRvIGNoZWNrIHByb2dyZXNzLicpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0VHJhbnNsYXRpb25TdGF0dXMoKTogUHJvbWlzZTxUcmFuc2xhdGlvblN0YXR1cyB8IG51bGw+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdGF0dXNEYXRhID0gYXdhaXQgZnMucmVhZEZpbGUoU1RBVFVTX0ZJTEUsICd1dGYtOCcpO1xuICAgIHJldHVybiBKU09OLnBhcnNlKHN0YXR1c0RhdGEpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcEJhY2tncm91bmRUcmFuc2xhdGlvbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwaWREYXRhID0gYXdhaXQgZnMucmVhZEZpbGUoUElEX0ZJTEUsICd1dGYtOCcpO1xuICAgIGNvbnN0IHBpZCA9IHBhcnNlSW50KHBpZERhdGEsIDEwKTtcblxuICAgIC8vIEtpbGwgdGhlIHByb2Nlc3NcbiAgICBwcm9jZXNzLmtpbGwocGlkLCAnU0lHVEVSTScpO1xuXG4gICAgLy8gQ2xlYW4gdXAgZmlsZXNcbiAgICBhd2FpdCBmcy51bmxpbmsoUElEX0ZJTEUpLmNhdGNoKCgpID0+IHt9KTtcbiAgICBhd2FpdCBmcy51bmxpbmsoU1RBVFVTX0ZJTEUpLmNhdGNoKCgpID0+IHt9KTtcblxuICAgIGNvbnNvbGUubG9nKCfinIUgQmFja2dyb3VuZCB0cmFuc2xhdGlvbiBzdG9wcGVkLicpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICBjb25zb2xlLmxvZygn4p2MIE5vIGJhY2tncm91bmQgdHJhbnNsYXRpb24gcnVubmluZy4nKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzVHJhbnNsYXRpb25SdW5uaW5nKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGNvbnN0IHBpZERhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZShQSURfRklMRSwgJ3V0Zi04Jyk7XG4gICAgY29uc3QgcGlkID0gcGFyc2VJbnQocGlkRGF0YSwgMTApO1xuXG4gICAgLy8gQ2hlY2sgaWYgcHJvY2VzcyBpcyBzdGlsbCBydW5uaW5nXG4gICAgdHJ5IHtcbiAgICAgIHByb2Nlc3Mua2lsbChwaWQsIDApOyAvLyBTaWduYWwgMCBjaGVja3MgaWYgcHJvY2VzcyBleGlzdHNcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gUHJvY2VzcyBkb2Vzbid0IGV4aXN0LCBjbGVhbiB1cCBzdGFsZSBmaWxlc1xuICAgICAgYXdhaXQgZnMudW5saW5rKFBJRF9GSUxFKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVN0YXR1cyh1cGRhdGVzOiBQYXJ0aWFsPFRyYW5zbGF0aW9uU3RhdHVzPik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjdXJyZW50ID0gKGF3YWl0IGdldFRyYW5zbGF0aW9uU3RhdHVzKCkpIHx8IHtcbiAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICBzdGFydFRpbWU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICB0b3RhbEZpbGVzOiAwLFxuICAgIHByb2Nlc3NlZEZpbGVzOiAwLFxuICAgIGVycm9yczogW10sXG4gIH07XG5cbiAgY29uc3QgdXBkYXRlZCA9IHsgLi4uY3VycmVudCwgLi4udXBkYXRlcyB9O1xuXG4gIC8vIEhhbmRsZSBlcnJvcnMgYXJyYXkgc3BlY2lhbGx5IC0gYXBwZW5kIGluc3RlYWQgb2YgcmVwbGFjZVxuICBpZiAodXBkYXRlcy5lcnJvcnMgJiYgQXJyYXkuaXNBcnJheSh1cGRhdGVzLmVycm9ycykpIHtcbiAgICB1cGRhdGVkLmVycm9ycyA9IFsuLi4oY3VycmVudC5lcnJvcnMgfHwgW10pLCAuLi51cGRhdGVzLmVycm9yc107XG4gIH1cblxuICBhd2FpdCBmcy53cml0ZUZpbGUoU1RBVFVTX0ZJTEUsIEpTT04uc3RyaW5naWZ5KHVwZGF0ZWQsIG51bGwsIDIpKTtcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7QUFBQSxrQkFBUztBQUNUO0FBQ0E7QUFDQTtBQUFBO0FBRUEsSUFBTSxhQUFhLEtBQUssS0FBSyxHQUFHLE9BQU8sR0FBRyxxQkFBcUI7QUFDL0QsSUFBTSxjQUFjLEtBQUssS0FBSyxZQUFZLGFBQWE7QUFDdkQsSUFBTSxXQUFXLEtBQUssS0FBSyxZQUFZLGFBQWE7QUFhcEQsZUFBc0IsMEJBQTBCLENBQUMsTUFBK0I7QUFBQSxFQUU5RSxNQUFNLEdBQUcsTUFBTSxZQUFZLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFBQSxFQUc5QyxNQUFNLFlBQVksTUFBTSxxQkFBcUI7QUFBQSxFQUM3QyxJQUFJLFdBQVc7QUFBQSxJQUNiLFFBQVEsSUFBSSx1REFBc0Q7QUFBQSxJQUNsRSxRQUFRLElBQUksc0VBQXNFO0FBQUEsSUFDbEY7QUFBQSxFQUNGO0FBQUEsRUFHQSxNQUFNLFFBQVEsT0FBTyxRQUFRO0FBQUEsRUFD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