( channel: ReleaseChannel, )
| 317 | } |
| 318 | |
| 319 | export async function getLatestVersion( |
| 320 | channel: ReleaseChannel, |
| 321 | ): Promise<string | null> { |
| 322 | const npmTag = channel === 'stable' ? 'stable' : 'latest' |
| 323 | |
| 324 | // Run from home directory to avoid reading project-level .npmrc |
| 325 | // which could be maliciously crafted to redirect to an attacker's registry |
| 326 | const result = await execFileNoThrowWithCwd( |
| 327 | 'npm', |
| 328 | ['view', `${MACRO.PACKAGE_URL}@${npmTag}`, 'version', '--prefer-online'], |
| 329 | { abortSignal: AbortSignal.timeout(5000), cwd: homedir() }, |
| 330 | ) |
| 331 | if (result.code !== 0) { |
| 332 | logForDebugging(`npm view failed with code ${result.code}`) |
| 333 | if (result.stderr) { |
| 334 | logForDebugging(`npm stderr: ${result.stderr.trim()}`) |
| 335 | } else { |
| 336 | logForDebugging('npm stderr: (empty)') |
| 337 | } |
| 338 | if (result.stdout) { |
| 339 | logForDebugging(`npm stdout: ${result.stdout.trim()}`) |
| 340 | } |
| 341 | return null |
| 342 | } |
| 343 | return result.stdout.trim() |
| 344 | } |
| 345 | |
| 346 | export type NpmDistTags = { |
| 347 | latest: string | null |
no test coverage detected