@livedesk/client 0.1.139 → 0.1.141

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import net from 'net';
4
4
  import os from 'os';
5
5
  import path from 'path';
6
6
  import crypto from 'crypto';
7
- import { promises as fs, statfsSync } from 'fs';
7
+ import { existsSync, promises as fs, statfsSync } from 'fs';
8
8
  import { spawn } from 'child_process';
9
9
  import { createRequire } from 'node:module';
10
10
 
@@ -1310,6 +1310,27 @@ function remotePolicyAllows(options, command) {
1310
1310
  return denied ? { ok: false, error: `${denied}-blocked-by-settings` } : { ok: true };
1311
1311
  }
1312
1312
 
1313
+ function buildClientUpdateBootstrapScript() {
1314
+ return [
1315
+ 'const { spawn } = require("node:child_process");',
1316
+ 'const fs = require("node:fs");',
1317
+ 'const path = require("node:path");',
1318
+ 'const waitPid = Number(process.env.LIVEDESK_UPDATE_WAIT_PID || 0);',
1319
+ 'const isAlive = pid => { try { process.kill(pid, 0); return true; } catch (error) { return error?.code !== "ESRCH"; } };',
1320
+ 'const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));',
1321
+ 'const waitForExit = async pid => { for (let attempt = 0; attempt < 360 && pid > 1; attempt += 1) { if (!isAlive(pid)) return; await sleep(500); } if (pid > 1 && isAlive(pid)) throw new Error("LiveDesk client launcher did not exit before update installation."); };',
1322
+ 'const nodeDir = path.dirname(process.execPath);',
1323
+ 'const npxCandidates = process.platform === "win32" ? [process.env.LIVEDESK_NPX_EXECUTABLE, path.join(nodeDir, "npx.cmd"), path.join(nodeDir, "npx.exe"), "npx.cmd"] : [process.env.LIVEDESK_NPX_EXECUTABLE, path.join(nodeDir, "npx"), "npx"];',
1324
+ 'const npx = npxCandidates.find(candidate => candidate && (!path.isAbsolute(candidate) || fs.existsSync(candidate)));',
1325
+ 'if (!npx) throw new Error("LiveDesk npx executable was not found.");',
1326
+ 'const npxArgs = ["-y", "--prefer-online", "livedesk@latest", "client", "--no-login"];',
1327
+ 'const command = process.platform === "win32" ? (process.env.ComSpec || "cmd.exe") : npx;',
1328
+ 'const commandArgs = process.platform === "win32" ? ["/d", "/s", "/c", `call "${npx}" ${npxArgs.join(" ")}`] : npxArgs;',
1329
+ '(async () => { await waitForExit(waitPid); const updater = spawn(command, commandArgs, { detached: true, stdio: "ignore", windowsHide: true, env: process.env }); updater.once("error", error => { console.error("LiveDesk updater failed to start: " + error.message); process.exitCode = 1; }); updater.once("spawn", () => updater.unref()); })().catch(error => { console.error("LiveDesk updater failed: " + error.message); process.exitCode = 1; });',
1330
+ ''
1331
+ ].join('\n');
1332
+ }
1333
+
1313
1334
  function scheduleClientUpdate(options, payload = {}) {
1314
1335
  const configuredParentPid = Number(process.env.LIVEDESK_CLIENT_PARENT_PID || process.ppid);
1315
1336
  const parentPid = Number.isInteger(configuredParentPid) && configuredParentPid > 1
@@ -1318,19 +1339,21 @@ function scheduleClientUpdate(options, payload = {}) {
1318
1339
  if (!Number.isInteger(parentPid) || parentPid <= 1) {
1319
1340
  return Promise.reject(new Error('LiveDesk client launcher process id is unavailable.'));
1320
1341
  }
1321
- const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
1342
+ const nodeBinDir = path.dirname(process.execPath);
1343
+ const npxCandidates = process.platform === 'win32'
1344
+ ? [process.env.LIVEDESK_NPX_EXECUTABLE, path.join(nodeBinDir, 'npx.cmd'), path.join(nodeBinDir, 'npx.exe'), 'npx.cmd']
1345
+ : [process.env.LIVEDESK_NPX_EXECUTABLE, path.join(nodeBinDir, 'npx'), 'npx'];
1346
+ const command = npxCandidates.find(candidate => candidate && (!path.isAbsolute(candidate) || existsSync(candidate)));
1347
+ if (!command) {
1348
+ return Promise.reject(new Error('LiveDesk npx executable was not found.'));
1349
+ }
1322
1350
  return new Promise((resolve, reject) => {
1323
- const child = spawn(command, [
1324
- '-y',
1325
- '--prefer-online',
1326
- 'livedesk@latest',
1327
- 'client',
1328
- '--no-login',
1329
- '--update-wait-pid',
1330
- String(parentPid)
1331
- ], {
1351
+ const child = spawn(process.execPath, ['-e', buildClientUpdateBootstrapScript()], {
1332
1352
  env: {
1333
1353
  ...process.env,
1354
+ LIVEDESK_NODE_EXECUTABLE: process.execPath,
1355
+ LIVEDESK_NPX_EXECUTABLE: command,
1356
+ LIVEDESK_UPDATE_WAIT_PID: String(parentPid),
1334
1357
  LIVEDESK_CLIENT_UPDATE_TARGET_VERSION: String(payload.targetVersion || process.env.LIVEDESK_CLIENT_UPDATE_TARGET_VERSION || '')
1335
1358
  },
1336
1359
  detached: true,
@@ -2526,6 +2526,18 @@ function resolveBundledFfmpegPaths() {
2526
2526
  function buildClientAgentEnvironment(prepared) {
2527
2527
  const env = { ...process.env };
2528
2528
  env.LIVEDESK_CLIENT_PARENT_PID = String(process.pid);
2529
+ // The client can be started by Explorer, a startup shortcut, or a GUI shell
2530
+ // with a PATH that does not contain the Node installation. Update commands
2531
+ // must therefore receive the exact Node tool paths used by this launcher.
2532
+ env.LIVEDESK_NODE_EXECUTABLE = process.execPath;
2533
+ const nodeBinDir = dirname(process.execPath);
2534
+ const npxCandidates = process.platform === 'win32'
2535
+ ? [env.LIVEDESK_NPX_EXECUTABLE, join(nodeBinDir, 'npx.cmd'), join(nodeBinDir, 'npx.exe')]
2536
+ : [env.LIVEDESK_NPX_EXECUTABLE, join(nodeBinDir, 'npx')];
2537
+ const npxExecutable = npxCandidates.find(candidate => candidate && existsSync(candidate));
2538
+ if (npxExecutable) {
2539
+ env.LIVEDESK_NPX_EXECUTABLE = npxExecutable;
2540
+ }
2529
2541
  env.LIVEDESK_CLIENT_MANAGER = String(prepared?.manager || env.LIVEDESK_CLIENT_MANAGER || '');
2530
2542
  env.LIVEDESK_CLIENT_PAIR_TOKEN = String(prepared?.pair || env.LIVEDESK_CLIENT_PAIR_TOKEN || '');
2531
2543
  env.LIVEDESK_CLIENT_NAME = String(prepared?.name || env.LIVEDESK_CLIENT_NAME || '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.139",
3
+ "version": "0.1.141",
4
4
  "description": "LiveDesk local remote client",
5
5
  "type": "module",
6
6
  "bin": {