* Classifies a concrete PATH hit after command lookup. This catches local * `node_modules/.bin` entries that arrived from the user's PATH instead of the * trusted local-bin discovery phase above.
( filePath: string, localBinDirectories: string[] )
| 572 | * trusted local-bin discovery phase above. |
| 573 | */ |
| 574 | async function classifyPathLocalBinCandidate( |
| 575 | filePath: string, |
| 576 | localBinDirectories: string[] |
| 577 | ): Promise<PathLocalBinCandidate> { |
| 578 | const localBinDirectory = await getLocalBinDirectory( |
| 579 | filePath, |
| 580 | localBinDirectories |
| 581 | ); |
| 582 | |
| 583 | if (localBinDirectory) { |
| 584 | return { directory: localBinDirectory }; |
| 585 | } |
| 586 | |
| 587 | const nodeModulesBinDirectory = await getNodeModulesBinDirectory(filePath); |
| 588 | |
| 589 | if (!nodeModulesBinDirectory) { |
| 590 | return null; |
| 591 | } |
| 592 | |
| 593 | const nodeModulesDirectory = path.dirname(nodeModulesBinDirectory); |
| 594 | const skippedReason = await getSkippedNodeModulesReason(nodeModulesDirectory); |
| 595 | |
| 596 | if (skippedReason) { |
| 597 | return { reason: `local node_modules is ${skippedReason}` }; |
| 598 | } |
| 599 | |
| 600 | return { reason: 'local bin is outside project lookup boundary' }; |
| 601 | } |
| 602 | |
| 603 | /** |
| 604 | * Validates that a local bin resolves to the installed `vercel` package bin. |
no test coverage detected