fix(cli): preserve profile path_prefix when BOXLITE_API_KEY is set#629
fix(cli): preserve profile path_prefix when BOXLITE_API_KEY is set#629G4614 wants to merge 1 commit into
Conversation
GlobalFlags::create_runtime built a bare BoxliteRestOptions in the BOXLITE_API_KEY branch and applied only the api key, skipping into_rest_options(profile) — the sole place the selected profile's path_prefix (routing slot) is threaded. With path_prefix = None the URL builder emitted the prefix-less /v1/boxes shape, which a multi-tenant server rejects with 404, so `--profile p1 list` failed whenever the env key was exported. Extract a pure resolve_rest_options(stored, env_api_key) that starts from the profile (keeping url + path_prefix) and lets BOXLITE_API_KEY override ONLY the bearer credential. Add unit tests covering the three precedence cases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Root cause — exactly which code dropped The bug lived entirely in the old let mut opts = BoxliteRestOptions::new(url); // bare: path_prefix = None, credential = None
// BOXLITE_API_KEY env beats stored credentials of any kind.
if let Ok(key) = std::env::var("BOXLITE_API_KEY") && !key.is_empty() {
opts = opts.with_api_key(key); // ← taken whenever the env key is set
} else if let Some(profile) = stored {
opts = crate::credentials::into_rest_options(profile); // ← the ONLY code that copies path_prefix
opts.url = self.url.clone().unwrap_or(opts.url);
}
The later In one line: the credential axis ( The fix in this PR decouples them: always start |
when setting BOXLITE_API_KEY, URL/path_prefix should not be changed
Test plan
Two-sided (reverted vs applied) via three unit tests on the pure
resolve_rest_optionshelper, the reverted side toggling it back to the bare-options logic:api_key_env_preserves_profile_path_prefix— profile carriespath_prefix=acme+ an ambientBOXLITE_API_KEY: resolved options must keeppath_prefix = Some("acme")(the regression).api_key_env_overrides_profile_bearer_but_keeps_prefix— confirmed precedence: the bearer resolves to the env key while the prefix still survives.api_key_env_without_profile_has_no_prefix— no profile → no routing slot even with a key (single-tenant shape unaffected).resolve_rest_options(profile{prefix:"acme"}, env_key)opts.path_prefixNone→ URL/v1/boxes→ 404Some("acme")→/v1/acme/boxesPrecedence is unchanged where it already worked:
BOXLITE_API_KEYstill wins for the bearer and--url/--path-prefixflags still override the profile — the env key simply no longer discards the profile's url and routing slot.