fix: Treat `npm: alias` dependencies as external, not workspace references (#12061)
## Summary
Fixes #8989
- When a dependency uses the `npm:` alias syntax (e.g. `"buffer":
"npm:buffer@6.0.3"`), turborepo incorrectly resolved it to a workspace
of the same name instead of the npm registry package. The
`npm:<pkg>@<version>` format explicitly targets the npm registry and
should never match a workspace.
## Root cause
`DependencyVersion::new("npm:buffer@6.0.3")` splits into
`protocol="npm"` and `version="buffer@6.0.3"`. Since `npm` is
special-cased to not be treated as external (for transparent workspace
support), the code falls through to semver comparison. `"buffer@6.0.3"`
fails to parse as a semver range, and the backwards-compatibility
fallback treats parse failures as internal matches.
## Fix
Added `is_npm_alias()` to detect the `npm:<pkg>@<version>` alias format
(including scoped packages like `npm:@scope/pkg@^1.0.0`). Aliased npm
dependencies are always treated as external since they explicitly target
the npm registry. This is distinct from plain `npm:^1.0.0` ranges which
still participate in transparent workspace resolution.
## Testing
To understand the fix, the `test_is_npm_alias` and
`test_matches_workspace_package` ("handles npm alias with matching
workspace name") test cases in `dep_splitter.rs` are the most relevant.
A berry lockfile test (`test_npm_alias_does_not_resolve_to_workspace`)
verifies the lockfile resolution and pruning paths. A `berry-npm-alias`
fixture was added to `lockfile-tests/fixtures/` reproducing the exact
scenario from the issue.