fix: Resolve $turbo-get-mfe-port by packageName when application key differs (#12149)
## Summary
When using `microfrontends.json` with the Vercel schema
(`https://openapi.vercel.sh/microfrontends.json`), application keys are
Vercel project names which often differ from the workspace package name
in `package.json`. The `packageName` field exists precisely to bridge
this gap, but `turbo get-mfe-port` ignored it — causing the command to
fail with `Package 'x' not found in microfrontends configuration`.
## Root Cause
`ConfigV1::port()` and `TurborepoConfig::port()` both resolved ports by
doing a direct map lookup using the application key:
```rust
pub fn port(&self, name: &str) -> Option<u16> {
let application = self.applications.get(name)?; // key-only lookup
Some(application.port(name))
}
```
`turbo get-mfe-port` reads `name` from the running package's
`package.json` (e.g. `"my-app"`), but the config may only have an entry
keyed by the Vercel project name (e.g. `"my-vercel-project"`). Since
`packageName: "my-app"` was never consulted, the lookup returned `None`.
Other parts of the system (`development_tasks()`, `applications()`,
`ConfigInfo::new()`) already handled this correctly by iterating entries
and resolving `packageName` — only `port()` was missing the fallback.
## Fix
Both `port()` methods now try a direct application-key lookup first
(fast path, no behavioural change for existing configs), then fall back
to scanning all applications for one whose resolved `packageName`
matches the requested name:
```rust
pub fn port(&self, name: &str) -> Option<u16> {
// Fast path: direct lookup by application key
if let Some(application) = self.applications.get(name) {
return Some(application.port(name));
}
// Fallback: find by packageName field (e.g. Vercel project name != package name)
self.applications
.iter()
.find(|(key, app)| app.package_name(key) == name)
.map(|(key, app)| app.port(key))
}
```
When no explicit port is configured and the port is auto-generated from
a hash, the application key (not `packageName`) is used as the hash seed
— consistent with Vercel's behaviour where the stable port is derived
from the project name.
## Testing
- Unit tests in `configv1.rs` and `schema.rs` covering both explicit
port and auto-generated port with mismatched application key /
`packageName`
- Integration test in `get_mfe_port.rs` covering the end-to-end `turbo
get-mfe-port` flow with a Vercel-style config where the application key
differs from the workspace package name
## Additional Information
> While working on [beakcrypt](https://beakcrypt.com), I ran into this
issue and that inspired this contribution.
---------
Co-authored-by: Anthony Shew <anthonyshew@gmail.com>