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
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
src/
main.rs Entry point, CLI argument parsing (clap), command dispatch
auth.rs Authentication config (load/save/resolve) + auth command
whoami.rs Whoami command (auth check, team info)
apps.rs Apps command (fetch, DB write)
consumers.rs Consumers command (paginated fetch, DB write)
request_logs.rs Request logs command (Arrow IPC or NDJSON streaming)
Expand All @@ -35,6 +36,7 @@ npm/
| Subcommand | Data source |
| -------------- | -------------------------------------------- |
| `auth` | — |
| `whoami` | `GET /v1/team` |
| `apps` | `GET /v1/apps` |
| `consumers` | `GET /v1/apps/{app_id}/consumers` |
| `request-logs` | `POST /v1/apps/{app_id}/request-logs/stream` |
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ You can also set the API key via the `APITALLY_API_KEY` environment variable or

Run `apitally --help` to see all commands and options.

### `whoami`

```
apitally whoami
```

Check authentication and show the authenticated team.

Example command:

```shell
apitally whoami
```

Example output:

<!-- prettier-ignore -->
```json
{"team_id":1,"team_name":"My Team"}
```

### `apps`

```
Expand Down
16 changes: 16 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod consumers;
mod request_logs;
mod sql;
mod utils;
mod whoami;

use std::io::{IsTerminal, Read};
use std::path::PathBuf;
Expand Down Expand Up @@ -44,6 +45,12 @@ enum Command {
api: ApiArgs,
},

/// Show the authenticated team
Whoami {
#[command(flatten)]
api: ApiArgs,
},

/// List apps in your team
///
/// Outputs newline-delimited JSON (one object per line).
Expand Down Expand Up @@ -193,6 +200,11 @@ fn run(cli: Cli) -> Result<()> {
&mut std::io::stdin(),
)
}
Command::Whoami { api } => whoami::run(
api.api_key.as_deref(),
api.api_base_url.as_deref(),
std::io::stdout().lock(),
),
Command::Apps { api, db } => apps::run(
db.as_deref(),
api.api_key.as_deref(),
Expand Down Expand Up @@ -275,6 +287,10 @@ mod tests {
Cli::try_parse_from(["apitally", "auth"]).unwrap().command,
Command::Auth { .. }
));
assert!(matches!(
Cli::try_parse_from(["apitally", "whoami"]).unwrap().command,
Command::Whoami { .. }
));
assert!(matches!(
Cli::try_parse_from(["apitally", "apps"]).unwrap().command,
Command::Apps { db: None, .. }
Expand Down
54 changes: 54 additions & 0 deletions src/whoami.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use std::io::Write;

use anyhow::Result;
use serde::{Deserialize, Serialize};

use crate::auth::{resolve_api_base_url, resolve_api_key};
use crate::utils::api_get;

#[derive(Deserialize, Serialize)]
struct TeamResponse {
team_id: i64,
team_name: String,
}

pub fn run(
api_key: Option<&str>,
api_base_url: Option<&str>,
mut writer: impl Write,
) -> Result<()> {
let api_key = resolve_api_key(api_key)?;
let api_base_url = resolve_api_base_url(api_base_url);
let url = format!("{api_base_url}/v1/team");
let mut response = api_get(&url, &api_key, &[])?;
let team: TeamResponse = response.body_mut().read_json()?;
serde_json::to_writer(&mut writer, &team)?;
writeln!(writer)?;
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::utils::test_utils::parse_ndjson;

#[test]
fn test_run() {
let mut server = mockito::Server::new();
let mock = server
.mock("GET", "/v1/team")
.with_status(200)
.with_header("content-type", "application/json")
.with_body(r#"{"team_id":1,"team_name":"Test Team"}"#)
.create();

let mut buf = Vec::new();
run(Some("test-key"), Some(&server.url()), &mut buf).unwrap();
mock.assert();

let rows = parse_ndjson(&buf);
assert_eq!(rows.len(), 1);
assert_eq!(rows[0]["team_id"], 1);
assert_eq!(rows[0]["team_name"], "Test Team");
}
}
Loading