diff --git a/lib/backend-api/src/query.rs b/lib/backend-api/src/query.rs index 341761e184b..943d952ac3b 100644 --- a/lib/backend-api/src/query.rs +++ b/lib/backend-api/src/query.rs @@ -429,6 +429,71 @@ pub async fn all_app_versions( Ok(all_versions) } +/// Retrieve versions for an app. +pub async fn get_deploy_app_versions_by_id( + client: &WasmerClient, + vars: types::GetDeployAppVersionsByIdVars, +) -> Result { + let res = client + .run_graphql_strict(types::GetDeployAppVersionsById::build(vars)) + .await?; + let versions = res + .node + .context("app not found")? + .into_app() + .context("invalid node type returned")? + .versions; + Ok(versions) +} + +/// Load all versions of an app id. +/// +/// Will paginate through all versions and return them in a single list. +pub async fn all_app_versions_by_id( + client: &WasmerClient, + app_id: impl Into, +) -> Result, anyhow::Error> { + let mut vars = types::GetDeployAppVersionsByIdVars { + id: cynic::Id::new(app_id), + offset: None, + before: None, + after: None, + first: Some(10), + last: None, + sort_by: None, + }; + + let mut all_versions = Vec::::new(); + + loop { + let page = get_deploy_app_versions_by_id(client, vars.clone()).await?; + if page.edges.is_empty() { + break; + } + + for edge in page.edges { + let edge = match edge { + Some(edge) => edge, + None => continue, + }; + let version = match edge.node { + Some(item) => item, + None => continue, + }; + + // Sanity check to avoid duplication. + if all_versions.iter().any(|v| v.id == version.id) == false { + all_versions.push(version); + } + + // Update pagination. + vars.after = Some(edge.cursor); + } + } + + Ok(all_versions) +} + /// Activate a particular version of an app. pub async fn app_version_activate( client: &WasmerClient, diff --git a/lib/backend-api/src/types.rs b/lib/backend-api/src/types.rs index e4ac2c38b75..a7888d40447 100644 --- a/lib/backend-api/src/types.rs +++ b/lib/backend-api/src/types.rs @@ -766,6 +766,39 @@ mod queries { pub versions: DeployAppVersionConnection, } + #[derive(cynic::QueryVariables, Debug, Clone)] + pub struct GetDeployAppVersionsByIdVars { + pub id: cynic::Id, + + pub offset: Option, + pub before: Option, + pub after: Option, + pub first: Option, + pub last: Option, + pub sort_by: Option, + } + + #[derive(cynic::QueryFragment, Debug, Clone, Serialize)] + #[cynic(graphql_type = "DeployApp", variables = "GetDeployAppVersionsByIdVars")] + pub struct DeployAppVersionsById { + #[arguments( + first: $first, + last: $last, + before: $before, + after: $after, + offset: $offset, + sortBy: $sort_by + )] + pub versions: DeployAppVersionConnection, + } + + #[derive(cynic::QueryFragment, Debug, Clone)] + #[cynic(graphql_type = "Query", variables = "GetDeployAppVersionsByIdVars")] + pub struct GetDeployAppVersionsById { + #[arguments(id: $id)] + pub node: Option, + } + #[derive(cynic::QueryFragment, Serialize, Debug, Clone)] #[cynic(graphql_type = "DeployApp")] pub struct SparseDeployApp { @@ -1596,6 +1629,23 @@ mod queries { #[derive(cynic::Scalar, Debug, Clone)] pub struct BigInt(pub i64); + #[derive(cynic::InlineFragments, Debug, Clone)] + #[cynic(graphql_type = "Node", variables = "GetDeployAppVersionsByIdVars")] + pub enum NodeDeployAppVersions { + DeployApp(Box), + #[cynic(fallback)] + Unknown, + } + + impl NodeDeployAppVersions { + pub fn into_app(self) -> Option { + match self { + Self::DeployApp(v) => Some(*v), + _ => None, + } + } + } + #[derive(cynic::InlineFragments, Debug)] pub enum Node { DeployApp(Box),