Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ that may never merge. They are not releases and are not listed here.
the same `k1=v1&k2=v2` shape as a URL's own query string — for an API
parameter this CLI's specs don't declare a flag for.

- `mapbox doctor` — a read-only snapshot of what the next command would
see: which token wins and its state, which proxy variables are in effect,
and where the update-check and telemetry switches currently stand.
`--verify` additionally checks that `api.mapbox.com` is reachable, the
only part of this that makes a request — the same precedent
`auth whoami --verify` sets.

- A native `aarch64-pc-windows-msvc` build. Windows on Arm ran the x64 build
under emulation before this — including inside a VM on Apple Silicon, the
larger of the two populations this serves — which `install.ps1` already
Expand Down
85 changes: 85 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ nests, and is typed `mapbox styles draft get`.
[config.set](#mapbox-config-set) · [config.list](#mapbox-config-list) ·
[config.unset](#mapbox-config-unset)

**[Doctor](#doctor)** — [doctor](#mapbox-doctor)

**[Usage](#usage)** — [usage](#mapbox-usage)

**[Accounts](#accounts)** —
Expand Down Expand Up @@ -3280,6 +3282,89 @@ update-check cleared, now on (default).

---

## Doctor

### `mapbox doctor`

A read-only snapshot of what the next command would see: which token wins
and its state, which proxy variables are in effect, and where the
update-check and telemetry switches currently stand. `auth whoami` answers
which token the next command will use; this answers the rest of what
commonly goes wrong before a real command finds out the hard way — a proxy
variable that silently isn't doing what someone thinks, or a switch
resolving to something other than what was intended.

Nothing here is sent unless `--verify` asks for the one check that needs a
request — the same precedent `auth whoami --verify` sets.

`Proxy:` names which of `HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`/`NO_PROXY` are
set — upper- or lowercase, exactly those two spellings each, which is what
`reqwest` itself reads. It answers "is a proxy variable set", not "would
this request actually use one" — `NO_PROXY` can exempt `api.mapbox.com`
specifically, a scheme-specific variable only ever applied to that scheme
in the first place, and on macOS a proxy configured only through system
Network settings (rather than an environment variable) is invisible here
even though `reqwest` would still use it.

#### Parameters

| Parameter | Effect |
| --- | --- |
| `--verify` | Also check that `api.mapbox.com` is reachable, through the same client and proxy handling every other request uses. Honors `--timeout`/`MAPBOX_TIMEOUT` like any other request; defaults to 5 seconds when neither is given, since this is a diagnostic someone is waiting on, not a request whose payload bounds a longer budget. |

#### Examples

```sh
mapbox doctor

mapbox doctor --verify
```

#### Outputs

<table>
<tr><th width="50%"><code>text</code></th><th width="50%"><code>json</code></th></tr>
<tr><td>

```
mapbox 0.3.0 (production)
Token: available, from login (sk)
Proxy: none set
Update check: on
Telemetry: on
```

</td><td>

```json
{
"build": { "version": "0.3.0", "channel": "production" },
"proxy": { "active": [] },
"switches": {
"telemetry_allowed": true,
"update_check_env_opt_out": false,
"update_check_persisted": true
},
"token": {
"available": true,
"source": "login",
"account": "user",
"usage": "sk",
"expires_at": 1788276540
}
}
```

</td></tr>
</table>

With `--verify`, a `connectivity` object joins the JSON and a `Reachable:`
line joins the text — `{ "reachable": true, "status": 200 }`, or `{
"reachable": false }` (plus an `error` field under `--debug`) when the
request itself failed rather than answered.

---

## Usage

### `mapbox usage`
Expand Down
6 changes: 3 additions & 3 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ fn save_credentials(creds: &Credentials, profile: Option<&str>) -> Result<()> {
.with_context(|| format!("Failed to write credentials to {}", path.display()))
}

fn token_expires_at(token: &str) -> Option<u64> {
pub(crate) fn token_expires_at(token: &str) -> Option<u64> {
let payload_b64 = token.split('.').nth(1)?;
let decoded = URL_SAFE_NO_PAD.decode(payload_b64).ok()?;
let json: serde_json::Value = serde_json::from_slice(&decoded).ok()?;
Expand Down Expand Up @@ -932,7 +932,7 @@ impl TokenSource {
/// The name a program reads. The prose form is built in
/// [`Identity::source_prose`], where it can name the variable or profile
/// the bare word leaves out.
fn as_str(self) -> &'static str {
pub(crate) fn as_str(self) -> &'static str {
match self {
TokenSource::Flag => "flag",
TokenSource::Environment => "environment",
Expand Down Expand Up @@ -973,7 +973,7 @@ pub(crate) fn resolve_source<'a>(
/// Read off the prefix rather than the payload because that is where the API
/// itself reports it — and because the prefix is the one part of a token that
/// is safe to print.
fn token_usage(token: &str) -> Option<&str> {
pub(crate) fn token_usage(token: &str) -> Option<&str> {
let (usage, rest) = token.split_once('.')?;
(!rest.is_empty() && matches!(usage, "pk" | "sk" | "tk")).then_some(usage)
}
Expand Down
Loading
Loading