* Resolves and validates the bin declared by the local `vercel` package.
( localPackage: LocalVercelPackage, commandBase: string )
| 722 | * Resolves and validates the bin declared by the local `vercel` package. |
| 723 | */ |
| 724 | async function getDeclaredLocalVercelPackageBin( |
| 725 | localPackage: LocalVercelPackage, |
| 726 | commandBase: string |
| 727 | ): Promise<LocalVercelPackageBinResult> { |
| 728 | const { packageJson, realNodeModulesDirectory, realPackageDirectory } = |
| 729 | localPackage; |
| 730 | |
| 731 | const binTarget = getPackageBinTarget(packageJson, commandBase); |
| 732 | |
| 733 | if (!binTarget) { |
| 734 | return { reason: 'local vercel package does not declare bin.vercel' }; |
| 735 | } |
| 736 | |
| 737 | const declaredBinPath = path.resolve(realPackageDirectory, binTarget); |
| 738 | const realDeclaredBinPath = await realpath(declaredBinPath); |
| 739 | |
| 740 | if (!isSubpath(realPackageDirectory, realDeclaredBinPath)) { |
| 741 | return { reason: 'local vercel package bin resolves outside package' }; |
| 742 | } |
| 743 | |
| 744 | const unsafePackageBinReason = await getUnsafePackageBinReason( |
| 745 | realNodeModulesDirectory, |
| 746 | realPackageDirectory, |
| 747 | realDeclaredBinPath |
| 748 | ); |
| 749 | |
| 750 | if (unsafePackageBinReason) { |
| 751 | return { |
| 752 | reason: `local vercel package bin is unsafe: ${unsafePackageBinReason}`, |
| 753 | }; |
| 754 | } |
| 755 | |
| 756 | if (process.platform !== 'win32' && !isNodeScript(realDeclaredBinPath)) { |
| 757 | try { |
| 758 | await access(realDeclaredBinPath, constants.F_OK | constants.X_OK); |
| 759 | } catch (error) { |
| 760 | return { |
| 761 | reason: `local vercel package bin is not executable: ${getErrorMessage(error)}`, |
| 762 | }; |
| 763 | } |
| 764 | } |
| 765 | |
| 766 | return { binPath: realDeclaredBinPath }; |
| 767 | } |
| 768 | |
| 769 | /** |
| 770 | * Reads the declared bin target for the requested command from package data. |
no test coverage detected