Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaffold teams apis #37

Merged
merged 1 commit into from
Mar 27, 2024
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,11 @@ slot deployments describe <Project Name> <katana | madara | torii>
View predeployed accounts
```sh
slot deployments account <Project Name> katana
```

Manage collaborators with teams
```sh
slot teams <Team Name> list
slot teams <Team Name> add <Account Name>
slot teams <Team Name> remove <Account Name>
```
196 changes: 196 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20847,6 +20847,112 @@
}
}
},
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "teamID",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
},
{
"defaultValue": null,
"description": null,
"name": "userIDs",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
}
}
],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "addToTeam",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
}
},
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "teamID",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
},
{
"defaultValue": null,
"description": null,
"name": "userIDs",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
}
}
],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "removeFromTeam",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
}
},
{
"args": [
{
Expand Down Expand Up @@ -22626,6 +22732,96 @@
"ofType": null
}
},
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "id",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "team",
"type": {
"kind": "OBJECT",
"name": "Team",
"ofType": null
}
},
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "after",
"type": {
"kind": "SCALAR",
"name": "Cursor",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "first",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "before",
"type": {
"kind": "SCALAR",
"name": "Cursor",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "last",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "where",
"type": {
"kind": "INPUT_OBJECT",
"name": "TeamWhereInput",
"ofType": null
}
}
],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "teams",
"type": {
"kind": "OBJECT",
"name": "TeamConnection",
"ofType": null
}
},
{
"args": [
{
Expand Down
5 changes: 5 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
pub mod auth;
pub mod deployments;
pub mod teams;

use anyhow::Result;
use clap::Subcommand;

use auth::Auth;
use deployments::Deployments;
use teams::Teams;

#[allow(clippy::large_enum_variant)]
#[derive(Subcommand, Debug)]
Expand All @@ -16,13 +18,16 @@ pub enum Command {
#[command(subcommand)]
#[command(about = "Manage Slot deployments.", aliases = ["d"])]
Deployments(Deployments),
#[command(about = "Manage Slot team.", aliases = ["t"])]
Teams(Teams),
}

impl Command {
pub async fn run(&self) -> Result<()> {
match &self {
Command::Auth(cmd) => cmd.run().await,
Command::Deployments(cmd) => cmd.run().await,
Command::Teams(cmd) => cmd.run().await,
}
}
}
19 changes: 19 additions & 0 deletions src/command/teams/members.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
query TeamMembersList($team: ID!) {
team(id: $team) {
members {
edges {
node {
id
}
}
}
}
}

mutation TeamMemberAdd($team: ID!, $accounts: [ID!]!) {
addToTeam(teamID: $team, userIDs: $accounts)
}

mutation TeamMemberRemove($team: ID!, $accounts: [ID!]!) {
removeFromTeam(teamID: $team, userIDs: $accounts)
}
121 changes: 121 additions & 0 deletions src/command/teams/members.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use anyhow::Result;
use clap::Args;
use graphql_client::{GraphQLQuery, Response};

use crate::api::ApiClient;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "src/command/teams/members.graphql",
response_derives = "Debug"
)]
pub struct TeamMembersList;

#[derive(Debug, Args, serde::Serialize)]
#[command(next_help_heading = "Team list options")]
pub struct TeamListArgs {}

impl TeamListArgs {
pub async fn run(&self, team: String) -> Result<()> {
let request_body =
TeamMembersList::build_query(self::team_members_list::Variables { team: team.clone() });

let client = ApiClient::new();
let res: Response<team_members_list::ResponseData> = client.post(&request_body).await?;
if let Some(errors) = res.errors.clone() {
for err in errors {
println!("Error: {}", err.message);
}

return Ok(());
}

if let Some(data) = res.data {
println!("{} members:", team);
data.team
.and_then(|team_list| team_list.members.edges)
.into_iter()
.flatten()
.for_each(|edge| {
if let Some(node) = edge.and_then(|edge| edge.node) {
println!(" {}", node.id)
}
});
}

Ok(())
}
}

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "src/command/teams/members.graphql",
response_derives = "Debug"
)]
pub struct TeamMemberAdd;

#[derive(Debug, Args, serde::Serialize)]
#[command(next_help_heading = "Team add options")]
pub struct TeamAddArgs {
#[arg(help = "Name of the team member to add.")]
pub account: Vec<String>,
}

impl TeamAddArgs {
pub async fn run(&self, team: String) -> Result<()> {
let request_body = TeamMemberAdd::build_query(self::team_member_add::Variables {
team,
accounts: self.account.clone(),
});

let client = ApiClient::new();
let res: Response<team_member_add::ResponseData> = client.post(&request_body).await?;
if let Some(errors) = res.errors {
for err in errors {
println!("Error: {}", err.message);
}

return Ok(());
}

Ok(())
}
}

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "src/command/teams/members.graphql",
response_derives = "Debug"
)]
pub struct TeamMemberRemove;

#[derive(Debug, Args, serde::Serialize)]
#[command(next_help_heading = "Team remove options")]
pub struct TeamRemoveArgs {
#[arg(help = "Name of the team member to add.")]
pub account: Vec<String>,
}

impl TeamRemoveArgs {
pub async fn run(&self, team: String) -> Result<()> {
let request_body = TeamMemberRemove::build_query(self::team_member_remove::Variables {
team,
accounts: self.account.clone(),
});

let client = ApiClient::new();
let res: Response<team_member_remove::ResponseData> = client.post(&request_body).await?;
if let Some(errors) = res.errors {
for err in errors {
println!("Error: {}", err.message);
}

return Ok(());
}

Ok(())
}
}
Loading
Loading