@tapi-dev/sdk 0.1.31 → 0.1.32

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.
package/dist/cli.d.ts CHANGED
@@ -85,6 +85,7 @@ export declare function trySelectDevSessionInOpenStudio(session: TapiDevSession,
85
85
  baseUrl?: string;
86
86
  reason?: string;
87
87
  }>;
88
+ export declare function servicePowerShell(action: string): string;
88
89
  export declare function installedServiceVersionFromPathName(pathName: string): string | undefined;
89
90
  export declare function serviceNeedsInstall(status: ServiceStatus, manifest: ServiceReleaseManifest): boolean;
90
91
  export declare function getDefaultStudioCacheDir(): string;
package/dist/cli.js CHANGED
@@ -28,6 +28,8 @@ const DOWNLOAD_PROGRESS_LOG_BYTES = 50 * 1024 * 1024;
28
28
  const MAX_WIDE_EVENT_PROCESS_ROOTS = 5;
29
29
  const MAX_NONCURRENT_MANAGED_DOWNLOADS = 0;
30
30
  const MAX_NONCURRENT_MANAGED_RELEASES = 0;
31
+ const WINDOWS_SERVICE_STATUS_TIMEOUT_MS = 8_000;
32
+ const WINDOWS_SERVICE_COMMAND_TIMEOUT_MS = 30_000;
31
33
  const MANAGED_RELEASE_MARKER = ".tapi-managed-release";
32
34
  const MIN_EXTRACTION_REQUIRED_BYTES = 1024 * 1024 * 1024;
33
35
  const EXTRACTION_REQUIRED_MULTIPLIER = 3;
@@ -1351,7 +1353,7 @@ async function runServiceCommand(action, args = []) {
1351
1353
  return repairService(parseStudioOptions([]));
1352
1354
  }
1353
1355
  const command = servicePowerShell(normalized);
1354
- const output = await withCliSpinner(`Running tapi-service ${normalized}`, () => runProcessCapture("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", command]));
1356
+ const output = await withCliSpinner(`Running tapi-service ${normalized}`, () => runProcessCapture("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", command], { timeoutMs: WINDOWS_SERVICE_COMMAND_TIMEOUT_MS }));
1355
1357
  if (output.trim()) {
1356
1358
  console.log(output.trim());
1357
1359
  }
@@ -1369,9 +1371,9 @@ async function repairService(options) {
1369
1371
  }
1370
1372
  return runServiceCommand("restart");
1371
1373
  }
1372
- function servicePowerShell(action) {
1374
+ export function servicePowerShell(action) {
1373
1375
  const serviceName = "tapi-service";
1374
- const status = `$svc = Get-Service -Name '${serviceName}' -ErrorAction SilentlyContinue; if ($null -eq $svc) { [pscustomobject]@{ installed = $false; name = '${serviceName}'; status = 'not_installed'; pathName = '' } | ConvertTo-Json -Compress; exit 0 }; $cim = Get-CimInstance Win32_Service -Filter "Name='${serviceName}'" -ErrorAction SilentlyContinue; $pathName = if ($null -ne $cim) { [string]$cim.PathName } else { '' }; [pscustomobject]@{ installed = $true; name = $svc.Name; status = $svc.Status.ToString(); pathName = $pathName } | ConvertTo-Json -Compress`;
1376
+ const status = `$svc = Get-Service -Name '${serviceName}' -ErrorAction SilentlyContinue; if ($null -eq $svc) { [pscustomobject]@{ installed = $false; name = '${serviceName}'; status = 'not_installed'; pathName = '' } | ConvertTo-Json -Compress; exit 0 }; $pathName = ''; try { $imagePath = (Get-ItemProperty -LiteralPath 'HKLM:\\SYSTEM\\CurrentControlSet\\Services\\${serviceName}' -Name ImagePath -ErrorAction SilentlyContinue).ImagePath; if ($null -ne $imagePath) { $pathName = [string]$imagePath } } catch {}; [pscustomobject]@{ installed = $true; name = $svc.Name; status = $svc.Status.ToString(); pathName = $pathName } | ConvertTo-Json -Compress`;
1375
1377
  if (action === "status") {
1376
1378
  return status;
1377
1379
  }
@@ -1393,7 +1395,7 @@ async function getServiceStatus() {
1393
1395
  "Bypass",
1394
1396
  "-Command",
1395
1397
  servicePowerShell("status"),
1396
- ]);
1398
+ ], { timeoutMs: WINDOWS_SERVICE_STATUS_TIMEOUT_MS });
1397
1399
  try {
1398
1400
  const payload = JSON.parse(output.trim());
1399
1401
  return {
@@ -1436,7 +1438,7 @@ async function ensureServiceReadyForStudio(options) {
1436
1438
  "Bypass",
1437
1439
  "-Command",
1438
1440
  servicePowerShell("start"),
1439
- ]));
1441
+ ], { timeoutMs: WINDOWS_SERVICE_COMMAND_TIMEOUT_MS }));
1440
1442
  if (output.trim()) {
1441
1443
  console.log(output.trim());
1442
1444
  }
@@ -3086,7 +3088,7 @@ async function runProcess(command, args) {
3086
3088
  });
3087
3089
  });
3088
3090
  }
3089
- async function runProcessCapture(command, args) {
3091
+ async function runProcessCapture(command, args, options = {}) {
3090
3092
  return await new Promise((resolvePromise, rejectPromise) => {
3091
3093
  const child = spawn(command, args, {
3092
3094
  stdio: ["ignore", "pipe", "pipe"],
@@ -3094,21 +3096,47 @@ async function runProcessCapture(command, args) {
3094
3096
  });
3095
3097
  let stdout = "";
3096
3098
  let stderr = "";
3099
+ let timedOut = false;
3100
+ let settled = false;
3101
+ const timeoutMs = Math.max(0, options.timeoutMs ?? 0);
3102
+ const timeout = timeoutMs > 0
3103
+ ? setTimeout(() => {
3104
+ timedOut = true;
3105
+ child.kill();
3106
+ }, timeoutMs)
3107
+ : undefined;
3108
+ timeout?.unref?.();
3109
+ const finish = (callback) => {
3110
+ if (settled) {
3111
+ return;
3112
+ }
3113
+ settled = true;
3114
+ if (timeout) {
3115
+ clearTimeout(timeout);
3116
+ }
3117
+ callback();
3118
+ };
3097
3119
  child.stdout.on("data", (chunk) => {
3098
3120
  stdout += String(chunk);
3099
3121
  });
3100
3122
  child.stderr.on("data", (chunk) => {
3101
3123
  stderr += String(chunk);
3102
3124
  });
3103
- child.once("error", rejectPromise);
3125
+ child.once("error", (error) => finish(() => rejectPromise(error)));
3104
3126
  child.once("exit", (code) => {
3105
- const err = stderr.trim();
3106
- if (code === 0) {
3107
- resolvePromise(stdout);
3108
- }
3109
- else {
3110
- rejectPromise(new Error(err || `Process exited with code ${code ?? "unknown"}.`));
3111
- }
3127
+ finish(() => {
3128
+ const err = stderr.trim();
3129
+ if (timedOut) {
3130
+ rejectPromise(new Error(`Process timed out after ${timeoutMs} ms: ${command} ${args.join(" ")}`));
3131
+ return;
3132
+ }
3133
+ if (code === 0) {
3134
+ resolvePromise(stdout);
3135
+ }
3136
+ else {
3137
+ rejectPromise(new Error(err || `Process exited with code ${code ?? "unknown"}.`));
3138
+ }
3139
+ });
3112
3140
  });
3113
3141
  });
3114
3142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapi-dev/sdk",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",